Source code for lannerpsp.sdk_hwm

import logging
import os.path
from configparser import ConfigParser
from ctypes import byref, c_float, c_int32, c_uint16, c_uint32, create_string_buffer, memset, sizeof
from os import PathLike
from re import match
from string import ascii_uppercase
from typing import Any, Dict, Iterable, List, NamedTuple, Union

from .core import PSP, get_psp_exc_msg
from .exc import (
    PSPError,
    PSPInvalid,
    PSPNotOpened,
    PSPNotSupport,
)
from .lmbinc import (
    ERR_Invalid,
    ERR_NotOpened,
    ERR_NotSupport,
    ERR_Success,
    HWM_RISER_12V,
    HWM_RISER_12VEXT,
    HWM_RISER_FAN1,
    HWM_RISER_TEMP1,
    HWM_RISER_TEMPLocal,
    HWM_RISER_VCC,
)
from .lmbipmi import (
    HWM_TYPE_NONE,
    HWM_TYPE_SIO,
    HWM_TYPE_IPMI,
    HWM_TYPE_SMBUS,
    HWM_TYPE_AST1400,
    IPMISensorInfo,
)
from .lmbsid import HWM_DISPLAY_NAME_MAPPING, HWMSensorItemV23, HWMSensorItemV30
from .sdk_dll import DLL

logger = logging.getLogger(__name__)

SUPPORTED_PLATFORMS = ("LEB-2680", "LEB-7242", "LEC-2290", "LEC-7230", "NCA-2510", "V3S", "V6S",)
UNSUPPORTED_PLATFORMS = ()

ALARM = "\033[1;31mALARM\033[m"
DEFAULT_HWM_CONF = "/etc/lanner/hwm.conf"


class _HWMSensorMsgModel(NamedTuple):
    """To store Hardware Monitor sensor message."""
    value: Union[int, float, str]
    unit: str


