module IDRAC::Power
def get_power_state
def get_power_state # Login to iDRAC if needed login unless @session_id # Get system information response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$select=PowerState") JSON.parse(handle_response(response))&.dig("PowerState") end
def get_power_usage_watts
def get_power_usage_watts # Login to iDRAC if needed login unless @session_id response = authenticated_request(:get, "/redfish/v1/Chassis/System.Embedded.1/Power") JSON.parse(handle_response(response))&.dig("PowerControl", 0, "PowerConsumedWatts")&.to_f end
def power_off(wait: true, kind: "ForceOff")
def power_off(wait: true, kind: "ForceOff") # Login to iDRAC if needed login unless @session_id puts "Powering off server...".light_cyan # Check current power state first current_state = get_power_state rescue "Unknown" if current_state == "Off" puts "Server is already powered OFF.".yellow return false end # Send power off command path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset" payload = { "ResetType" => kind } response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) if response.status == 409 puts "Server is already powered OFF.".yellow else handle_response(response) end # Wait for power state change if requested if wait success = wait_for_power_state(target_state: "Off", tries: 6) # If graceful shutdown failed, try force shutdown if !success && kind != "ForceOff" return power_off(wait: wait, kind: "ForceOff") end end return true end
def power_on(wait: true)
def power_on(wait: true) # Login to iDRAC if needed login unless @session_id puts "Powering on server...".light_cyan # Check current power state first current_state = get_power_state rescue "Unknown" if current_state == "On" puts "Server is already powered ON.".yellow return false end # Send power on command (Reset with ResetType=On) path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset" payload = { "ResetType" => "On" } tries = 10 while tries > 0 response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) case response.status when 200, 204 puts "Server power on command sent successfully".green break when 409 begin error_data = JSON.parse(response.body) if error_data["error"] && error_data["error"]["@Message.ExtendedInfo"] && error_data["error"]["@Message.ExtendedInfo"].any? { |m| m["Message"] =~ /Server is already powered ON/ } puts "Server is already powered ON.".yellow return false else raise Error, "Failed to power on: #{error_data.inspect}" end rescue JSON::ParserError raise Error, "Failed to power on with status 409: #{response.body}" end when 500 puts "[iDRAC 500] Server is busy...".red tries -= 1 puts "Retrying... #{tries}/10".yellow if tries > 0 sleep 10 else raise Error, "Unknown response code #{response.status}: #{response.body}" end end raise Error, "Failed to power on after 10 retries" if tries <= 0 # Wait for power state change if requested wait_for_power_state(target_state: "On", tries: 10) if wait return true end
def reboot
def reboot # Login to iDRAC if needed login unless @session_id puts "Rebooting server...".light_cyan # Check current power state first current_state = get_power_state rescue "Unknown" if current_state == "Off" puts "Server is currently off, powering on instead of rebooting".yellow return power_on end # Send reboot command (Reset with ResetType=ForceRestart) path = "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset" payload = { "ResetType" => "ForceRestart" } response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) if response.status >= 200 && response.status < 300 puts "Server reboot command sent successfully".green return true elsif response.status == 409 error_data = JSON.parse(response.body) rescue nil puts "Received conflict (409) error from iDRAC: #{error_data.inspect}" # Try gracefulRestart as an alternative puts "Trying GracefulRestart instead...".yellow payload = { "ResetType" => "GracefulRestart" } response = authenticated_request(:post, path, body: payload.to_json, headers: { 'Content-Type' => 'application/json' }) handle_response(response) else raise Error, "Failed to reboot server. Status code: #{response.status}" end end
def wait_for_power_state(target_state:, tries: 6)
def wait_for_power_state(target_state:, tries: 6) retry_count = tries while retry_count > 0 begin current_state = get_power_state return true if current_state == target_state puts "Waiting for power #{target_state == 'On' ? 'on' : 'off'}...".yellow puts "Current state: #{current_state}" retry_count -= 1 sleep 8 rescue => e puts "Error checking power state: #{e.message}".red retry_count -= 1 sleep 5 end end puts "Failed to reach power state #{target_state}".red return false end