Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.sfp import Sfp
from sonic_platform.psu import Psu
from sonic_platform.fan_drawer import fan_drawer_list_get
from sonic_platform.thermal import thermal_list_get
from eeprom import Eeprom
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
Expand All @@ -26,6 +28,9 @@ def __init__(self):
psu = Psu(i)
self._psu_list.append(psu)

self._fan_drawer_list = fan_drawer_list_get()
self._thermal_list = thermal_list_get()

def get_name(self):
"""
Retrieves the name of the chassis
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
try:
from sonic_platform.platform_thrift_client import thrift_try
from sonic_platform_base.fan_drawer_base import FanDrawerBase
from sonic_platform_base.fan_base import FanBase
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

_MAX_FAN = 10

def _fan_info_get(fan_num, cb, default=None):
def get_data(client):
return client.pltfm_mgr.pltfm_mgr_fan_info_get(fan_num)
fan_info = thrift_try(get_data)
if fan_num == fan_info.fan_num:
return cb(fan_info)
if default is None:
raise LookupError
return default

def _fan_info_get_all():
for fan_num in range(1, _MAX_FAN + 1):
def get_data(client, fan_num=fan_num):
return client.pltfm_mgr.pltfm_mgr_fan_info_get(fan_num)
fan_info = thrift_try(get_data)
if fan_info.fan_num == fan_num:
yield fan_info

# Fan -> FanBase -> DeviceBase
class Fan(FanBase):
def __init__(self, num):
self.__num = num

# FanBase interface methods:
# returns speed in percents
def get_speed(self):
def cb(info): return info.percent
return _fan_info_get(self.__num, cb, 0)

def set_speed(self, percent):
def set_fan_speed(client):
return client.pltfm_mgr.pltfm_mgr_fan_speed_set(fan, percent)
return thrift_try(set_fan_speed)

# DeviceBase interface methods:
def get_name(self):
return f"counter-rotating-fan-{self.__num}"

def get_presence(self):
return _fan_info_get(self.__num, lambda _: True, False)

def get_position_in_parent(self):
return self.__num

def is_replaceable(self):
return True

def get_status(self):
return True

# FanDrawer -> FanDrawerBase -> DeviceBase
class FanDrawer(FanDrawerBase):
def __init__(self):
# For now we return only present fans
self._fan_list = [Fan(i.fan_num) for i in _fan_info_get_all()]

# DeviceBase interface methods:
def get_name(self):
return 'fantray'

def get_presence(self):
return True

def get_status(self):
return True

def fan_drawer_list_get():
return [FanDrawer()]
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
try:
import subprocess

from sonic_platform.bfn_extensions.platform_sensors import platform_sensors_get
from sonic_platform_base.thermal_base import ThermalBase
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

'''
data argument is in "sensors -A -u" format, example:
coretemp-isa-0000
Package id 0:
temp1_input: 37.000
temp1_max: 82.000
temp1_crit: 104.000
temp1_crit_alarm: 0.000
Core 0:
temp2_input: 37.000
...
'''
def _sensors_chip_parsed(data: str):
def kv(line):
k, v, *_ = [t.strip(': ') for t in line.split(':') if t] + ['']
return k, v

chip, *data = data.strip().split('\n')
chip = chip.strip(': ')

sensors = []
for line in data:
if not line.startswith(' '):
sensor_label = line.strip(': ')
sensors.append((sensor_label, {}))
continue

if len(sensors) == 0:
raise RuntimeError(f'invalid data to parse: {data}')

attr, value = kv(line)
sensor_label, sensor_data = sensors[-1]
sensor_data.update({attr: value})

return chip, dict(sensors)

'''
Example of returned dict:
{
'coretemp-isa-0000': {
'Core 1': { "temp1_input": 40, ... },
'Core 2': { ... }
}
}
'''
def _sensors_get() -> dict:
data = platform_sensors_get(['-A', '-u']) or ''
data += subprocess.check_output("/usr/bin/sensors -A -u",
shell=True, text=True)
data = data.split('\n\n')
data = [_sensors_chip_parsed(chip_data) for chip_data in data if chip_data]
data = dict(data)
return data

def _value_get(d: dict, key_prefix, key_suffix=''):
for k, v in d.items():
if k.startswith(key_prefix) and k.endswith(key_suffix):
return v
return None

# Thermal -> ThermalBase -> DeviceBase
class Thermal(ThermalBase):
def __init__(self, chip, label):
self.__chip = chip
self.__label = label
self.__name = f"{chip}:{label}".lower().replace(' ', '-')

def __get(self, attr_prefix, attr_suffix):
sensor_data = _sensors_get().get(self.__chip, {}).get(self.__label, {})
value = _value_get(sensor_data, attr_prefix, attr_suffix)
if value is not None: return value
raise NotImplementedError

# ThermalBase interface methods:
def get_temperature(self) -> float:
return float(self.__get('temp', 'input'))

def get_high_threshold(self) -> float:
return float(self.__get('temp', 'max'))

def get_high_critical_threshold(self) -> float:
return float(self.__get('temp', 'crit'))

# DeviceBase interface methods:
def get_name(self):
return self.__name

def get_presence(self):
return True

def get_status(self):
return True

def thermal_list_get():
l = []
for chip, chip_data in _sensors_get().items():
for sensor, sensor_data in chip_data.items():
# add only temperature sensors
if _value_get(sensor_data, "temp") is not None:
l.append(Thermal(chip, sensor))
return l