class Rotor: def __init__(self, config): if config is not None and isinstance(config, dict): self.__reg_speed_getter = Reg(config.get("speed_getter")) self.__reg_speed_setter = Reg(config.get("speed_setter")) self.__speed_max = config.get("speed_max") else: raise ValueError("init rotor Error: {}".format(config)) def get_speed(self): try: return int(self.__reg_speed_getter.decode()) except Exception as e: logger.error(e.message) return 0 def set_speed(self, speed): try: return self.__reg_speed_setter.encode(speed) except Exception as e: logger.error(e.message) return False def get_speed_percentage(self): try: speed = self.get_speed() return (100 * speed) / self.__speed_max except Exception as e: logger.error(e.message) return 0
class Psu(PsuBase): """Ruijie Platform-specific PSU class""" # HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" # HWMON_NODE = os.listdir(HWMON_DIR)[0] # MAILBOX_DIR = HWMON_DIR + HWMON_NODE def __init__(self, name, config=None, hal_psu=None): """ "psus": [ { "name": "psu1", "present": {"loc": "2-0037/psu_status", "format": DecodeFormat.ONE_BIT_HEX, "bit": 0}, "status": {"loc": "2-0037/psu_status", "format": DecodeFormat.ONE_BIT_HEX, "bit": 1}, "sn": {"loc": "7-0050/psu_sn"}, "in_current": {"loc": "7-0058/hwmon/*/curr1_input", "format": DecodeFormat.THOUSANDTH}, "in_voltage": {"loc": "7-0058/hwmon/*/in1_input", "format": DecodeFormat.THOUSANDTH}, "out_voltage": {"loc": "7-0058/hwmon/*/in2_input", "format": DecodeFormat.THOUSANDTH}, "out_current": {"loc": "7-0058/hwmon/*/curr2_input", "format": DecodeFormat.THOUSANDTH}, "temperature": {"loc": "7-0058/hwmon/*/temp1_input", "format": DecodeFormat.THOUSANDTH}, "hw_version": {"loc": "7-0050/psu_hw"}, "psu_type": {"loc": "7-0050/psu_type"}, "fans": [ { "rotor": { "speed": {"loc": "7-0058/hwmon/*/fan1_input"}, "speed_max": xx } } ], "in_power": {"loc": "7-0058/hwmon/*/power1_input", "format": DecodeFormat.MILLIONTH}, "out_power": {"loc": "7-0058/hwmon/*/power2_input", "format": DecodeFormat.MILLIONTH}, } ] """ self._fan_list = [] if config is not None: self.name = name self.__reg_sn = Reg(config.get("sn")) self.__reg_present = Reg(config.get("present")) self.__reg_status = Reg(config.get("status")) self.__reg_out_vol = Reg(config.get("out_voltage")) self.__reg_out_cur = Reg(config.get("out_current")) self.__reg_out_pow = Reg(config.get("out_power")) self.__reg_pn = Reg(config.get("pn")) self._psu_fan_parser(config.get("fans")) self._hal_psu = hal_psu def _psu_fan_parser(self, fans): if not isinstance(fans, list): raise TypeError("fan type error fans: {}".format(fans)) for i, f in enumerate(fans): if not isinstance(f, dict): raise TypeError("fan type must be a dict") fanname = "{}-fan{}".format(self.name, i + 1) self._fan_list.append(Fan(fanname, config=f, is_psu_fan=True)) def _reg_setter(self, target, val): if isinstance(val, dict): target = Reg(val) elif isinstance(val, Reg): target = val else: raise ValueError return target @property def reg_sn(self): return self.__reg_sn @reg_sn.setter def reg_sn(self, val): self._reg_setter(self.__reg_sn, val) @property def reg_present(self): return self.__reg_present @reg_present.setter def reg_present(self, val): self._reg_setter(self.__reg_present, val) @property def reg_status(self): return self.__reg_status @reg_status.setter def reg_status(self, val): self._reg_setter(self.__reg_status, val) @property def reg_out_vol(self): return self.__reg_out_vol @reg_out_vol.setter def reg_out_vol(self, val): self._reg_setter(self.__reg_out_vol, val) @property def reg_out_cur(self): return self.__reg_out_cur @reg_out_cur.setter def reg_out_cur(self, val): self._reg_setter(self.__reg_out_cur, val) @property def reg_out_pow(self): return self.__reg_out_pow @reg_out_pow.setter def reg_out_pow(self, val): self._reg_setter(self.__reg_out_pow, val) def get_name(self): """ Retrieves the name of the device Returns: string: The name of the device """ return self.name def get_presence(self): """ Retrieves the presence of the Power Supply Unit (PSU) Returns: bool: True if PSU is present, False if not """ if self._hal_psu: pass try: if isinstance(self.__reg_present, Reg): psu_presence = self.__reg_present.decode() if psu_presence == 0 or psu_presence == "0": return True except Exception as e: logger.error(e.message) return False def get_model(self): """ Retrieves the part number of the PSU Returns: string: Part number of PSU """ if self._hal_psu: return self._hal_psu.pn() try: if isinstance(self.__reg_pn, Reg): return self.__reg_pn.decode() except Exception as e: logger.error(e.message) return "NA" def get_serial(self): """ Retrieves the serial number of the PSU Returns: string: Serial number of PSU """ if self._hal_psu: return self._hal_psu.sn() try: if isinstance(self.__reg_sn, Reg): return self.__reg_sn.decode() except Exception as e: logger.error(e.message) return "NA" def get_status(self): """ Retrieves the operational status of the PSU Returns: bool: True if PSU is operating properly, False if not """ # status = False # psu_status = self._get_pmc_register(self.psu_presence_reg) # if (psu_status != 'ERR'): # psu_status = int(psu_status, 16) # # Checking whether both bit 3 and bit 2 are not set # if (~psu_status & 0b1000) and (~psu_status & 0b0100): # status = True if self._hal_psu: return self._hal_psu.get_status() try: if isinstance(self.reg_status, Reg): psu_status = self.reg_status.decode() if psu_status == 1 or psu_status == "1": return True elif psu_status == 0 or psu_status == "0": return False except Exception as e: logger.error(e.message) return False def get_voltage(self): """ Retrieves current PSU voltage output Returns: A float number, the output voltage in volts, e.g. 12.1 """ # psu_voltage = self._get_pmc_register(self.psu_voltage_reg) # if (psu_voltage != 'ERR') and self.get_presence(): # # Converting the value returned by driver which is in # # millivolts to volts # psu_voltage = float(psu_voltage) / 1000 # else: # psu_voltage = 0.0 if self._hal_psu: pass try: if isinstance(self.__reg_out_vol, Reg): return self.__reg_out_vol.decode() except Exception as e: logger.error(e.message) return 0.0 def get_current(self): """ Retrieves present electric current supplied by PSU Returns: A float number, electric current in amperes, e.g. 15.4 """ # psu_current = self._get_pmc_register(self.psu_current_reg) # if (psu_current != 'ERR') and self.get_presence(): # # Converting the value returned by driver which is in # # milliamperes to amperes # psu_current = float(psu_current) / 1000 # else: # psu_current = 0.0 if self._hal_psu: pass try: if isinstance(self.__reg_out_cur, Reg): return self.__reg_out_cur.decode() except Exception as e: logger.error(e.message) return 0.0 def get_power(self): """ Retrieves current energy supplied by PSU Returns: A float number, the power in watts, e.g. 302.6 """ if self._hal_psu: pass try: if isinstance(self.__reg_out_pow, Reg): return self.__reg_out_pow.decode() except Exception as e: logger.error(e.message) return 0.0 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. """ if self._hal_psu: pass else: if self.get_status() and self.get_presence(): return True return False def get_status_led(self): """ Gets the state of the PSU status LED Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ # TODO if self.get_powergood_status(): return self.STATUS_LED_COLOR_GREEN else: return self.STATUS_LED_COLOR_RED 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 Returns: bool: True if status LED state is set successfully, False if not """ # not supported return False
class Thermal(ThermalBase): def __init__(self, name, config=None, hal_thermal=None): self.name = name if config: self.__reg_low_threshold = Reg(config.get("low")) self.__reg_high_thresnold = Reg(config.get("high")) self.__reg_crit_low_threshold = Reg(config.get("crit_low")) self.__reg_crit_high_thresnold = Reg(config.get("crit_high")) self.__reg_temperature = Reg(config.get("temperature")) def get_name(self): """ Retrieves the name of the thermal Returns: string: The name of the thermal """ return self.name def get_presence(self): """ Retrieves the presence of the thermal Returns: bool: True if thermal is present, False if not """ return True def get_model(self): """ Retrieves the model number (or part number) of the Thermal Returns: string: Model/part number of Thermal """ return "NA" def get_serial(self): """ Retrieves the serial number of the Thermal Returns: string: Serial number of Thermal """ return "NA" def get_status(self): """ Retrieves the operational status of the thermal Returns: A boolean value, True if thermal is operating properly, False if not """ if self.get_temperature() == 0.0: return False return True 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 """ try: if isinstance(self.__reg_temperature, Reg): return self.__reg_temperature.decode() except Exception as e: logger.error(e.message) return None def get_high_threshold(self): """ Retrieves the high threshold temperature of thermal Returns: A float number, the high threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ try: if isinstance(self.__reg_high_thresnold, Reg): return float(self.__reg_high_thresnold.decode()) except Exception as e: logger.error(e.message) return None def get_low_threshold(self): """ Retrieves the low threshold temperature of thermal Returns: A float number, the low threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ try: if isinstance(self.__reg_low_threshold, Reg): return float(self.__reg_low_threshold.decode()) except Exception as e: logger.error(e.message) return None def set_high_threshold(self, temperature): """ Sets the high threshold temperature of thermal Args : temperature: A float number up to nearest thousandth of one degree Celsius, e.g. 30.125 Returns: A boolean, True if threshold is set successfully, False if not """ try: if isinstance(self.__reg_high_thresnold, Reg): temp_val = str(int(temperature * 1000)) return self.__reg_high_thresnold.encode(temp_val) except Exception as e: logger.error(str(e)) return False def set_low_threshold(self, temperature): """ Sets the low threshold temperature of thermal Args : temperature: A float number up to nearest thousandth of one degree Celsius, e.g. 30.125 Returns: A boolean, True if threshold is set successfully, False if not """ # not supported return False def get_high_critical_threshold(self): """ Retrieves the high critical threshold temperature of thermal Returns: A float number, the high critical threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ try: if isinstance(self.__reg_crit_high_thresnold, Reg): return float(self.__reg_crit_high_thresnold.decode()) except Exception as e: logger.error(e.message) return None def get_low_critical_threshold(self): """ Retrieves the low critical threshold temperature of thermal Returns: A float number, the low critical threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ try: if isinstance(self.__reg_crit_low_threshold, Reg): return float(self.__reg_crit_low_threshold.decode()) except Exception as e: logger.error(e.message) return None
class Component(ComponentBase): """ Ragile Platform-specific Component class""" def __init__(self, index, config=None): self.index = index self.name = config.get("name") self._reg_fm_ver = Reg(config.get("firmware_version")) self.description = config.get("desc") self.slot = config.get("slot") def get_name(self): """ Retrieves the name of the component Returns: A string containing the name of the component """ return self.name def get_description(self): """ Retrieves the description of the component Returns: A string containing the description of the component """ return self.description def get_firmware_version(self): """ Retrieves the firmware version of the component Returns: A string containing the firmware version of the component """ try: return self._reg_fm_ver.decode() except Exception as e: logger.error(str(e)) return "" def install_firmware(self, image_path): """ Installs firmware to the component Args: image_path: A string, path to firmware image Returns: A boolean, True if install was successful, False if not """ try: successtips = "CPLD Upgrade succeeded!" status, output = subprocess.getstatusoutput( "which firmware_upgrade") if status or len(output) <= 0: logger.error("no upgrade tool.") return False cmdstr = "%s %s cpld %d cpld" % (output, image_path, self.slot) ret, log = subprocess.getstatusoutput(cmdstr) if ret == 0 and successtips in log: return True logger.error("upgrade failed. ret:%d, log:\n%s" % (ret, log)) except Exception as e: logger.error(str(e)) return False
class Fan(FanBase): """Ruijie Platform-specific Fan class""" MAX_SPEED_CODE = 255 def __init__(self, index, config=None, hal_fan=None, is_psu_fan=False): self.index = index self.is_psu_fan = is_psu_fan if config: if self.is_psu_fan: self.name = "Psu{}-{}".format(self.index, config.get("name")) else: self.name = config.get("name") self.__reg_sn = Reg(config.get("sn")) self.__reg_present = Reg(config.get("present")) self.__reg_status = Reg(config.get("status")) self.__reg_led = Reg(config.get("led")) self.__reg_pn = Reg(config.get("pn")) self.__led_colors = config.get("led_colors") # rotors rotors = config.get("rotors") if isinstance(rotors, list): self.__rotors = [] for rotor in rotors: self.__rotors.append(Rotor(rotor)) self._hal_fan = hal_fan def _reg_setter(self, target, val): if isinstance(val, dict): target = Reg(val) elif isinstance(val, Reg): target = val else: raise ValueError return target @property def reg_sn(self): return self.__reg_sn @reg_sn.setter def reg_sn(self, val): self._reg_setter(self.__reg_sn, val) @property def reg_present(self): return self.__reg_present @reg_present.setter def reg_present(self, val): self._reg_setter(self.__reg_present, val) @property def reg_status(self): return self.__reg_status @reg_status.setter def reg_status(self, val): self._reg_setter(self.__reg_status, val) @property def reg_led(self): return self.__reg_led @reg_led.setter def reg_led(self, val): self._reg_setter(self.__reg_led, val) def get_name(self): """ Retrieves the fan name Returns: string: The name of the device """ return self.name def get_model(self): """ Retrieves the part number of the FAN Returns: string: Part number of FAN """ if self._hal_fan: return self._hal_fan.pn() try: if isinstance(self.__reg_pn, Reg): return self.__reg_pn.decode() except Exception as e: logger.error(str(e)) return "NA" def get_serial(self): """ Retrieves the serial number of the FAN Returns: string: Serial number of FAN """ if self._hal_fan: return self._hal_fan.sn() try: if isinstance(self.__reg_sn, Reg): return self.__reg_sn.decode() except Exception as e: logger.error(str(e)) return "NA" def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if fan is present, False if not """ # print self.fan_presence_reg.decode() # return True if self.fan_presence_reg.decode() == 0 else False if self._hal_fan: return self._hal_fan.get_presence() try: if isinstance(self.__reg_present, Reg): present = self.__reg_present.decode() if present == 0 or present == "0": return True except Exception as e: logger.error(str(e)) return False def get_status(self): """ Retrieves the operational status of the FAN Returns: bool: True if FAN is operating properly, False if not """ # return True if self.fan_status_reg.decode() == 1 else False if self._hal_fan: return self._hal_fan.get_status() try: if isinstance(self.__reg_status, Reg): status = self.__reg_status.decode() if status == 1 or status == "1": return True except Exception as e: pass return False def get_direction(self): """ Retrieves the fan airflow direction Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction Notes: - Forward/Exhaust : Air flows from Port side to Fan side. - Reverse/Intake : Air flows from Fan side to Port side. """ # TODO return self.FAN_DIRECTION_EXHAUST def get_speed(self): """ Retrieves the speed of fan Returns: int: percentage of the max fan speed """ if self.get_presence(): maxspeed = 0 for r in self.__rotors: speed = r.get_speed_percentage() if speed > maxspeed: maxspeed = speed return maxspeed else: return 0 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 """ # TODO return 0 def set_speed(self, speed): """ Set fan speed to expected value Args: speed: An integer, the percentage of full fan speed to set fan to, in the range 0 (off) to 100 (full speed) Returns: bool: True if set success, False if fail. """ if self.__rotors: speed_code = hex( int(ceil(float(self.MAX_SPEED_CODE) / 100 * speed))) return self.__rotors[0].set_speed(speed_code) return False 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. """ # TODO if self.is_psu_fan: # No LED available for PSU Fan return False try: if color not in self.__led_colors: logger.error("color:%s not defined." % color) return False val = hex(self.__led_colors[color]) if isinstance(self.__reg_led, Reg): return self.__reg_led.encode(val) return ret except Exception as e: logger.error(str(e)) return False def get_status_led(self): """ Gets the state of the Fan status LED Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ # TODO if self.is_psu_fan: # No LED available for PSU Fan return None else: try: if isinstance(self.__reg_led, Reg): led_color = self.__reg_led.decode() for color, code in self.__led_colors.items(): if code ^ led_color == 0: return color except Exception as e: logger.error(str(e)) return None def get_target_speed(self): """ Retrieves the target (expected) speed of the fan Returns: An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) """ # TODO return 0