platform/broadcom/sonic-platform-modules-tencent/common/lib/plat_hal/psu.py (529 lines of code) (raw):
#!/usr/bin/env python3
#######################################################
#
# psu.py
# Python implementation of the Class psu
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
from eepromutil.fru import ipmifru
from plat_hal.sensor import sensor
class psu(devicebase):
__pmbus = None
__e2loc = None
__present = None
__productManufacturer = None # : ARTESYN
__productName = None # : CRPS550W
__productPartModelName = None # : CSU550AP-3-300
__productVersion = None # : AB
__productSerialNumber = None # : M623UZ00JYABL
__AirFlow = None # 'N/A'
__AirFlowconifg = None
__psu_display_name = None # 'N/A'
__psu_display_name_conifg = None
__psu_not_present_pwm = None
__InputStatus_config = None
__OutputStatus_config = None
__FanSpeed_config = None
__Temperature_config = None
__InputStatus = None
__OutputStatus = None
__FanSpeed = None
__Temperature = None
__FanSpeedMin = None
__FanSpeedMax = None
__FanSpeedTolerance = None
__InputsVoltage_config = None
__InputsCurrent_config = None
__InputsPower_config = None
__OutputsVoltage_config = None
__OutputsCurrent_config = None
__OutputsPower_config = None
__InputsVoltage = {}
__InputsCurrent = None
__InputsPower = None
__OutputsVoltage = None
__OutputsCurrent = None
__OutputsPower = None
__InputsType_config = None
__InputsType = None
__psu_sn_config = None
__psu_hw_config = None
__psu_pn_config = None
__psu_vendor_config = None
__TempStatus_config = None
__FanStatus_config = None
__TempStatus = None
__FanStatus = None
def __init__(self, conf=None):
self.pmbus = conf.get("pmbusloc", None)
self.e2loc = conf.get("e2loc", None)
self.__presentconfig = conf.get("present", None)
self.name = conf.get("name", None)
self.AirFlowconifg = conf.get("airflow", None)
self.psu_display_name_conifg = conf.get("psu_display_name", None)
self.psu_not_present_pwm = conf.get("psu_not_present_pwm", 100)
self.Temperature_config = conf.get("Temperature", None)
self.Temperature = sensor(self.Temperature_config)
self.FanSpeedTolerance = conf.get('psu_fan_tolerance', 30)
self.FanSpeed_config = conf.get("FanSpeed", None)
self.FanSpeed = sensor(self.FanSpeed_config)
self.__InputsVoltage_config = conf.get("InputsVoltage", None)
self.generate_psu_input_vol(self.__InputsVoltage_config)
self.__InputsCurrent_config = conf.get("InputsCurrent", None)
self.InputsCurrent = sensor(self.__InputsCurrent_config)
self.__InputsPower_config = conf.get("InputsPower", None)
self.InputsPower = sensor(self.__InputsPower_config)
self.__OutputsVoltage_config = conf.get("OutputsVoltage", None)
self.OutputsVoltage = sensor(self.__OutputsVoltage_config)
self.__OutputsCurrent_config = conf.get("OutputsCurrent", None)
self.OutputsCurrent = sensor(self.__OutputsCurrent_config)
self.__OutputsPower_config = conf.get("OutputsPower", None)
self.OutputsPower = sensor(self.__OutputsPower_config)
self.__InputStatus_config = conf.get("InputsStatus", None)
self.__OutputStatus_config = conf.get("OutputsStatus", None)
self.__InputsType_config = conf.get('InputsType', None)
self.__psu_sn_config = conf.get('psu_sn', None)
self.__psu_hw_config = conf.get('psu_hw', None)
self.__psu_pn_config = conf.get('psu_pn', None)
self.__psu_vendor_config = conf.get('psu_vendor', None)
self.__TempStatus_config = conf.get("TempStatus", None)
self.__FanStatus_config = conf.get("FanStatus", None)
def generate_psu_input_vol(self, config):
tmp = {}
for (key, item) in config.items():
tmp.setdefault(key, sensor(item))
self.__InputsVoltage = tmp
def get_psu_sensor_by_name(self, psutype):
return self.__InputsVoltage.get(psutype) or self.__InputsVoltage.get('other')
@property
def InputsVoltage(self):
psutype = self.InputsType
input_sensor = self.get_psu_sensor_by_name(psutype)
if input_sensor is None:
return None
else:
return input_sensor
@InputsVoltage.setter
def InputsVoltage(self, val):
self.__InputsVoltage = val
@property
def InputsCurrent(self):
return self.__InputsCurrent
@InputsCurrent.setter
def InputsCurrent(self, val):
self.__InputsCurrent = val
@property
def InputsPower(self):
return self.__InputsPower
@InputsPower.setter
def InputsPower(self, val):
self.__InputsPower = val
@property
def OutputsVoltage(self):
return self.__OutputsVoltage
@OutputsVoltage.setter
def OutputsVoltage(self, val):
self.__OutputsVoltage = val
@property
def OutputsCurrent(self):
return self.__OutputsCurrent
@OutputsCurrent.setter
def OutputsCurrent(self, val):
self.__OutputsCurrent = val
@property
def OutputsPower(self):
return self.__OutputsPower
@OutputsPower.setter
def OutputsPower(self, val):
self.__OutputsPower = val
@property
def InputStatus(self):
if self.present == False:
self.__InputStatus = False
else:
ret, val = self.get_value(self.__InputStatus_config)
mask = self.__InputStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__InputStatus = True
else:
self.__InputStatus = False
else:
self.__InputStatus = False
return self.__InputStatus
@InputStatus.setter
def InputStatus(self, val):
self.__InputStatus = val
@property
def TempStatus(self):
if self.__TempStatus_config is None:
return None
if self.present == False:
self.__TempStatus = False
else:
ret, val = self.get_value(self.__TempStatus_config)
mask = self.__TempStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__TempStatus = True
else:
self.__TempStatus = False
else:
self.__TempStatus = False
return self.__TempStatus
@TempStatus.setter
def TempStatus(self, val):
self.__TempStatus = val
@property
def FanStatus(self):
if self.__FanStatus_config is None:
return None
if self.present == False:
self.__FanStatus = False
else:
ret, val = self.get_value(self.__FanStatus_config)
mask = self.__FanStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__FanStatus = True
else:
self.__FanStatus = False
else:
self.__FanStatus = False
return self.__FanStatus
@FanStatus.setter
def FanStatus(self, val):
self.__FanStatus = val
@property
def InputsType(self):
psutypedecode = self.__InputsType_config.get('psutypedecode', None)
if self.present == False:
self.__InputsType = psutypedecode.get(0x00)
else:
ret, val = self.get_value(self.__InputsType_config)
self.__InputsType = self.__InputsType_config.get(val, None)
if self.__InputsType is not None:
return self.__InputsType
if ret == True and val in psutypedecode:
self.__InputsType = psutypedecode.get(val)
else:
self.__InputsType = psutypedecode.get(0x00)
return self.__InputsType
@InputsType.setter
def InputsType(self, val):
self.__InputsType = val
@property
def FanSpeedMin(self):
return self.__FanSpeedMin
@FanSpeedMin.setter
def FanSpeedMin(self, val):
self.__FanSpeedMin = val
@property
def FanSpeedMax(self):
return self.__FanSpeedMax
@FanSpeedMax.setter
def FanSpeedMax(self, val):
self.__FanSpeedMax = val
@property
def FanSpeedTolerance(self):
return self.__FanSpeedTolerance
@FanSpeedTolerance.setter
def FanSpeedTolerance(self, val):
self.__FanSpeedTolerance = val
@property
def OutputStatus(self):
if self.present == False:
self.__OutputStatus = False
else:
ret, val = self.get_value(self.__OutputStatus_config)
mask = self.__OutputStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__OutputStatus = True
else:
self.__OutputStatus = False
else:
self.__OutputStatus = False
return self.__OutputStatus
@OutputStatus.setter
def OutputStatus(self, val):
self.__OutputStatus = val
@property
def FanSpeed(self):
return self.__FanSpeed
@FanSpeed.setter
def FanSpeed(self, val):
self.__FanSpeed = val
@property
def Temperature(self):
return self.__Temperature
@Temperature.setter
def Temperature(self, val):
self.__Temperature = val
@property
def Temperature_config(self):
return self.__Temperature_config
@Temperature_config.setter
def Temperature_config(self, val):
self.__Temperature_config = val
@property
def AirFlowconifg(self):
return self.__AirFlowconifg
@AirFlowconifg.setter
def AirFlowconifg(self, val):
self.__AirFlowconifg = val
@property
def psu_display_name_conifg(self):
return self.__psu_display_name_conifg
@psu_display_name_conifg.setter
def psu_display_name_conifg(self, val):
self.__psu_display_name_conifg = val
@property
def pmbus(self):
return self.__pmbus
@pmbus.setter
def pmbus(self, val):
self.__pmbus = val
@property
def e2loc(self):
return self.__e2loc
@e2loc.setter
def e2loc(self, val):
self.__e2loc = val
@property
def AirFlow(self):
return self.__AirFlow
@AirFlow.setter
def AirFlow(self, val):
self.__AirFlow = val
@property
def psu_display_name(self):
return self.__psu_display_name
@psu_display_name.setter
def psu_display_name(self, val):
self.__psu_display_name = val
@property
def psu_not_present_pwm(self):
return self.__psu_not_present_pwm
@psu_not_present_pwm.setter
def psu_not_present_pwm(self, val):
self.__psu_not_present_pwm = val
@property
def present(self):
ret, val = self.get_value(self.__presentconfig)
if ret is False or val is None:
return False
mask = self.__presentconfig.get("mask")
if isinstance(val, str):
value = int(val, 16)
else:
value = val
ttt = value & mask
okval = self.__presentconfig.get("okval", 0)
if ttt == okval:
return True
else:
return False
@present.setter
def present(self, val):
self.__present = val
@property
def productManufacturer(self):
return self.__productManufacturer
@productManufacturer.setter
def productManufacturer(self, val):
self.__productManufacturer = val
@property
def productName(self):
return self.__productName
@productName.setter
def productName(self, val):
self.__productName = val
@property
def productPartModelName(self):
return self.__productPartModelName
@productPartModelName.setter
def productPartModelName(self, val):
self.__productPartModelName = val
@property
def productVersion(self):
return self.__productVersion
@productVersion.setter
def productVersion(self, val):
self.__productVersion = val
@property
def productSerialNumber(self):
return self.__productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, val):
self.__productSerialNumber = val
@property
def psu_sn_sysfs(self):
if self.__psu_sn_config is None:
return None
ret, val = self.get_value(self.__psu_sn_config)
if ret is False or val is None:
return None
return val
@property
def psu_hw_sysfs(self):
if self.__psu_hw_config is None:
return None
ret, val = self.get_value(self.__psu_hw_config)
if ret is False or val is None:
return None
return val
@property
def psu_pn_sysfs(self):
if self.__psu_pn_config is None:
return None
ret, val = self.get_value(self.__psu_pn_config)
if ret is False or val is None:
return None
return val
@property
def psu_vendor_sysfs(self):
if self.__psu_vendor_config is None:
return None
ret, val = self.get_value(self.__psu_vendor_config)
if ret is False or val is None:
return None
return val
def __str__(self):
formatstr = \
"name : %s \n" \
"productManufacturer : %s \n" \
"productName : %s \n" \
"productPartModelName: %s \n" \
"productVersion : %s \n" \
"productSerialNumber : %s \n" \
"AirFlow : %s \n" \
tmpstr = formatstr % (self.name, self.productManufacturer,
self.productName, self.productPartModelName,
self.productVersion, self.productSerialNumber, self.AirFlow)
return tmpstr
def get_fan_speed_pwm(self):
if self.present == False:
return self.psu_not_present_pwm
selfconfig = {}
selfconfig['bus'] = self.pmbus['bus']
selfconfig['addr'] = self.pmbus['addr']
selfconfig['way'] = 'i2cword'
selfconfig['offset'] = 0x3b
ret, val = self.get_value(selfconfig)
if ret == True:
return val
else:
return None
def set_fan_speed_pwm(self, pwm):
'''
pmbus
if duty:
i2cset -f -y 0x3b 0x0064 wp
'''
if self.present == False:
return None
if 0 <= pwm <= 100:
'''enable duty first '''
selfconfig = {}
selfconfig['bus'] = self.pmbus['bus']
selfconfig['addr'] = self.pmbus['addr']
selfconfig['way'] = 'i2cpec'
selfconfig['offset'] = 0x3a
self.set_value(selfconfig, 0x80)
selfconfig['way'] = 'i2cwordpec'
selfconfig['offset'] = 0x3b
bytetmp = pwm
ret, val = self.set_value(selfconfig, int(bytetmp))
if ret == True:
return True
else:
return None
else:
raise Exception("pwm not in range [0,100]")
def get_fru_info_by_sysfs(self):
try:
psu_sn = self.psu_sn_sysfs
psu_hw = self.psu_hw_sysfs
psu_pn = self.psu_pn_sysfs
psu_vendor = self.psu_vendor_sysfs
if psu_sn is None or psu_hw is None or psu_pn is None or psu_vendor is None:
return False
self.productSerialNumber = psu_sn.strip().replace(chr(0), "")
self.productVersion = psu_hw.strip()
self.productPartModelName = psu_pn.strip()
self.productManufacturer = psu_vendor.strip().replace(chr(0), "")
except Exception as e:
self.productSerialNumber = None
self.productVersion = None
self.productPartModelName = None
self.productManufacturer = None
return False
return True
def get_fru_info_by_decode(self):
try:
eeprom = self.get_eeprom_info(self.e2loc)
if eeprom is None:
raise Exception("%s:value is none" % self.name)
fru = ipmifru()
if isinstance(eeprom, bytes):
eeprom = self.byteTostr(eeprom)
fru.decodeBin(eeprom)
if fru.productInfoArea is not None:
self.productManufacturer = fru.productInfoArea.productManufacturer.strip()
self.productName = fru.productInfoArea.productName.strip()
self.productPartModelName = fru.productInfoArea.productPartModelName.strip()
self.productVersion = fru.productInfoArea.productVersion.strip()
self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip().replace(chr(0), "")
except Exception as e:
self.productManufacturer = None
self.productName = None
self.productPartModelName = None
self.productVersion = None
self.productSerialNumber = None
return False
return True
def get_fru_info(self):
try:
if self.present is not True:
raise Exception("%s: not present" % self.name)
if self.get_fru_info_by_sysfs() is True:
return True
return self.get_fru_info_by_decode()
except Exception as e:
self.productManufacturer = None
self.productName = None
self.productPartModelName = None
self.productVersion = None
self.productSerialNumber = None
return False
def get_AirFlow(self):
if self.productPartModelName is None:
ret = self.get_fru_info()
if ret is False:
self.AirFlow = None
return False
if self.AirFlowconifg is None:
self.AirFlow = None
return False
else:
for i in self.AirFlowconifg:
if self.productPartModelName in self.AirFlowconifg[i]:
self.AirFlow = i
return True
self.AirFlow = None
return False
def get_psu_display_name(self):
if self.productPartModelName is None:
ret = self.get_fru_info()
if ret is False:
self.psu_display_name = None
return False
if self.psu_display_name_conifg is None:
self.psu_display_name = self.productPartModelName
return False
else:
for i in self.psu_display_name_conifg:
if self.productPartModelName in self.psu_display_name_conifg[i]:
self.psu_display_name = i
return True
self.psu_display_name = self.productPartModelName
return False