[docs] class HWMSensorModel(NamedTuple): """To store Hardware Monitor sensor information.""" sid: int name: str display_name: str value: Any unit: str
[docs] def to_dict(self) -> Dict[str, Any]: """Convert to dict.""" return dict(self._asdict())
[docs] class HWM: """ Hardware Monitor. :param bool check_platform: Set to :data:`True` to check if the platform supports this feature. Defaults to :data:`False` for better compatibility. :raises PSPNotSupport: This function is not supported (when ``check_platform`` is set to :data:`True`). :raises NotImplementedError: It has not been verified to run on this platform (when ``check_platform`` is set to :data:`True`). """ def __init__(self, check_platform: bool = False) -> None: self._dw_sensor_type = c_int32(0) self._version = DLL().get_version() if not check_platform: return if self._version.platform_id in SUPPORTED_PLATFORMS: pass elif self._version.platform_id in UNSUPPORTED_PLATFORMS: raise PSPNotSupport("Not supported on this platform") else: raise NotImplementedError
[docs] def get_cpu_temp(self, num: int) -> int: """ Read temperature of the CPU processor (°C). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_cpu_temp(1) 40 :param int num: selects CPU number :return: the current temperature value of the CPU :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetCpuTemp(num, byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_GetCpuTemp", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_TEMP_CPU{num:d}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {int(f_temp.value):d}") return int(f_temp.value) elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_sys_temp(self, num: int) -> int: """ Read temperature of the system (°C). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_sys_temp(1) 41 :param int num: selects System sensor number :return: the current temperature value of the system :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetSysTemp(num, byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_GetSysTemp", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_TEMP_SYS{num:d}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {int(f_temp.value):d}") return int(f_temp.value) elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_core_volt(self, num: int) -> float: """ Read the CPU Vcore voltage (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_core_volt(1) 0.856 :param int num: selects CPU number :return: the current voltage of CPU Vcore :rtype: float :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetVcore(num, byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_GetVcore", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_VCORE_CPU{num:d}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_12v_volt(self) -> float: """ Read the positive 12V voltage (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_12v_volt() 12.232 :return: the current voltage of positive 12V :rtype: float :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_Get12V(byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_Get12V", i_ret) if i_ret == ERR_Success: # hwm_id = "HWMID_VOLT_P12V" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_5v_volt(self) -> float: """ Read the positive 5V voltage (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_5v_volt() 5.087 :return: the current voltage of positive 5V :rtype: float :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_Get5V(byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_Get5V", i_ret) if i_ret == ERR_Success: # hwm_id = "HWMID_VOLT_P5V" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_3v3_volt(self) -> float: """ Read the positive 3.3V voltage (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_3v3_volt() 3.328 :return: the current voltage of positive 3.3V :rtype: float :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_Get3V3(byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_Get3V3", i_ret) if i_ret == ERR_Success: # hwm_id = "HWMID_VOLT_P3V3" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_5vsb_volt(self) -> float: """ Read the positive 5V standby power (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_5vsb_volt() 5.003 :return: the current voltage of positive 5V standby power :rtype: float :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_Get5Vsb(byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_Get5Vsb", i_ret) if i_ret == ERR_Success: # hwm_id = "HWMID_VOLT_P5VSB" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_3v3sb_volt(self) -> float: """ Read the positive 3V/3.3V standby power (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_3v3sb_volt() 3.344 :return: the current voltage of positive 3.3V standby power :rtype: float :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_Get3V3sb(byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_Get3V3sb", i_ret) if i_ret == ERR_Success: # hwm_id = "HWMID_VOLT_P3V3SB" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_bat_volt(self) -> float: """ Read the battery voltage (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_bat_volt() 3.168 :return: the current voltage of the battery :rtype: float :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetVbat(byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_GetVbat", i_ret) if i_ret == ERR_Success: # hwm_id = "HWMID_VOLT_VBAT" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_dimm_volt(self, ch: int) -> float: """ Read the DRAM voltage (V). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_dimm_volt() 1.096 :param int ch: the DDR channel :return: the current voltage of the DDR channel :rtype: float :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(ch, int): raise TypeError("'num' type must be int") f_temp = c_float() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetVDDR(ch, byref(f_temp)) msg = get_psp_exc_msg("LMB_HWM_GetVDDR", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_VOLT_DDRCH{ch:d}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {f_temp.value:2.3f}") return float(f"{f_temp.value:2.3f}") elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_psu_volt(self, num: int) -> int: """ Read the power supply AC input (V). :param int num: the AC power supply number which is described in user manual :return: the AC power voltage :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # TODO: Example # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") w_data = c_uint16() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetPowerSupply(num, byref(w_data)) msg = get_psp_exc_msg("LMB_HWM_GetPowerSupply", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_PSU{num:d}_VOLTIN" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {w_data.value:d}") return w_data.value elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_cpu_fan_speed(self, num: int) -> int: """ Get CPU fan speed (RPM). :param int num: the number of fan :return: the fan speed :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # TODO: Example # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") w_rpm = c_uint16() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetCpuFan(num, byref(w_rpm)) msg = get_psp_exc_msg("LMB_HWM_GetCpuFan", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_RPM_FanCpu{num:d}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {int(w_rpm.value):d}") return int(w_rpm.value) elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_sys_fan_speed(self, num: int) -> int: """ Get SYS fan speed (RPM). :param int num: the number of fan :return: the fan speed :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # TODO: Example # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") w_rpm = c_uint16() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetSysFan(num, byref(w_rpm)) msg = get_psp_exc_msg("LMB_HWM_GetSysFan", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_RPM_FanSys{num:d}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {int(w_rpm.value):d}") return int(w_rpm.value) elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_fan_speed(self, num: int) -> int: """ Read the fan speed which was assigned (RPM). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_fan_speed(1) 7297 :param int num: the fan index number which is described in user manual :return: the fan speed :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") w_rpm = c_uint16() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetFanSpeed(num, byref(w_rpm)) msg = get_psp_exc_msg("LMB_HWM_GetFanSpeed", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_RPM_Fan{num:d}A" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {int(w_rpm.value):d}") return int(w_rpm.value) elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_fan_speed_ex(self, num: int, ex_num: int) -> int: """ Read the fan speed which was assigned (RPM). Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_fan_speed_ex(1, 1) 7258 :param int num: the fan index number which is described in user manual :param int ex_num: the fan sub-index number which is described in user manual (A=1, B=2, and so on) :return: the fan speed :rtype: int :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(num, int): raise TypeError("'num' type must be int") if not isinstance(ex_num, int): raise TypeError("'ex_num' type must be int") w_rpm = c_uint16() with PSP() as psp: i_ret = psp.lib.LMB_HWM_GetFanSpeedEx(num, byref(w_rpm), ex_num) msg = get_psp_exc_msg("LMB_HWM_GetFanSpeedEx", i_ret) if i_ret == ERR_Success: # hwm_id = f"HWMID_RPM_Fan{num:d}{ascii_uppercase[ex_num - 1]}" # logger.debug(f"{HWM_DISPLAY_NAME_MAPPING[hwm_id]} = {int(w_rpm.value):d}") return int(w_rpm.value) elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_sensor_name(self, sid: int) -> str: """ Get the sensor ID name by PSP define. Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_sensor_name(0) 'HWMID_TEMP_CPU1' :param int sid: sensor index number :return: the sensor name of the designated :rtype: str :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(sid, int): raise TypeError("'sid' type must be int") # Check value. if self._version.dll_major == 2 and self._version.dll_minor == 1: pass # Can not check. elif self._version.dll_major == 2 and self._version.dll_minor == 3: if sid not in range(HWMSensorItemV23.HWMID_TOTAL.value): raise PSPInvalid(f"'sid' value must be in range({HWMSensorItemV23.HWMID_TOTAL.value})") elif self._version.dll_major == 3 and self._version.dll_minor == 0: if sid not in range(HWMSensorItemV30.HWMID_TOTAL.value): raise PSPInvalid(f"'sid' value must be in range({HWMSensorItemV30.HWMID_TOTAL.value})") else: raise NotImplementedError str_id_name = create_string_buffer(50) memset(str_id_name, 0, 30) with PSP() as psp: if self._version.dll_major == 2 and self._version.dll_minor in (1, 2, 3): i_ret = psp.lib.LMB_HWM_GetSensorName(sid, str_id_name) elif self._version.dll_major == 3 and self._version.dll_minor == 0: i_ret = psp.lib.LMB_HWM_GetSensorName(sid, str_id_name, sizeof(str_id_name)) msg = get_psp_exc_msg("LMB_HWM_GetSensorName", i_ret) if i_ret == ERR_Success: name: str = str_id_name.value.decode(errors="ignore") # logger.debug(f"Sensor ID={sid:d}, name is \"{name}\"") return name elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def get_sensor_msg(self, sid: int) -> str: """ Read the sensor report message. Example: .. code-block:: pycon >>> hwm = HWM() >>> hwm.get_sensor_msg(0) '41000 mCelsius' :param int sid: sensor index number :return: the message of the designated :rtype: str :raises TypeError: The input parameters type error. :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ # Check type. if not isinstance(sid, int): raise TypeError("'sid' type must be int") # Check value. if self._version.dll_major == 2 and self._version.dll_minor == 1: pass elif self._version.dll_major == 2 and self._version.dll_minor == 3: if sid not in range(HWMSensorItemV23.HWMID_TOTAL.value): raise PSPInvalid(f"'sid' value must be in range({HWMSensorItemV23.HWMID_TOTAL.value})") elif self._version.dll_major == 3 and self._version.dll_minor == 0: if sid not in range(HWMSensorItemV30.HWMID_TOTAL.value): raise PSPInvalid(f"'sid' value must be in range({HWMSensorItemV30.HWMID_TOTAL.value})") else: raise NotImplementedError str_msg = create_string_buffer(50) memset(str_msg, 0, 30) with PSP() as psp: if self._version.dll_major == 2 and self._version.dll_minor in (1, 2, 3): i_ret = psp.lib.LMB_HWM_GetSensorReport(sid, str_msg) elif self._version.dll_major == 3 and self._version.dll_minor == 0: i_ret = psp.lib.LMB_HWM_GetSensorReport(sid, str_msg, sizeof(str_msg)) msg = get_psp_exc_msg("LMB_HWM_GetSensorReport", i_ret) if i_ret == ERR_Success: message: str = str_msg.value.decode(errors="ignore") # logger.debug(f"Sensor ID={sid:d}, message is \"{message}\"") return message elif i_ret == ERR_NotOpened: raise PSPNotOpened(msg) elif i_ret == ERR_Invalid: raise PSPInvalid(msg) elif i_ret == ERR_NotSupport: raise PSPNotSupport(msg) else: raise PSPError(msg)
[docs] def list_supported_sensors(self, with_graphic_card: bool = False) -> List[HWMSensorModel]: """ List all supported sensors. Example: .. code-block:: pycon >>> hwm = HWM() >>> sensors = hwm.list_supported_sensors() >>> for s in sensors: ... s.to_dict() {'sid': 0, 'name': 'HWMID_TEMP_CPU1', 'display_name': 'CPU 1 temperature', 'value': 40, 'unit': 'C'} {'sid': 2, 'name': 'HWMID_TEMP_SYS1', 'display_name': 'SYS 1 temperature', 'value': 42, 'unit': 'C'} . . . {'sid': 12, 'name': 'HWMID_VOLT_DDRCH1', 'display_name': 'DDR channel 1', 'value': 1.096, 'unit': 'V'} >>> for s in sensors: ... print(f"{s.display_name} = {s.value} {s.unit}") ... CPU-1 temperature = 40 C SYS-1 temperature = 42 C . . . VDIMM-1 = 1.096 V :param bool with_graphic_card: Set to :data:`True` to merge graphics card information (if supported). Defaults to :data:`False` for better performance. :return: list of supported sensor model :rtype: List[HWMSensorModel] :raises PSPNotOpened: The library is not ready or opened yet. :raises PSPInvalid: The input parameter is out of range. :raises PSPNotSupport: This platform does not support this function. :raises PSPError: General PSP functional error. """ if self._version.dll_major == 2 and self._version.dll_minor == 1: total = 100 elif self._version.dll_major == 2 and self._version.dll_minor in (2, 3): total = HWMSensorItemV23.HWMID_TOTAL.value elif self._version.dll_major == 3 and self._version.dll_minor == 0: total = HWMSensorItemV30.HWMID_TOTAL.value else: raise NotImplementedError supported_sensors = [] for i in range(total): try: message = self.get_sensor_msg(i) except PSPError: continue name = self.get_sensor_name(i) display_name = HWM_DISPLAY_NAME_MAPPING.get(name, None) if display_name is None: continue parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=i, name=name, display_name=display_name, value=parsed_msg.value, unit=parsed_msg.unit)) if with_graphic_card: # For LEC-2290 with PSP version 2.1.X: if self._version.platform_id in ("LEC-2290",) and self._version.dll_major == 2 and self._version.dll_minor == 1: str_msg = create_string_buffer(30) with PSP() as psp: for x in range(1, 3): sid = HWM_RISER_TEMP1 + x - 1 if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mCelsius" parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=sid, name="", display_name=f"Graphic Card Temp-{x}", value=parsed_msg.value, unit=parsed_msg.unit)) for x in range(1, 3): sid = HWM_RISER_FAN1 + x - 1 if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 RPM" parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=sid, name="", display_name=f"Graphic Card FAN-{x}", value=parsed_msg.value, unit=parsed_msg.unit)) # For PSP version 2.1.2: if self._version.dll_build == 2: sid = HWM_RISER_TEMPLocal if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mCelsius" parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=sid, name="", display_name=f"Graphic Card Temp-Chip", value=parsed_msg.value, unit=parsed_msg.unit)) sid = HWM_RISER_VCC if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mVolts" parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=sid, name="", display_name=f"Graphic Card 3.3V", value=parsed_msg.value, unit=parsed_msg.unit)) sid = HWM_RISER_12V if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mVolts" parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=sid, name="", display_name=f"Graphic Card 12V", value=parsed_msg.value, unit=parsed_msg.unit)) sid = HWM_RISER_12VEXT if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mVolts" parsed_msg = self._parse_sensor_msg(msg=message) supported_sensors.append(HWMSensorModel(sid=sid, name="", display_name=f"Graphic Card 12VEXT", value=parsed_msg.value, unit=parsed_msg.unit)) return supported_sensors
@classmethod def _parse_sensor_msg(cls, msg: str) -> _HWMSensorMsgModel: """ Parse sensor message from :meth:`get_sensor_name`. :param str msg: Output message from :meth:`get_sensor_name`. :return: The :class:`_HWMSensorMsgModel` model. :rtype: _HWMSensorMsgModel """ value_str, unit = msg.strip().split() if unit in ("mCelsius",): value = int(value_str) // 1000 unit = "C" elif unit in ("mVolts",): value = int(value_str) / 1000 unit = "V" elif unit in ("mAmps",): value = int(value_str) / 1000 unit = "A" elif unit in ("mWatts",): value = int(value_str) / 1000 unit = "W" elif unit in ("Volts",): value = int(value_str) unit = "V" elif unit in ("RPM",): value = int(value_str) unit = "RPM" elif unit in ("Status",): value = value_str unit = "Status" else: value = value_str # NotImplementedError return _HWMSensorMsgModel(value=value, unit=unit) def testhwm( self, conf_path: Union[ str, bytes, "PathLike[str]", "PathLike[bytes]", Iterable[Union[str, bytes, "PathLike[str]", "PathLike[bytes]"]], ] = "/opt/lanner/psp/bin/amd64/utils/hwm.conf", ) -> None: """ For hardware monitor testing. Example for PSP version < 2.3: .. code-block:: pycon >>> hwm = HWM() >>> hwm.testhwm() CPU-1 temperature = 40 C (min = 30 C, max = 85 C) SYS-1 temperature = 41 C (min = 25 C, max = 65 C) CPU-1 Vcore = 0.856 V (min = 0.600 V, max = 2.000 V) 5V = 5.087 V (min = 4.500 V, max = 5.500 V) 3.3V = 3.350 V (min = 2.970 V, max = 3.630 V) Vbat = 3.168 V (min = 3.000 V, max = 3.300 V) VDDR = 1.104 V (min = 1.080 V, max = 1.320 V) or PSP version >= 2.3: .. code-block:: pycon >>> hwm = HWM() >>> hwm.testhwm() ===> Hardware Monitor Type is SuperIO <=== Sensor Name Value LowCritical UpperCritical Result ------------------------------------------------------------------------- SYS1 Temp = 40 C (min = -5 C, max = 70 C) SYS2 Temp = 39 C (min = -5 C, max = 70 C) Vcore = 0.784 V (min = 0.450 V, max = 1.350 V) VGFX = 0.824 V (min = 0.450 V, max = 1.350 V) 12V = 12.232 V (min = 11.400 V, max = 12.600 V) 5V = 5.003 V (min = 4.750 V, max = 5.250 V) VCC3V = 3.344 V (min = 3.130 V, max = 3.460 V) VSB3V = 3.344 V (min = 3.130 V, max = 3.460 V) VBAT = 3.280 V (min = 2.000 V, max = 3.470 V) :type conf_path: str or bytes or PathLike[str] or PathLike[bytes] or Iterable[str or bytes or PathLike[str] or PathLike[bytes]] :param conf_path: path of the `hwm.conf` """ if self._version.dll_major == 2 and self._version.dll_minor == 1: self._hwm_tst_v21(conf_path) elif self._version.dll_major == 2 and self._version.dll_minor == 3: self._hwm_tst_v23(conf_path) elif self._version.dll_major == 3 and self._version.dll_minor == 0: self._hwm_tst_v30(conf_path) else: raise NotImplementedError def _hwm_tst_v21( self, conf_path: Union[ str, bytes, "PathLike[str]", "PathLike[bytes]", Iterable[Union[str, bytes, "PathLike[str]", "PathLike[bytes]"]], ], ) -> None: """ For PSP version == '2.1.X'. """ f_temp = c_float() w_data = c_uint16() w_rpm = c_uint16() cp = ConfigParser() cp.read(conf_path) with PSP() as psp: # Temperature area if psp.lib.LMB_HWM_GetCpuTemp(1, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_CPU1_Temp", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_CPU1_Temp", "max", fallback="0")) msg = f"CPU-1 temperature = {int(f_temp.value):3d} C\t" \ f"(min = {min_:3.0f} C, max = {max_:3.0f} C)" if f_temp.value < min_ or f_temp.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetCpuTemp(2, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_CPU2_Temp", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_CPU2_Temp", "max", fallback="0")) msg = f"CPU-2 temperature = {int(f_temp.value):3d} C\t" \ f"(min = {min_:3.0f} C, max = {max_:3.0f} C)" if f_temp.value < min_ or f_temp.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetSysTemp(1, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_SYS1_Temp", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_SYS1_Temp", "max", fallback="0")) msg = f"SYS-1 temperature = {int(f_temp.value):3d} C\t" \ f"(min = {min_:3.0f} C, max = {max_:3.0f} C)" if f_temp.value < min_ or f_temp.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetSysTemp(2, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_SYS2_Temp", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_SYS2_Temp", "max", fallback="0")) msg = f"SYS-2 temperature = {int(f_temp.value):3d} C\t" \ f"(min = {min_:3.0f} C, max = {max_:3.0f} C)" if f_temp.value < min_ or f_temp.value > max_: msg += f" {ALARM}" print(msg) # Voltage area if psp.lib.LMB_HWM_GetVcore(1, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_Core1_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_Core1_volt", "max", fallback="0")) msg = f"CPU-1 Vcore = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetVcore(2, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_Core2_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_Core2_volt", "max", fallback="0")) msg = f"CPU-2 Vcore = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_Get12V(byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_12v_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_12v_volt", "max", fallback="0")) msg = f"12V = {f_temp.value:7.3f} V\t\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_Get5V(byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_5v_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_5v_volt", "max", fallback="0")) msg = f"5V = {f_temp.value:7.3f} V\t\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_Get3V3(byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_3v3_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_3v3_volt", "max", fallback="0")) msg = f"3.3V = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_Get5Vsb(byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_5vsb_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_5vsb_volt", "max", fallback="0")) msg = f"5VSB = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_Get3V3sb(byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_3v3sb_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_3v3sb_volt", "max", fallback="0")) msg = f"3.3VSB = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetVbat(byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_vBat_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_vBat_volt", "max", fallback="0")) msg = f"Vbat = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetVDDR(1, byref(f_temp)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_vddr_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_vddr_volt", "max", fallback="0")) msg = f"VDDR = {f_temp.value:7.3f} V\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" round_up_buffer = int(f_temp.value * 1000) if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetPowerSupply(1, byref(w_data)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_PSU1_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_PSU1_volt", "max", fallback="0")) msg = f"PowerSupply 1 AC voltage = {w_data.value:3d} V\t" \ f"(min = {min_:3.0f} V, max = {max_:3.0f} V)" if w_data.value < min_ or w_data.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetPowerSupply(2, byref(w_data)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_PSU2_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_PSU2_volt", "max", fallback="0")) msg = f"PowerSupply 2 AC voltage = {w_data.value:3d} V\t" \ f"(min = {min_:3.0f} V, max = {max_:3.0f} V)" if w_data.value < min_ or w_data.value > max_: msg += f" {ALARM}" print(msg) # Fan area if psp.lib.LMB_HWM_GetCpuFan(1, byref(w_rpm)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_CPU1_RPM", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_CPU1_RPM", "max", fallback="0")) msg = f"CPU FAN 1 speed = {w_rpm.value:5d} rpm\t" \ f"(min = {min_:5.0f} rpm, max = {max_:5.0f} rpm)" if w_rpm.value < min_ or w_rpm.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetCpuFan(2, byref(w_rpm)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_CPU2_RPM", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_CPU2_RPM", "max", fallback="0")) msg = f"CPU FAN 2 speed = {w_rpm.value:5d} rpm\t" \ f"(min = {min_:5.0f} rpm, max = {max_:5.0f} rpm)" if w_rpm.value < min_ or w_rpm.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetSysFan(1, byref(w_rpm)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_SYS1_RPM", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_SYS1_RPM", "max", fallback="0")) msg = f"SYS FAN 1 speed = {w_rpm.value:5d} rpm\t" \ f"(min = {min_:5.0f} rpm, max = {max_:5.0f} rpm)" if w_rpm.value < min_ or w_rpm.value > max_: msg += f" {ALARM}" print(msg) if psp.lib.LMB_HWM_GetSysFan(2, byref(w_rpm)) == ERR_Success: min_ = self._str_replace(cp.get("HWM_SYS2_RPM", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_SYS2_RPM", "max", fallback="0")) msg = f"SYS FAN 2 speed = {w_rpm.value:5d} rpm\t" \ f"(min = {min_:5.0f} rpm, max = {max_:5.0f} rpm)" if w_rpm.value < min_ or w_rpm.value > max_: msg += f" {ALARM}" print(msg) # For LEC-2290 with PSP version 2.1.X: if self._version.platform_id in ("LEC-2290",) and self._version.dll_major == 2 and self._version.dll_minor == 1: for i in range(100, 0, -1): # Searching from behind will be faster. name = self.get_sensor_name(i) if name != "HWMID_VOLT_VCCGT": continue min_ = self._str_replace(cp.get("HWM_vccgt_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_vccgt_volt", "max", fallback="0")) message = self.get_sensor_msg(sid=i) value = self._parse_sensor_msg(msg=message).value msg = f"VGT = {value:7.3f} V\t\t\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) break print("\033[2;31m=================== Graphic Card Sensor Items ======================\033[m") str_msg = create_string_buffer(30) with PSP() as psp: for x in range(1, 3): sid = HWM_RISER_TEMP1 + x - 1 min_ = self._str_replace(cp.get("HWM_RISER_TEMP", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_RISER_TEMP", "max", fallback="0")) if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mCelsius" value = self._parse_sensor_msg(msg=message).value msg = f"Graphic Card Temp-{x:d} = {int(value):3d} C\t" \ f"(min = {min_:7.0f} C, max = {max_:7.0f} C)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) for x in range(1, 3): sid = HWM_RISER_FAN1 + x - 1 min_ = self._str_replace(cp.get("HWM_RISER_FAN", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_RISER_FAN", "max", fallback="0")) if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 RPM" value = self._parse_sensor_msg(msg=message).value msg = f"Graphic Card FAN-{x:d} = {value:5d} rpm\t" \ f"(min = {min_:5.0f} rpm, max = {max_:5.0f} rpm)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) # For PSP version 2.1.2: if self._version.dll_build == 2: sid = HWM_RISER_TEMPLocal min_ = self._str_replace(cp.get("HWM_RISER_LOCAL", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_RISER_LOCAL", "max", fallback="0")) if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mCelsius" value = self._parse_sensor_msg(msg=message).value msg = f"Graphic Card Temp-Chip = {int(value):3d} C\t" \ f"(min = {min_:7.0f} C, max = {max_:7.0f} C)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) sid = HWM_RISER_VCC min_ = self._str_replace(cp.get("HWM_3v3_volt", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_3v3_volt", "max", fallback="0")) if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mVolts" value = self._parse_sensor_msg(msg=message).value msg = f"Graphic Card 3.3V = {value:7.3f} V\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) sid = HWM_RISER_12V min_ = self._str_replace(cp.get("HWM_RISER_12v", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_RISER_12v", "max", fallback="0")) if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mVolts" value = self._parse_sensor_msg(msg=message).value msg = f"Graphic Card 12V = {value:7.3f} V\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) sid = HWM_RISER_12VEXT min_ = self._str_replace(cp.get("HWM_RISER_12v", "min", fallback="0")) max_ = self._str_replace(cp.get("HWM_RISER_12v", "max", fallback="0")) if psp.lib.LMB_HWM_GetF75837(sid, str_msg) != ERR_NotSupport: message: str = str_msg.value.decode(errors="ignore") or "0 mVolts" value = self._parse_sensor_msg(msg=message).value msg = f"Graphic Card 12VEXT = {value:7.3f} V\t" \ f"(min = {min_:7.3f} V, max = {max_:7.3f} V)" if value < min_ or value > max_: msg += f" {ALARM}" print(msg) def _hwm_tst_v23( self, conf_path: Union[ str, bytes, "PathLike[str]", "PathLike[bytes]", Iterable[Union[str, bytes, "PathLike[str]", "PathLike[bytes]"]], ], ) -> None: """ For PSP version == '2.3.X'. """ show_ipmi_only = False if os.path.isfile(conf_path): print(f"\033[1;31m<Note> found {conf_path} file, critical value will change !!!\033[m") else: conf_path = DEFAULT_HWM_CONF if os.path.isfile(conf_path): print(f"\033[1;31m<Note> found {conf_path} file, critical value will change !!!\033[m") cp = ConfigParser() cp.read(conf_path) with PSP() as psp: psp.lib.LMB_HWM_GetSensorType(byref(self._dw_sensor_type)) if self._dw_sensor_type.value == HWM_TYPE_NONE: print("\033[1;31m<Warning> Hardware Monitor Type is Unknown !!!\033[m") return elif self._dw_sensor_type.value == HWM_TYPE_IPMI: show_ipmi_only = True print("\033[1;34m===> Hardware Monitor Type is IPMI <===\033[m") elif self._dw_sensor_type.value == HWM_TYPE_AST1400: print("\033[1;34m===> Hardware Monitor Type is AST-1400 <===\033[m") elif self._dw_sensor_type.value == HWM_TYPE_SMBUS: print("\033[1;34m===> Hardware Monitor Type is SMBus <===\033[m") elif self._dw_sensor_type.value == HWM_TYPE_SIO: print("\033[1;34m===> Hardware Monitor Type is SuperIO <===\033[m") else: print("\033[1;31m<Warning> Hardware Monitor Type is Unknown !!!\033[m") return print("Sensor Name Value LowCritical UpperCritical Result") print("-------------------------------------------------------------------------") # CPU Temperature sid = HWMSensorItemV23.HWMID_TEMP_CPU1.value for i in range(sid, sid + 4): self._show_temperature_v23(i, cp) # SYS Temperature sid = HWMSensorItemV23.HWMID_TEMP_SYS1.value for i in range(sid, sid + 4): self._show_temperature_v23(i, cp) # PCH Temperature sid = HWMSensorItemV23.HWMID_TEMP_PCH.value self._show_temperature_v23(sid, cp) # CPU DIMM Temperature sid = HWMSensorItemV23.HWMID_TEMP_DIMMP1A0.value for i in range(sid, sid + 32): self._show_temperature_v23(i, cp) # CPU Vcore sid = HWMSensorItemV23.HWMID_VCORE_CPU1.value for i in range(sid, sid + 4): self._show_voltage_v23(i, cp) # P12V sid = HWMSensorItemV23.HWMID_VOLT_P12V.value self._show_voltage_v23(sid, cp) # P5V sid = HWMSensorItemV23.HWMID_VOLT_P5V.value self._show_voltage_v23(sid, cp) # P3.3V sid = HWMSensorItemV23.HWMID_VOLT_P3V3.value self._show_voltage_v23(sid, cp) # P5VSB sid = HWMSensorItemV23.HWMID_VOLT_P5VSB.value self._show_voltage_v23(sid, cp) # P3.3VSB sid = HWMSensorItemV23.HWMID_VOLT_P3V3SB.value self._show_voltage_v23(sid, cp) # VBAT sid = HWMSensorItemV23.HWMID_VOLT_VBAT.value self._show_voltage_v23(sid, cp) # 1.05V sid = HWMSensorItemV23.HWMID_VOLT_P1V05.value self._show_voltage_v23(sid, cp) # VCCIO sid = HWMSensorItemV23.HWMID_VOLT_PVCCIO_CPU1.value for i in range(sid, sid + 4): self._show_voltage_v23(i, cp) # VCCSA sid = HWMSensorItemV23.HWMID_VOLT_PVCCSA_CPU1.value for i in range(sid, sid + 4): self._show_voltage_v23(i, cp) # VNN sid = HWMSensorItemV23.HWMID_VOLT_PVNN.value self._show_voltage_v23(sid, cp) # DDR Voltage sid = HWMSensorItemV23.HWMID_VOLT_DDRCH1.value for i in range(sid, sid + 8): self._show_voltage_v23(i, cp) # extern sensors sid = HWMSensorItemV23.HWMID_PSU2_TEMP2.value + 1 for i in range(sid, HWMSensorItemV23.HWMID_TOTAL.value): self._show_voltage_v23(i, cp) sid = HWMSensorItemV23.HWMID_RPM_Fan1A.value for i in range(10): self._show_rpm_v23(i * 2 + sid, cp) self._show_rpm_v23(i * 2 + sid + 1, cp) # IPMI PSU for i in range(2): if show_ipmi_only: print("\033[2;31m================ For PSU when BMC exist ==========================\033[m") show_ipmi_only = False # PSU VIn sid = HWMSensorItemV23.HWMID_PSU1_VOLTIN.value + 11 * i self._show_voltage_v23(sid, cp) # PSU Vout sid = HWMSensorItemV23.HWMID_PSU1_VOLTOUT.value + 11 * i self._show_voltage_v23(sid, cp) # PSU Current In sid = HWMSensorItemV23.HWMID_PSU1_CURRENTIN.value + 11 * i self._show_current_v23(sid, cp) # PSU Current Out sid = HWMSensorItemV23.HWMID_PSU1_CURRENTOUT.value + 11 * i self._show_current_v23(sid, cp) # PSU Power In sid = HWMSensorItemV23.HWMID_PSU1_POWERIN.value + 11 * i self._show_watts_v23(sid, cp) # PSU Power Out sid = HWMSensorItemV23.HWMID_PSU1_POWEROUT.value + 11 * i self._show_watts_v23(sid, cp) # PSU Fan 1 sid = HWMSensorItemV23.HWMID_PSU1_FAN1.value + 11 * i self._show_rpm_v23(sid, cp) # PSU Fan 2 sid = HWMSensorItemV23.HWMID_PSU1_FAN2.value + 11 * i self._show_rpm_v23(sid, cp) # PSU Temp 1 sid = HWMSensorItemV23.HWMID_PSU1_TEMP1.value + 11 * i self._show_temperature_v23(sid, cp) # PSU Temp 2 sid = HWMSensorItemV23.HWMID_PSU1_TEMP2.value + 11 * i self._show_temperature_v23(sid, cp) def _show_temperature_v23(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '2.3.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() udw_lo_critical = c_uint32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(udw_lo_critical), byref(udw_hi_critical)) min_ = udw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) temp = self._atoll(str_msg.value.decode()) / 1000 if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = --N/A-- C, max = {int(max_):7d} C)", end="") if temp > max_: print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = {int(min_):7d} C, max = --N/A-- C)", end="") if temp < min_: print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = --N/A-- C, max = --N/A-- C)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = {int(min_):7d} C, max = {int(max_):7d} C)", end="") if temp < min_ or temp > max_: print(f" {ALARM}", end="") print() def _show_rpm_v23(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '2.3.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() udw_lo_critical = c_uint32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(udw_lo_critical), byref(udw_hi_critical)) min_ = udw_lo_critical.value max_ = udw_hi_critical.value else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) rpm = self._atoll(str_msg.value.decode()) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = --N/A-- rpm, max = {int(max_):5d} rpm)", end="") if rpm > max_: print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = {int(min_):5d} rpm, max = --N/A-- rpm)", end="") if rpm < min_: print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = --N/A-- rpm, max = --N/A-- rpm)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = {int(min_):5d} rpm, max = {int(max_):5d} rpm)", end="") if rpm < min_ or rpm > max_: print(f" {ALARM}", end="") print() def _show_voltage_v23(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '2.3.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() udw_lo_critical = c_uint32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(udw_lo_critical), byref(udw_hi_critical)) min_ = udw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) volt = self._atoll(str_msg.value.decode()) / 1000 round_up_buffer = int(volt * 1000) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = --N/A-- V, max = {max_:7.3f} V)", end="") if round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = {min_:7.3f} V, max = --N/A-- V)", end="") if round_up_buffer < int(min_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = --N/A-- V, max = --N/A-- V)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = {min_:7.3f} V, max = {max_:7.3f} V)", end="") if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") print() def _show_current_v23(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '2.3.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() udw_lo_critical = c_uint32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(udw_lo_critical), byref(udw_hi_critical)) min_ = udw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) current = self._atoll(str_msg.value.decode()) / 1000 round_up_buffer = int(current * 1000) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = --N/A-- A, max = {max_:7.3f} A)", end="") if round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = {min_:7.3f} A, max = --N/A-- A)", end="") if round_up_buffer < int(min_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = --N/A-- A, max = --N/A-- A)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = {min_:7.3f} A, max = {max_:7.3f} A)", end="") if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") print() def _show_watts_v23(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '2.3.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() udw_lo_critical = c_uint32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(udw_lo_critical), byref(udw_hi_critical)) min_ = udw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) watts = self._atoll(str_msg.value.decode()) / 1000 round_up_buffer = int(watts * 1000) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = --N/A-- W, max = {max_:7.3f} W)", end="") if round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = {min_:7.3f} W, max = --N/A-- W)", end="") if round_up_buffer < int(min_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = --N/A-- W, max = --N/A-- W)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = {min_:7.3f} W, max = {max_:7.3f} W)", end="") if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") print() def _hwm_tst_v30( self, conf_path: Union[ str, bytes, "PathLike[str]", "PathLike[bytes]", Iterable[Union[str, bytes, "PathLike[str]", "PathLike[bytes]"]], ], ) -> None: """ For PSP version == '3.0.X'. """ show_ipmi_only = False if os.path.isfile(conf_path): print(f"\033[1;31m<Note> found {conf_path} file, critical value will change !!!\033[m") else: conf_path = DEFAULT_HWM_CONF if os.path.isfile(conf_path): print(f"\033[1;31m<Note> found {conf_path} file, critical value will change !!!\033[m") cp = ConfigParser() cp.read(conf_path) with PSP() as psp: psp.lib.LMB_HWM_GetSensorType(byref(self._dw_sensor_type)) if self._dw_sensor_type.value == HWM_TYPE_NONE: print("\033[1;31m<Warning> Hardware Monitor Type is Unknown !!!\033[m") return elif self._dw_sensor_type.value == HWM_TYPE_IPMI: show_ipmi_only = True print("\033[1;34m===> Hardware Monitor Type is IPMI <===\033[m") elif self._dw_sensor_type.value == HWM_TYPE_AST1400: print("\033[1;34m===> Hardware Monitor Type is AST-1400 <===\033[m") elif self._dw_sensor_type.value == HWM_TYPE_SMBUS: print("\033[1;34m===> Hardware Monitor Type is SMBus <===\033[m") elif self._dw_sensor_type.value == HWM_TYPE_SIO: print("\033[1;34m===> Hardware Monitor Type is SuperIO <===\033[m") else: print("\033[1;31m<Warning> Hardware Monitor Type is Unknown !!!\033[m") return print("Sensor Name Value LowCritical UpperCritical Result") print("-------------------------------------------------------------------------") # CPU Temperature sid = HWMSensorItemV30.HWMID_TEMP_CPU1.value for i in range(sid, sid + 4): self._show_temperature_v30(i, cp) # SYS Temperature sid = HWMSensorItemV30.HWMID_TEMP_SYS1.value for i in range(sid, sid + 4): self._show_temperature_v30(i, cp) # PCH Temperature sid = HWMSensorItemV30.HWMID_TEMP_PCH.value self._show_temperature_v30(sid, cp) # CPU DIMM Temperature sid = HWMSensorItemV30.HWMID_TEMP_DIMMP1A0.value for i in range(sid, sid + 32): self._show_temperature_v30(i, cp) # CPU Vcore sid = HWMSensorItemV30.HWMID_VCORE_CPU1.value for i in range(sid, sid + 4): self._show_voltage_v30(i, cp) # P12V sid = HWMSensorItemV30.HWMID_VOLT_P12V.value self._show_voltage_v30(sid, cp) # P5V sid = HWMSensorItemV30.HWMID_VOLT_P5V.value self._show_voltage_v30(sid, cp) # P3.3V sid = HWMSensorItemV30.HWMID_VOLT_P3V3.value self._show_voltage_v30(sid, cp) # P5VSB sid = HWMSensorItemV30.HWMID_VOLT_P5VSB.value self._show_voltage_v30(sid, cp) # P3.3VSB sid = HWMSensorItemV30.HWMID_VOLT_P3V3SB.value self._show_voltage_v30(sid, cp) # VBAT sid = HWMSensorItemV30.HWMID_VOLT_VBAT.value self._show_voltage_v30(sid, cp) # 1.05V sid = HWMSensorItemV30.HWMID_VOLT_P1V05.value self._show_voltage_v30(sid, cp) # VCCIO sid = HWMSensorItemV30.HWMID_VOLT_PVCCIO_CPU1.value for i in range(sid, sid + 4): self._show_voltage_v30(i, cp) # VCCSA sid = HWMSensorItemV30.HWMID_VOLT_PVCCSA_CPU1.value for i in range(sid, sid + 4): self._show_voltage_v30(i, cp) # VNN sid = HWMSensorItemV30.HWMID_VOLT_PVNN.value self._show_voltage_v30(sid, cp) # DDR Voltage sid = HWMSensorItemV30.HWMID_VOLT_DDRCH1.value for i in range(sid, sid + 8): self._show_voltage_v30(i, cp) # extern sensors sid = HWMSensorItemV30.HWMID_PSU2_TEMP2.value + 1 for i in range(sid, HWMSensorItemV30.HWMID_TOTAL.value): self._show_voltage_v30(i, cp) sid = HWMSensorItemV30.HWMID_RPM_Fan1A.value for i in range(10): self._show_rpm_v30(i * 2 + sid, cp) self._show_rpm_v30(i * 2 + sid + 1, cp) # IPMI PSU for i in range(2): if show_ipmi_only: print("\033[2;31m================ For PSU when BMC exist ==========================\033[m") show_ipmi_only = False # PSU VIn sid = HWMSensorItemV30.HWMID_PSU1_VOLTIN.value + 11 * i self._show_voltage_v30(sid, cp) # PSU Vout sid = HWMSensorItemV30.HWMID_PSU1_VOLTOUT.value + 11 * i self._show_voltage_v30(sid, cp) # PSU Current In sid = HWMSensorItemV30.HWMID_PSU1_CURRENTIN.value + 11 * i self._show_current_v30(sid, cp) # PSU Current Out sid = HWMSensorItemV30.HWMID_PSU1_CURRENTOUT.value + 11 * i self._show_current_v30(sid, cp) # PSU Power In sid = HWMSensorItemV30.HWMID_PSU1_POWERIN.value + 11 * i self._show_watts_v30(sid, cp) # PSU Power Out sid = HWMSensorItemV30.HWMID_PSU1_POWEROUT.value + 11 * i self._show_watts_v30(sid, cp) # PSU Fan 1 sid = HWMSensorItemV30.HWMID_PSU1_FAN1.value + 11 * i self._show_rpm_v30(sid, cp) # PSU Fan 2 sid = HWMSensorItemV30.HWMID_PSU1_FAN2.value + 11 * i self._show_rpm_v30(sid, cp) # PSU Temp 1 sid = HWMSensorItemV30.HWMID_PSU1_TEMP1.value + 11 * i self._show_temperature_v30(sid, cp) # PSU Temp 2 sid = HWMSensorItemV30.HWMID_PSU1_TEMP2.value + 11 * i self._show_temperature_v30(sid, cp) def _show_temperature_v30(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '3.0.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() dw_lo_critical = c_int32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg, sizeof(str_msg)) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp, sizeof(str_disp)) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name, sizeof(str_id_name)) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(dw_lo_critical), byref(udw_hi_critical)) min_ = dw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) temp = self._atoll(str_msg.value.decode()) / 1000 if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = --N/A-- C, max = {int(max_):7d} C)", end="") if temp > max_: print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = {int(min_):7d} C, max = --N/A-- C)", end="") if temp < min_: print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = --N/A-- C, max = --N/A-- C)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {int(temp):7d} C\t" f"(min = {int(min_):7d} C, max = {int(max_):7d} C)", end="") if temp < min_ or temp > max_: print(f" {ALARM}", end="") print() def _show_rpm_v30(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '3.0.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() dw_lo_critical = c_int32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg, sizeof(str_msg)) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp, sizeof(str_disp)) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name, sizeof(str_id_name)) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(dw_lo_critical), byref(udw_hi_critical)) min_ = dw_lo_critical.value max_ = udw_hi_critical.value else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) rpm = self._atoll(str_msg.value.decode()) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = --N/A-- rpm, max = {int(max_):5d} rpm)", end="") if rpm > max_: print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = {int(min_):5d} rpm, max = --N/A-- rpm)", end="") if rpm < min_: print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = --N/A-- rpm, max = --N/A-- rpm)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {int(rpm):5d} rpm\t" f"(min = {int(min_):5d} rpm, max = {int(max_):5d} rpm)", end="") if rpm < min_ or rpm > max_: print(f" {ALARM}", end="") print() def _show_voltage_v30(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '3.0.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() dw_lo_critical = c_int32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg, sizeof(str_msg)) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp, sizeof(str_disp)) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name, sizeof(str_id_name)) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(dw_lo_critical), byref(udw_hi_critical)) min_ = dw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) volt = self._atoll(str_msg.value.decode()) / 1000 round_up_buffer = int(volt * 1000) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = --N/A-- V, max = {max_:7.3f} V)", end="") if round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = {min_:7.3f} V, max = --N/A-- V)", end="") if round_up_buffer < int(min_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = --N/A-- V, max = --N/A-- V)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} V\t" f"(min = {min_:7.3f} V, max = {max_:7.3f} V)", end="") if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") print() def _show_current_v30(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '3.0.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() dw_lo_critical = c_int32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg, sizeof(str_msg)) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp, sizeof(str_disp)) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name, sizeof(str_id_name)) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(dw_lo_critical), byref(udw_hi_critical)) min_ = dw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) current = self._atoll(str_msg.value.decode()) / 1000 round_up_buffer = int(current * 1000) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = --N/A-- A, max = {max_:7.3f} A)", end="") if round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = {min_:7.3f} A, max = --N/A-- A)", end="") if round_up_buffer < int(min_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = --N/A-- A, max = --N/A-- A)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} A\t" f"(min = {min_:7.3f} A, max = {max_:7.3f} A)", end="") if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") print() def _show_watts_v30(self, sid: int, cp: ConfigParser) -> None: """ For PSP version == '3.0.X'. """ str_msg = create_string_buffer(30) str_disp = create_string_buffer(30) str_id_name = create_string_buffer(30) stu_sensor_info = IPMISensorInfo() udw_hi_critical = c_uint32() dw_lo_critical = c_int32() f_flag_value = 0 memset(str_msg, 0, 30) with PSP() as psp: if psp.lib.LMB_HWM_GetSensorReport(sid, str_msg, sizeof(str_msg)) != ERR_NotSupport: psp.lib.LMB_HWM_GetSensorDisplay(sid, str_disp, sizeof(str_disp)) psp.lib.LMB_HWM_GetSensorName(sid, str_id_name, sizeof(str_id_name)) min_ = self._str_replace(cp.get(str_id_name.value.decode(), "min", fallback="999999")) if min_ == 999999: # hwm.conf not setting, read from SDK. if self._dw_sensor_type.value == HWM_TYPE_IPMI: i_ret = psp.lib.LMB_IPMI_InfoByName(str_disp, byref(stu_sensor_info)) if i_ret == ERR_Success: min_ = stu_sensor_info.f_lo_critical max_ = stu_sensor_info.f_hi_critical else: min_ = max_ = 0.0 else: # read from hwm_table.h psp.lib.LMB_HWM_GetSensorCritical(sid, byref(dw_lo_critical), byref(udw_hi_critical)) min_ = dw_lo_critical.value / 1000 max_ = udw_hi_critical.value / 1000 else: max_ = self._str_replace(cp.get(str_id_name.value.decode(), "max", fallback="999999")) if min_ in (99999, 999999): f_flag_value |= 0x01 if max_ in (99999, 999999): f_flag_value |= 0x02 space_len = self._calc_space_string(str_disp.value.decode()) watts = self._atoll(str_msg.value.decode()) / 1000 round_up_buffer = int(watts * 1000) if f_flag_value == 0x01: # min_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = --N/A-- W, max = {max_:7.3f} W)", end="") if round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x02: # max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = {min_:7.3f} W, max = --N/A-- W)", end="") if round_up_buffer < int(min_ * 1000): print(f" {ALARM}", end="") elif f_flag_value == 0x03: # min_ = N/A and max_ = N/A print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = --N/A-- W, max = --N/A-- W)", end="") else: print(f"{str_disp.value.decode()}{' ' * space_len} = {round_up_buffer * 0.001:7.3f} W\t" f"(min = {min_:7.3f} W, max = {max_:7.3f} W)", end="") if round_up_buffer < int(min_ * 1000) or round_up_buffer > int(max_ * 1000): print(f" {ALARM}", end="") print() @classmethod def _str_replace(cls, s: str) -> float: """Replace str to float from `hwm.conf`.""" result = 1.0 for element in s.split("*"): result *= float(element.strip()) return result @classmethod def _atoll(cls, s: str) -> int: pattern = r"[\s]*[+-]?[\d]+" is_matched = match(pattern, s) if is_matched: result = int(is_matched.group(0)) if result > 2 ** 31 - 1: result = 2 ** 31 - 1 if result < -2 ** 31: result = -2 ** 31 else: result = 0 return result @classmethod def _calc_space_string(cls, s: str) -> int: max_len = 16 if len(s) <= max_len: return max_len - len(s) else: return 0