示例#1
0
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
示例#2
0
 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))
示例#3
0
 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"))
示例#4
0
 def __init__(self, index, config=None, hal_thermal=None):
     self.index = index
     if config:
         self.name = config.get("name")
         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"))
         self.minimum_thermal = self.get_temperature()
         self.maximum_thermal = self.get_temperature()
示例#5
0
 def _reg_setter(self, target, val):
     if isinstance(val, dict):
         target = Reg(val)
     elif isinstance(val, Reg):
         target = val
     else:
         raise ValueError
     return target
示例#6
0
    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
示例#7
0
    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
示例#8
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
示例#9
0
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
示例#10
0
 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")
示例#11
0
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
示例#12
0
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