def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 if (self.fanindex == 1): self.max_speed_offset = FAN1_MAX_SPEED_OFFSET else: self.max_speed_offset = FAN2_MAX_SPEED_OFFSET self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor( self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor( self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor( self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor( self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor( self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET self.max_speed = 16000
def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): FanBase.__init__(self) self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) if self.fanindex == 1: self.max_speed_offset = FAN1_MAX_SPEED_OFFSET else: self.max_speed_offset = FAN2_MAX_SPEED_OFFSET self.fan_direction_offset = FAN_DIRECTION_OFFSET else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET #self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(7+(fan_index-1)) self.max_speed = 18000
def __init__(self, psu_index): PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.state_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.voltage_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Voltage"]) self.current_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Current"]) self.power_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Power"]) self.input_voltage_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["InVoltage"]) self.input_current_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["InCurrent"]) self.input_power_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["InPower"]) self.temp_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Temperature"]) self.psu_type_offset = PSU_TYPE_OFFSET self.fru = IpmiFru(self.FRU_MAPPING[self.index]) self._fan_list.append( Fan(fan_index=self.index, psu_fan=True, dependency=self))
def __init__(self, fantray_index): FanDrawerBase.__init__(self) # FanTray is 1-based in DellEMC platforms self.fantrayindex = fantray_index + 1 for i in range(Z9332F_FANS_PER_FANTRAY): self._fan_list.append(Fan(fantray_index, i)) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex])
def __init__(self, psu_index): PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, dependency=self))
def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(fantray_index) else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(7+(fan_index-1)) self.max_speed = 23500
class FanDrawer(FanDrawerBase): """DellEMC Platform-specific Fan class""" FAN_FRU_MAPPING = {1: 6, 2: 7, 3: 8, 4: 9, 5: 10, 6: 11, 7: 12} def __init__(self, fantray_index): FanDrawerBase.__init__(self) # FanTray is 1-based in DellEMC platforms self.fantrayindex = fantray_index + 1 for i in range(Z9332F_FANS_PER_FANTRAY): self._fan_list.append(Fan(fantray_index, i)) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) def get_name(self): """ Retrieves the fan drawer name Returns: string: The name of the device """ return "FanTray{}".format(self.fantrayindex) def get_presence(self): """ Retrieves the presence of the fan drawer Returns: bool: True if fan_tray is present, False if not """ return self.get_fan(0).get_presence() def get_model(self): """ Retrieves the part number of the fan drawer Returns: string: Part number of fan drawer """ return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the fan drawer Returns: string: Serial number of the fan drawer """ return self.fru.get_board_serial() def get_status(self): """ Retrieves the operational status of the fan drawer Returns: bool: True if fan drawer is operating properly, False if not """ status = True for fan in self.get_all_fans(): status &= fan.get_status() return status def get_position_in_parent(self): """ Retrieves 1-based relative physical position in parent device. Returns: integer: The 1-based relative physical position in parent device or -1 if cannot determine the position """ return self.fantrayindex def is_replaceable(self): """ Indicate whether this fan drawer is replaceable. Returns: bool: True if it is replaceable, False if not """ return True def set_status_led(self, color): """ Set led to expected color Args: color: A string representing the color with which to set the fan module status LED Returns: bool: True if set success, False if fail. """ # Fan tray status LED controlled by BMC # Return True to avoid thermalctld alarm return True def get_maximum_consumed_power(self): """ Retrives the maximum power drawn by Fan Drawer Returns: A float, with value of the maximum consumable power of the component. """ return 36.0
class Fan(FanBase): """DellEMC Platform-specific Fan class""" # { FAN-ID: { Sensor-Name: Sensor-ID } } FAN_SENSOR_MAPPING = { 1: { "Prsnt": 0x57, "State": 0x57, "Speed": 0x24 }, 2: { "Prsnt": 0x5b, "State": 0x5b, "Speed": 0x20 }, 3: { "Prsnt": 0x58, "State": 0x58, "Speed": 0x25 }, 4: { "Prsnt": 0x5c, "State": 0x5c, "Speed": 0x21 }, 5: { "Prsnt": 0x57, "State": 0x59, "Speed": 0x26 }, 6: { "Prsnt": 0x59, "State": 0x5d, "Speed": 0x22 }, 7: { "Prsnt": 0x5a, "State": 0x5a, "Speed": 0x27 }, 8: { "Prsnt": 0x5e, "State": 0x5e, "Speed": 0x23 } } PSU_FAN_SENSOR_MAPPING = { 1: { "State": 0x31, "Speed": 0x2e }, 2: { "State": 0x32, "Speed": 0x2f } } # { FANTRAY-ID: FRU-ID } FAN_FRU_MAPPING = {1: 0, 2: 0, 3: 0, 4: 0} PSU_FRU_MAPPING = {1: 0, 2: 0} def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 if (self.fanindex == 1): self.max_speed_offset = FAN1_MAX_SPEED_OFFSET else: self.max_speed_offset = FAN2_MAX_SPEED_OFFSET self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor( self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor( self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor( self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor( self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor( self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET self.max_speed = 16000 def get_name(self): """ Retrieves the name of the device Returns: String: The name of the device """ if self.is_psu_fan: return "PSU{} Fan".format(self.fanindex) else: return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) def get_model(self): """ Retrieves the part number of the FAN Returns: String: Part number of FAN """ return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the FAN Returns: String: Serial number of FAN """ return self.fru.get_board_serial() def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if fan is present, False if not """ if self.is_psu_fan: return self.dependency.get_presence() else: # In S5212F, Fans are fixed return True def get_status(self): """ Retrieves the operational status of the FAN Returns: bool: True if FAN is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if self.is_psu_fan: if not state > 1: status = True else: if state == 0x00: status = True return status def get_direction(self): """ Retrieves the fan airfow direction Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction Notes: In DellEMC platforms, - Forward/Exhaust : Air flows from Port side to Fan side. - Reverse/Intake : Air flows from Fan side to Port side. """ board_info = self.fru.get_board_part_number() if board_info is not None: board_part_no = board_info[0:6] if board_part_no in switch_sku: return switch_sku[board_part_no][1] return None def get_speed(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ speed = None if not self.is_psu_fan: if self.max_speed == 0: self.max_speed = self.fru.get_fru_data(self.max_speed_offset, 2)[1] self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] is_valid, fan_speed = self.speed_sensor.get_reading() if is_valid and self.max_speed > 0: speed = (100 * fan_speed) // self.max_speed return speed def get_speed_rpm(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ fan_speed = None if not self.is_psu_fan: is_valid, fan_speed = self.speed_sensor.get_reading() return fan_speed if is_valid else None def get_position_in_parent(self): """ Retrieves 1-based relative physical position in parent device. Returns: integer: The 1-based relative physical position in parent device or -1 if cannot determine the position """ return self.fanindex def is_replaceable(self): """ Indicate whether Fan is replaceable. Returns: bool: True if it is replaceable. """ return False def get_speed_tolerance(self): """ Retrieves the speed tolerance of the fan Returns: An integer, the percentage of variance from target speed which is considered tolerable """ if self.get_presence(): # The tolerance value is fixed as 20% for all the DellEMC platforms tolerance = 20 else: tolerance = 0 return tolerance def set_status_led(self, color): """ Set led to expected color Args: color: A string representing the color with which to set the fan status LED Returns: bool: True if set success, False if fail. """ # Fan tray status LED controlled by HW # Return True to avoid thermalctld alarm return True
class Psu(PsuBase): """DellEMC Platform-specific PSU class""" # { PSU-ID: { Sensor-Name: Sensor-ID } } SENSOR_MAPPING = { 1: { "State": 0x2f, "Current": 0x37, "Power": 0x38, "Voltage": 0x36 }, 2: { "State": 0x39, "Current": 0x41, "Power": 0x42, "Voltage": 0x40 } } # ( PSU-ID: FRU-ID } FRU_MAPPING = {1: 3, 2: 4} def __init__(self, psu_index): PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.state_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.voltage_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Voltage"]) self.current_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Current"]) self.power_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Power"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) self.psu_type_raw_cmd = "0x3A 0x0B {}".format(psu_index + 1) self._fan_list.append( Fan(fan_index=self.index, psu_fan=True, dependency=self)) def get_name(self): """ Retrieves the name of the device Returns: string: The name of the device """ return "PSU{}".format(self.index) def get_presence(self): """ Retrieves the presence of the Power Supply Unit (PSU) Returns: bool: True if PSU is present, False if not """ presence = False is_valid, state = self.state_sensor.get_reading() if is_valid: if state & 0b1: presence = True return presence def get_model(self): """ Retrieves the part number of the PSU Returns: string: Part number of PSU """ return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the PSU Returns: string: Serial number of PSU """ return self.fru.get_board_serial() def get_status(self): """ Retrieves the operational status of the PSU Returns: bool: True if PSU is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state & 0b1010) == 0: status = True return status def get_voltage(self): """ Retrieves current PSU voltage output Returns: A float number, the output voltage in volts, e.g. 12.1 """ is_valid, voltage = self.voltage_sensor.get_reading() if not is_valid: return None return "{:.1f}".format(voltage) def get_current(self): """ Retrieves present electric current supplied by PSU Returns: A float number, electric current in amperes, e.g. 15.4 """ is_valid, current = self.current_sensor.get_reading() if not is_valid: return None return "{:.1f}".format(current) def get_power(self): """ Retrieves current energy supplied by PSU Returns: A float number, the power in watts, e.g. 302.6 """ is_valid, power = self.power_sensor.get_reading() if not is_valid: return None return "{:.1f}".format(power) def get_powergood_status(self): """ Retrieves the powergood status of PSU Returns: A boolean, True if PSU has stablized its output voltages and passed all its internal self-tests, False if not. """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state & 0b1010) == 0: status = True return status def get_mfr_id(self): """ Retrives the Manufacturer Id of PSU Returns: A string, the manunfacturer id. """ return self.fru.get_board_mfr_id() def get_type(self): """ Retrives the Power Type of PSU Returns : A string, PSU power type """ psu_type = [None, 'AC', 'AC', 'DC'] type_res = get_ipmitool_raw_output(self.psu_type_raw_cmd) if type_res is not None and len(type_res) == 1: return psu_type[type_res[0]] return None
class Fan(FanBase): """DellEMC Platform-specific Fan class""" # { FAN-ID: { Sensor-Name: Sensor-ID } } FAN_SENSOR_MAPPING = {1: {"Prsnt": 0x57, "State": 0x20, "Speed": 0x1c}, 2: {"Prsnt": 0x57, "State": 0x21, "Speed": 0x1d}, 3: {"Prsnt": 0x56, "State": 0x22, "Speed": 0x1a}, 4: {"Prsnt": 0x56, "State": 0x23, "Speed": 0x1b}, 5: {"Prsnt": 0x55, "State": 0x24, "Speed": 0x18}, 6: {"Prsnt": 0x55, "State": 0x25, "Speed": 0x19}, 7: {"Prsnt": 0x54, "State": 0x26, "Speed": 0x16}, 8: {"Prsnt": 0x54, "State": 0x27, "Speed": 0x17}, 9: {"Prsnt": 0x53, "State": 0x28, "Speed": 0x14}, 10: {"Prsnt": 0x53, "State": 0x29, "Speed": 0x15}, 11: {"Prsnt": 0x52, "State": 0x2a, "Speed": 0x12}, 12: {"Prsnt": 0x52, "State": 0x2b, "Speed": 0x13}, 13: {"Prsnt": 0x51, "State": 0x2c, "Speed": 0x10}, 14: {"Prsnt": 0x51, "State": 0x2d, "Speed": 0x11}} PSU_FAN_SENSOR_MAPPING = {1: {"State": 0x40, "Speed": 0x45}, 2: {"State": 0x30, "Speed": 0x35}} # { FANTRAY-ID: FRU-ID } FAN_FRU_MAPPING = {1: 3, 2: 4, 3: 5, 4: 6, 5: 7, 6: 8, 7: 9} PSU_FRU_MAPPING = {1: 1, 2: 2} def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): FanBase.__init__(self) self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) if self.fanindex == 1: self.max_speed_offset = FAN1_MAX_SPEED_OFFSET else: self.max_speed_offset = FAN2_MAX_SPEED_OFFSET self.fan_direction_offset = FAN_DIRECTION_OFFSET else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET #self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(7+(fan_index-1)) self.max_speed = 18000 def get_name(self): """ Retrieves the name of the device Returns: String: The name of the device """ if self.is_psu_fan: return "PSU{} Fan".format(self.fanindex) else: return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) def get_model(self): """ Retrieves the part number of the FAN Returns: String: Part number of FAN """ if self.is_psu_fan: return 'NA' else: return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the FAN Returns: String: Serial number of FAN """ if self.is_psu_fan: return 'NA' else: return self.fru.get_board_serial() def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if fan is present, False if not """ presence = False if self.is_psu_fan: return self.dependency.get_presence() else: is_valid, state = self.prsnt_sensor.get_reading() if is_valid: if state & 0b1: presence = True return presence def get_status(self): """ Retrieves the operational status of the FAN Returns: bool: True if FAN is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if state <= 1: status = True return status def get_direction(self): """ Retrieves the fan airfow direction Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction Notes: In DellEMC platforms, - Forward/Exhaust : Air flows from Port side to Fan side. - Reverse/Intake : Air flows from Fan side to Port side. """ direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] fan_status = self.get_status() if not fan_status: return None is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) if is_valid: return direction[fan_direction[0]] return None def get_speed(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ if self.max_speed == 0: self.max_speed = self.fru.get_fru_data(self.max_speed_offset, 2)[1] self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] is_valid, fan_speed = self.speed_sensor.get_reading() if not is_valid or self.max_speed == 0: return None else: speed = (100 * fan_speed)//self.max_speed return speed def get_speed_rpm(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ is_valid, fan_speed = self.speed_sensor.get_reading() return fan_speed if is_valid else None def get_position_in_parent(self): """ Retrieves 1-based relative physical position in parent device. Returns: integer: The 1-based relative physical position in parent device or -1 if cannot determine the position """ return self.fanindex def is_replaceable(self): """ Indicate whether Fan is replaceable. Returns: bool: True if it is replaceable. """ return False def get_speed_tolerance(self): """ Retrieves the speed tolerance of the fan Returns: An integer, the percentage of variance from target speed which is considered tolerable """ if self.get_presence(): # The tolerance value is fixed as 20% for all the DellEMC platforms tolerance = 20 else: tolerance = 0 return tolerance def set_status_led(self, color): """ Set led to expected color Args: color: A string representing the color with which to set the fan status LED Returns: bool: True if set success, False if fail. """ # Fan tray status LED controlled by HW # Return True to avoid thermalctld alarm return True
class Psu(PsuBase): """DellEMC Platform-specific PSU class""" # { PSU-ID: { Sensor-Name: Sensor-ID } } SENSOR_MAPPING = { 1: { "State": 0x2f, "Current": 0x37, "Power": 0x38, "Voltage": 0x36, "Temperature": 0x35 }, 2: { "State": 0x39, "Current": 0x41, "Power": 0x42, "Voltage": 0x40, "Temperature": 0x3F } } # ( PSU-ID: FRU-ID } FRU_MAPPING = {1: 3, 2: 4} def __init__(self, psu_index): PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.state_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.voltage_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Voltage"]) self.current_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Current"]) self.power_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Power"]) self.temp_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Temperature"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) self.psu_type_raw_cmd = "0x3A 0x0B {}".format(psu_index + 1) self._fan_list.append( Fan(fan_index=self.index, psu_fan=True, dependency=self)) def get_name(self): """ Retrieves the name of the device Returns: string: The name of the device """ return "PSU{}".format(self.index) def get_presence(self): """ Retrieves the presence of the Power Supply Unit (PSU) Returns: bool: True if PSU is present, False if not """ presence = False is_valid, state = self.state_sensor.get_reading() if is_valid: if state & 0b1: presence = True return presence def get_model(self): """ Retrieves the part number of the PSU Returns: string: Part number of PSU """ return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the PSU Returns: string: Serial number of PSU """ return self.fru.get_board_serial() def get_status(self): """ Retrieves the operational status of the PSU Returns: bool: True if PSU is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state & 0b1010) == 0: status = True return status def get_voltage(self): """ Retrieves current PSU voltage output Returns: A float number, the output voltage in volts, e.g. 12.1 """ is_valid, voltage = self.voltage_sensor.get_reading() if not is_valid: return None return float(voltage) def get_voltage_low_threshold(self): """ Returns PSU low threshold in Volts """ is_valid, low_threshold = self.voltage_sensor.get_threshold( "LowerCritical") if not is_valid: low_threshold = 11.4 low_threshold = "{:.2f}".format(low_threshold) return float(low_threshold) def get_voltage_high_threshold(self): """ Returns PSU high threshold in Volts """ is_valid, high_threshold = self.voltage_sensor.get_threshold( "UpperCritical") if not is_valid: high_threshold = 12.6 high_threshold = "{:.2f}".format(high_threshold) return float(high_threshold) def get_temperature(self): """ Retrieves current temperature reading from thermal Returns: A float number of current temperature in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ is_valid, temperature = self.temp_sensor.get_reading() if not is_valid: temperature = 0 return float(temperature) def get_temperature_high_threshold(self): """ Returns the high temperature threshold for PSU in Celsius """ is_valid, high_threshold = self.temp_sensor.get_threshold( "UpperCritical") if not is_valid: high_threshold = 113 high_threshold = "{:.2f}".format(high_threshold) return float(high_threshold) def get_current(self): """ Retrieves present electric current supplied by PSU Returns: A float number, electric current in amperes, e.g. 15.4 """ is_valid, current = self.current_sensor.get_reading() if not is_valid: return None return float(current) def get_power(self): """ Retrieves current energy supplied by PSU Returns: A float number, the power in watts, e.g. 302.6 """ is_valid, power = self.power_sensor.get_reading() if not is_valid: return None return float(power) def get_powergood_status(self): """ Retrieves the powergood status of PSU Returns: A boolean, True if PSU has stablized its output voltages and passed all its internal self-tests, False if not. """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state & 0b1010) == 0: status = True return status def get_mfr_id(self): """ Retrives the Manufacturer Id of PSU Returns: A string, the manunfacturer id. """ return self.fru.get_board_mfr_id() def get_type(self): """ Retrives the Power Type of PSU Returns : A string, PSU power type """ psu_type = [None, 'AC', 'AC', 'DC'] type_res = get_ipmitool_raw_output(self.psu_type_raw_cmd) if type_res is not None and len(type_res) == 1: return psu_type[type_res[0]] return None def get_position_in_parent(self): """ Retrieves 1-based relative physical position in parent device. Returns: integer: The 1-based relative physical position in parent device or -1 if cannot determine the position """ return self.index def is_replaceable(self): """ Indicate whether this PSU is replaceable. Returns: bool: True if it is replaceable. """ return True
class Psu(PsuBase): """DellEMC Platform-specific PSU class""" # { PSU-ID: { Sensor-Name: Sensor-ID } } SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39, "Power": 0x37, "Voltage": 0x38 }, 2: { "State": 0x32, "Current": 0x3F, "Power": 0x3D, "Voltage": 0x3E } } # ( PSU-ID: FRU-ID } FRU_MAPPING = { 1: 1, 2: 2 } def __init__(self, psu_index): PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.state_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.voltage_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Voltage"]) self.current_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Current"]) self.power_sensor = IpmiSensor(self.SENSOR_MAPPING[self.index]["Power"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, dependency=self)) def get_name(self): """ Retrieves the name of the device Returns: string: The name of the device """ return "PSU{}".format(self.index) def get_presence(self): """ Retrieves the presence of the Power Supply Unit (PSU) Returns: bool: True if PSU is present, False if not """ presence = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state & 0b1): presence = True return presence def get_model(self): """ Retrieves the part number of the PSU Returns: string: Part number of PSU """ return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the PSU Returns: string: Serial number of PSU """ return self.fru.get_board_serial() def get_status(self): """ Retrieves the operational status of the PSU Returns: bool: True if PSU is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state == 0x01): status = True return status def get_voltage(self): """ Retrieves current PSU voltage output Returns: A float number, the output voltage in volts, e.g. 12.1 """ is_valid, voltage = self.voltage_sensor.get_reading() if not is_valid: voltage = 0 return float(voltage) def get_current(self): """ Retrieves present electric current supplied by PSU Returns: A float number, electric current in amperes, e.g. 15.4 """ is_valid, current = self.current_sensor.get_reading() if not is_valid: current = 0 return float(current) def get_power(self): """ Retrieves current energy supplied by PSU Returns: A float number, the power in watts, e.g. 302.6 """ is_valid, power = self.power_sensor.get_reading() if not is_valid: power = 0 return float(power) def get_powergood_status(self): """ Retrieves the powergood status of PSU Returns: A boolean, True if PSU has stablized its output voltages and passed all its internal self-tests, False if not. """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state == 0x01): status = True return status def get_mfr_id(self): """ Retrives the Manufacturer Id of PSU Returns: A string, the manunfacturer id. """ return self.fru.get_board_mfr_id() def get_type(self): """ Retrives the Power Type of PSU Returns : A string, PSU power type """ info = self.fru.get_board_product().split(',') if 'AC' in info : return 'AC' if 'DC' in info : return 'DC' return 'Unknown'
class Fan(FanBase): """DellEMC Platform-specific Fan class""" # { FAN-ID: { Sensor-Name: Sensor-ID } } FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x53, "State": 0x57, "Speed": 0x24}, 2: {"Prsnt": 0x53, "State": 0x5b, "Speed": 0x20}, 3: {"Prsnt": 0x54, "State": 0x58, "Speed": 0x25}, 4: {"Prsnt": 0x54, "State": 0x5c, "Speed": 0x21}, 5: {"Prsnt": 0x55, "State": 0x59, "Speed": 0x26}, 6: {"Prsnt": 0x55, "State": 0x5d, "Speed": 0x22}, 7: {"Prsnt": 0x56, "State": 0x5a, "Speed": 0x27}, 8: {"Prsnt": 0x56, "State": 0x5e, "Speed": 0x23} } PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x31, "Speed": 0x28}, 2: {"State": 0x32, "Speed": 0x29} } # { FANTRAY-ID: FRU-ID } FAN_FRU_MAPPING = { 1: 3, 2: 4, 3: 5, 4: 6 } PSU_FRU_MAPPING = { 1: 1, 2: 2 } def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 if (self.fanindex == 1): self.max_speed_offset = FAN1_MAX_SPEED_OFFSET else: self.max_speed_offset = FAN2_MAX_SPEED_OFFSET self.fan_direction_offset = FAN_DIRECTION_OFFSET self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.max_speed_offset = PSU_FAN_MAX_SPEED_OFFSET self.fan_direction_offset = PSU_FAN_DIRECTION_OFFSET self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] def get_name(self): """ Retrieves the name of the device Returns: String: The name of the device """ if self.is_psu_fan: return "PSU{} Fan".format(self.fanindex) else: return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) def get_model(self): """ Retrieves the part number of the FAN Returns: String: Part number of FAN """ if self.is_psu_fan: return 'NA' else: return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the FAN Returns: String: Serial number of FAN """ if self.is_psu_fan: return 'NA' else: return self.fru.get_board_serial() def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if fan is present, False if not """ presence = False if self.is_psu_fan: return self.dependency.get_presence() else: is_valid, state = self.prsnt_sensor.get_reading() if is_valid: if (state & 0b1): presence = True return presence def get_status(self): """ Retrieves the operational status of the FAN Returns: bool: True if FAN is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if not state > 1: status = True return status def get_direction(self): """ Retrieves the fan airfow direction Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction Notes: In DellEMC platforms, - Forward/Exhaust : Air flows from Port side to Fan side. - Reverse/Intake : Air flows from Fan side to Port side. """ direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] fan_status = self.get_presence() if not fan_status: return 'NA' is_valid, fan_direction = self.fru.get_fru_data(self.fan_direction_offset) if is_valid and fan_direction[0] < len(direction): return direction[fan_direction[0]] else: return 'NA' def get_speed(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ if self.max_speed == 0: self.max_speed = self.fru.get_fru_data(self.max_speed_offset,2)[1] self.max_speed = self.max_speed[1] << 8 | self.max_speed[0] is_valid, fan_speed = self.speed_sensor.get_reading() if not is_valid or self.max_speed == 0: speed = 0 else: speed = (100 * fan_speed)//self.max_speed return speed def get_speed_rpm(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ fan_speed = 0 is_valid, fan_speed = self.speed_sensor.get_reading() return fan_speed
class Fan(FanBase): """DellEMC Platform-specific Fan class""" # { FAN-ID: { Sensor-Name: Sensor-ID } } FAN_SENSOR_MAPPING = { 1: {"Prsnt": 0x6, "State": 0x6, "Speed": 0xd}, 2: {"Prsnt": 0x6, "State": 0x6, "Speed": 0x45}, 3: {"Prsnt": 0x7, "State": 0x7, "Speed": 0xe}, 4: {"Prsnt": 0x7, "State": 0x7, "Speed": 0x46}, 5: {"Prsnt": 0x8, "State": 0x8, "Speed": 0xf}, 6: {"Prsnt": 0x8, "State": 0x8, "Speed": 0x47}, 7: {"Prsnt": 0x9, "State": 0x9, "Speed": 0x10}, 8: {"Prsnt": 0x9, "State": 0x9, "Speed": 0x48}, 9: {"Prsnt": 0xa, "State": 0xa, "Speed": 0x11}, 10: {"Prsnt": 0xa, "State": 0xa, "Speed": 0x49}, 11: {"Prsnt": 0xb, "State": 0xb, "Speed": 0x12}, 12: {"Prsnt": 0xb, "State": 0xb, "Speed": 0x4a}, 13: {"Prsnt": 0xc, "State": 0xc, "Speed": 0x13}, 14: {"Prsnt": 0xc, "State": 0xc, "Speed": 0x4b} } PSU_FAN_SENSOR_MAPPING = { 1: {"State": 0x2f, "Speed": 0x33}, 2: {"State": 0x39, "Speed": 0x3d} } # { FANTRAY-ID: FRU-ID } FAN_FRU_MAPPING = { 1: 6, 2: 7, 3: 8, 4: 9, 5: 10, 6: 11, 7: 12 } PSU_FRU_MAPPING = { 1: 3, 2: 4 } def __init__(self, fantray_index=1, fan_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: # API index is starting from 0, DellEMC platform index is # starting from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 self.index = (self.fantrayindex - 1) * 2 + self.fanindex self.prsnt_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Prsnt"], is_discrete=True) self.state_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.FAN_SENSOR_MAPPING[self.index]["Speed"]) self.fru = IpmiFru(self.FAN_FRU_MAPPING[self.fantrayindex]) self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(fantray_index) else: self.dependency = dependency self.fanindex = fan_index self.state_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["State"], is_discrete=True) self.speed_sensor = IpmiSensor(self.PSU_FAN_SENSOR_MAPPING[self.fanindex]["Speed"]) self.fru = IpmiFru(self.PSU_FRU_MAPPING[self.fanindex]) self.fan_dir_raw_cmd = "0x3a 0x0a {}".format(7+(fan_index-1)) self.max_speed = 23500 def get_name(self): """ Retrieves the name of the device Returns: String: The name of the device """ if self.is_psu_fan: return "PSU{} Fan".format(self.fanindex) else: return "FanTray{}-Fan{}".format(self.fantrayindex, self.fanindex) def get_model(self): """ Retrieves the part number of the FAN Returns: String: Part number of FAN """ if self.is_psu_fan: return None else: return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the FAN Returns: String: Serial number of FAN """ if self.is_psu_fan: return None else: return self.fru.get_board_serial() def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if fan is present, False if not """ presence = False if self.is_psu_fan: return self.dependency.get_presence() else: is_valid, state = self.prsnt_sensor.get_reading() if is_valid: if (state & 0b1): presence = True return presence def get_status(self): """ Retrieves the operational status of the FAN Returns: bool: True if FAN is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if state & 0b1: status = True return status def get_direction(self): """ Retrieves the fan airfow direction Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction Notes: In DellEMC platforms, - Forward/Exhaust : Air flows from Port side to Fan side. - Reverse/Intake : Air flows from Fan side to Port side. """ direction = [self.FAN_DIRECTION_EXHAUST, self.FAN_DIRECTION_INTAKE] fan_status = self.get_presence() if not fan_status: return None dir_res = get_ipmitool_raw_output(self.fan_dir_raw_cmd) if dir_res is not None and len(dir_res) == 1 : return direction[dir_res[0]] else: return None def get_speed(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ if self.max_speed == 0: self.max_speed = 23500 is_valid, fan_speed = self.speed_sensor.get_reading() if not is_valid or self.max_speed == 0: return None else: speed = (100 * fan_speed)/self.max_speed return speed def get_speed_rpm(self): """ Retrieves the speed of the fan Returns: int: percentage of the max fan speed """ is_valid, fan_speed = self.speed_sensor.get_reading() return fan_speed if is_valid else None
class Psu(PsuBase): """DellEMC Platform-specific PSU class""" # { PSU-ID: { Sensor-Name: Sensor-ID } } SENSOR_MAPPING = { 1: { "State": 0x31, "Current": 0x39, "Power": 0x37, "Voltage": 0x38, "InCurrent": 0x36, "InPower": 0x34, "InVoltage": 0x35, "Temperature": 0xc }, 2: { "State": 0x32, "Current": 0x3F, "Power": 0x3D, "Voltage": 0x3E, "InCurrent": 0x3C, "InPower": 0x3A, "InVoltage": 0x3B, "Temperature": 0xd } } # ( PSU-ID: FRU-ID } FRU_MAPPING = {1: 1, 2: 2} def __init__(self, psu_index): PsuBase.__init__(self) # PSU is 1-based in DellEMC platforms self.index = psu_index + 1 self.state_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["State"], is_discrete=True) self.voltage_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Voltage"]) self.current_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Current"]) self.power_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Power"]) self.input_voltage_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["InVoltage"]) self.input_current_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["InCurrent"]) self.input_power_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["InPower"]) self.temp_sensor = IpmiSensor( self.SENSOR_MAPPING[self.index]["Temperature"]) self.fru = IpmiFru(self.FRU_MAPPING[self.index]) self._fan_list.append( Fan(fan_index=self.index, psu_fan=True, dependency=self)) def get_name(self): """ Retrieves the name of the device Returns: string: The name of the device """ return "PSU{}".format(self.index) def get_presence(self): """ Retrieves the presence of the Power Supply Unit (PSU) Returns: bool: True if PSU is present, False if not """ presence = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state == 0x01): presence = True return presence def get_temperature(self): """ Retrieves current temperature reading from thermal Returns: A float number of current temperature in Celcius up to nearest thousandth of one degree celcius, e.g. 30.125 """ is_valid, temperature = self.temp_sensor.get_reading() if not is_valid: temperature = 0 return float(temperature) def get_temperature_high_threshold(self): """ Returns the high temperature threshold for PSU in Celsius """ is_valid, high_threshold = self.temp_sensor.get_threshold( "UpperCritical") if not is_valid: high_threshold = 105 high_threshold = "{:.2f}".format(high_threshold) return float(high_threshold) def get_model(self): """ Retrieves the part number of the PSU Returns: string: Part number of PSU """ return self.fru.get_board_part_number() def get_serial(self): """ Retrieves the serial number of the PSU Returns: string: Serial number of PSU """ return self.fru.get_board_serial() def get_revision(self): """ Retrives thehardware revision of the device Returns: String: revision value of device """ serial = self.fru.get_board_serial() if serial != "NA" and len(serial) == 23: return serial[-3:] else: return "NA" def is_replaceable(self): """ Indicate whether this PSU is replaceable. Returns: bool: True if it is replaceable. """ return True def get_status(self): """ Retrieves the operational status of the PSU Returns: bool: True if PSU is operating properly, False if not """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state == 0x01): status = True return status def get_voltage(self): """ Retrieves current PSU voltage output Returns: A float number, the output voltage in volts, e.g. 12.1 """ is_valid, voltage = self.voltage_sensor.get_reading() if not is_valid: return 0.0 return float(voltage) def get_voltage_low_threshold(self): """ Returns PSU low threshold in Volts """ is_valid, low_threshold = self.voltage_sensor.get_threshold( "LowerCritical") if not is_valid: low_threshold = 11.6 low_threshold = "{:.2f}".format(low_threshold) return float(low_threshold) def get_voltage_high_threshold(self): """ Returns PSU high threshold in Volts """ is_valid, high_threshold = self.voltage_sensor.get_threshold( "UpperCritical") if not is_valid: high_threshold = 12.8 high_threshold = "{:.2f}".format(high_threshold) return float(high_threshold) def get_current(self): """ Retrieves present electric current supplied by PSU Returns: A float number, electric current in amperes, e.g. 15.4 """ is_valid, current = self.current_sensor.get_reading() if not is_valid: return 0.0 return float(current) def get_power(self): """ Retrieves current energy supplied by PSU Returns: A float number, the power in watts, e.g. 302.6 """ is_valid, power = self.power_sensor.get_reading() if not is_valid: return 0.0 return float(power) def get_input_voltage(self): """ Retrieves current PSU voltage input Returns: A float number, the input voltage in volts, e.g. 12.1 """ is_valid, input_voltage = self.input_voltage_sensor.get_reading() if not is_valid: return 0.0 return float(input_voltage) def get_input_current(self): """ Retrieves present electric current supplied to PSU Returns: A float number, electric current in amperes, e.g. 15.4 """ is_valid, input_current = self.input_current_sensor.get_reading() if not is_valid: return 0.0 return float(input_current) def get_input_power(self): """ Retrieves current energy supplied to PSU Returns: A float number, the power in watts, e.g. 302.6 """ is_valid, input_power = self.input_power_sensor.get_reading() if not is_valid: return None return float(input_power) def get_powergood_status(self): """ Retrieves the powergood status of PSU Returns: A boolean, True if PSU has stablized its output voltages and passed all its internal self-tests, False if not. """ status = False is_valid, state = self.state_sensor.get_reading() if is_valid: if (state == 0x01): status = True return status def get_mfr_id(self): """ Retrives the Manufacturer Id of PSU Returns: A string, the manunfacturer id. """ return self.fru.get_board_mfr_id() def get_type(self): """ Retrives the Power Type of PSU Returns : A string, PSU power type """ board_product = self.fru.get_board_product() if board_product is not None: info = board_product.split(',') if 'AC' in info: return 'AC' if 'DC' in info: return 'DC' return None def get_position_in_parent(self): """ Retrieves 1-based relative physical position in parent device. Returns: integer: The 1-based relative physical position in parent device or -1 if cannot determine the position """ return self.index def get_maximum_supplied_power(self): """ Retrieves the maximum supplied power by PSU Returns: A float number, the maximum power output in Watts. e.g. 1200.1 """ return float(750) def set_status_led(self, color): """ Sets the state of the PSU status LED Args: color: A string representing the color with which to set the PSU status LED Note: Only support green and off Returns: bool: True if status LED state is set successfully, False if not """ # Hardware not supported return False