This change introduces PDDF which is described here: https://github.com/Azure/SONiC/pull/536 Most of the platform bring up effort goes in developing the platform device drivers, SONiC platform APIs and validating them. Typically each platform vendor writes their own drivers and platform APIs which is very tailor made to that platform. This involves writing code, building, installing it on the target platform devices and testing. Many of the details of the platform are hard coded into these drivers, from the HW spec. They go through this cycle repetitively till everything works fine, and is validated before upstreaming the code. PDDF aims to make this platform driver and platform APIs development process much simpler by providing a data driven development framework. This is enabled by: JSON descriptor files for platform data Generic data-driven drivers for various devices Generic SONiC platform APIs Vendor specific extensions for customisation and extensibility Signed-off-by: Fuzail Khan <fuzail.khan@broadcom.com>
273 lines
6.8 KiB
Python
Executable File
273 lines
6.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# Sample pddf_psuutil file
|
|
#
|
|
# All the supported PSU SysFS aattributes are
|
|
#- psu_present
|
|
#- psu_model_name
|
|
#- psu_power_good
|
|
#- psu_mfr_id
|
|
#- psu_serial_num
|
|
#- psu_fan_dir
|
|
#- psu_v_out
|
|
#- psu_i_out
|
|
#- psu_p_out
|
|
#- psu_fan1_speed_rpm
|
|
#
|
|
|
|
import os.path
|
|
import sys
|
|
sys.path.append('/usr/share/sonic/platform/plugins')
|
|
import pddfparse
|
|
import json
|
|
|
|
try:
|
|
from sonic_psu.psu_base import PsuBase
|
|
except ImportError as e:
|
|
raise ImportError (str(e) + "- required module not found")
|
|
|
|
|
|
class PsuUtil(PsuBase):
|
|
"""PDDF generic PSU util class"""
|
|
|
|
def __init__(self):
|
|
PsuBase.__init__(self)
|
|
global pddf_obj
|
|
global plugin_data
|
|
with open(os.path.join(os.path.dirname(os.path.realpath(__file__)) + '/../pddf/pd-plugin.json')) as pd:
|
|
plugin_data = json.load(pd)
|
|
|
|
pddf_obj = pddfparse.PddfParse()
|
|
self.platform = pddf_obj.get_platform()
|
|
|
|
def get_num_psus(self):
|
|
return int(self.platform['num_psus'])
|
|
|
|
def get_psu_status(self, index):
|
|
if index is None:
|
|
return False
|
|
|
|
device = "PSU" + "%d"%index
|
|
output = pddf_obj.get_attr_name_output(device, "psu_power_good")
|
|
if not output:
|
|
return False
|
|
|
|
mode = output['mode']
|
|
val = output['status']
|
|
|
|
val = val.rstrip()
|
|
vmap = plugin_data['PSU']['psu_power_good'][mode]['valmap']
|
|
|
|
if val in vmap:
|
|
return vmap[val]
|
|
else:
|
|
return False
|
|
|
|
def get_psu_presence(self, index):
|
|
if index is None:
|
|
return False
|
|
|
|
status = 0
|
|
device = "PSU" + "%d"%index
|
|
output = pddf_obj.get_attr_name_output(device, "psu_present")
|
|
if not output:
|
|
return False
|
|
|
|
mode = output['mode']
|
|
status = output['status']
|
|
|
|
vmap = plugin_data['PSU']['psu_present'][mode]['valmap']
|
|
|
|
if status.rstrip('\n') in vmap:
|
|
return vmap[status.rstrip('\n')]
|
|
else:
|
|
return False
|
|
|
|
def get_powergood_status(self, idx):
|
|
if idx is None:
|
|
return False
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return False
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_power_good")
|
|
if not output:
|
|
return False
|
|
|
|
mode = output['mode']
|
|
status = output ['status']
|
|
|
|
vmap = plugin_data['PSU']['psu_power_good'][mode]['valmap']
|
|
|
|
if status.rstrip('\n') in vmap:
|
|
return vmap[status.rstrip('\n')]
|
|
else:
|
|
return False
|
|
|
|
def get_model(self, idx):
|
|
if idx is None:
|
|
return None
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return None
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_model_name")
|
|
if not output:
|
|
return None
|
|
|
|
model = output['status']
|
|
|
|
# strip_non_ascii
|
|
stripped = (c for c in model if 0 < ord(c) < 127)
|
|
model = ''.join(stripped)
|
|
|
|
return model.rstrip('\n')
|
|
|
|
def get_mfr_id(self, idx):
|
|
if idx is None:
|
|
return None
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return None
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_mfr_id")
|
|
if not output:
|
|
return None
|
|
|
|
mfr = output['status']
|
|
|
|
return mfr.rstrip('\n')
|
|
|
|
def get_serial(self, idx):
|
|
if idx is None:
|
|
return None
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return None
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_serial_num")
|
|
if not output:
|
|
return None
|
|
|
|
serial = output['status']
|
|
|
|
return serial.rstrip('\n')
|
|
|
|
def get_direction(self, idx):
|
|
if idx is None:
|
|
return None
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return None
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_fan_dir")
|
|
if not output:
|
|
return None
|
|
|
|
mode = output['mode']
|
|
direction = output['status'].rstrip('\n')
|
|
|
|
vmap = plugin_data['PSU']['psu_fan_dir'][mode]['valmap']
|
|
if direction in vmap:
|
|
airflow_dir_real = vmap[direction]
|
|
else:
|
|
airflow_dir_real = direction
|
|
|
|
return airflow_dir_real
|
|
|
|
def get_output_voltage(self, idx):
|
|
if idx is None:
|
|
return 0.0
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return 0.0
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_v_out")
|
|
if not output:
|
|
return 0.0
|
|
|
|
v_out = output['status']
|
|
|
|
# value returned by the psu driver is in mV
|
|
return float(v_out)/1000
|
|
|
|
def get_output_current(self, idx):
|
|
if idx is None:
|
|
return 0.0
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return 0.0
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_i_out")
|
|
if not output:
|
|
return 0.0
|
|
|
|
i_out = output['status']
|
|
|
|
# current in mA
|
|
return float(i_out)/1000
|
|
|
|
def get_output_power(self, idx):
|
|
if idx is None:
|
|
return 0.0
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return 0.0
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
output = pddf_obj.get_attr_name_output(device, "psu_p_out")
|
|
if not output:
|
|
return 0.0
|
|
|
|
p_out = output['status']
|
|
|
|
# power is returned in micro watts
|
|
return float(p_out)/1000000
|
|
|
|
def get_fan_rpm(self, idx, fan_idx):
|
|
if idx is None or fan_idx is None:
|
|
return 0
|
|
|
|
if idx<1 or idx>self.platform['num_psus']:
|
|
print "Invalid index %d\n"%idx
|
|
return 0
|
|
|
|
|
|
device = "PSU"+"%d"%(idx)
|
|
num_fans = pddf_obj.get_num_psu_fans(device)
|
|
|
|
if fan_idx<1 or fan_idx>num_fans:
|
|
print "Invalid PSU-fan index %d\n"%fan_idx
|
|
return 0
|
|
|
|
output = pddf_obj.get_attr_name_output(device, "psu_fan"+str(fan_idx)+"_speed_rpm")
|
|
if not output:
|
|
return 0
|
|
|
|
#mode = output['mode']
|
|
output['status'] = output['status'].rstrip()
|
|
if output['status'].isalpha():
|
|
return 0
|
|
else:
|
|
speed = int(output['status'])
|
|
|
|
return speed
|
|
|
|
def dump_sysfs(self):
|
|
return pddf_obj.cli_dump_dsysfs('psu')
|