From 403747aa5ed1e129d718be33aebf7ae8cb65aeaa Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Thu, 22 Oct 2020 01:22:36 +0800 Subject: [PATCH] [sonic-platform-common] Add new platform API for SONiC Physical MIB Extension feature (#134) Why I did this? In order to implement physical entity mib object entPhysicalParentRelPos, entPhysicalContainedIn and entPhysicalIsFRU, new platform API is required to collect information from each vendor. What I did? 1. Add DeviceBase.is_replaceable and DeviceBase.get_position_in_parent 2. Add PsuBase.get_num_thermals, PsuBase.get_all_thermals, PsuBase.get_thermal 3. Add SfpBase.get_num_thermals, SfpBase.get_all_thermals, SfpBase.get_thermal --- sonic_platform_base/device_base.py | 17 ++++++++++ sonic_platform_base/psu_base.py | 51 +++++++++++++++++++++++++++++ sonic_platform_base/sfp_base.py | 52 ++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/sonic_platform_base/device_base.py b/sonic_platform_base/device_base.py index 73511d3118f7..3116f2471f40 100644 --- a/sonic_platform_base/device_base.py +++ b/sonic_platform_base/device_base.py @@ -56,3 +56,20 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ raise NotImplementedError + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + raise NotImplementedError + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + raise NotImplementedError diff --git a/sonic_platform_base/psu_base.py b/sonic_platform_base/psu_base.py index c59dae7619bd..69a5fd214ac8 100644 --- a/sonic_platform_base/psu_base.py +++ b/sonic_platform_base/psu_base.py @@ -25,9 +25,20 @@ class PsuBase(device_base.DeviceBase): # available on the PSU _fan_list = None + # List of ThermalBase-derived objects representing all thermals + # available on the PSU. Put a class level _thermal_list here to + # avoid an exception when call get_num_thermals, get_all_thermals + # and get_thermal if vendor does not call PsuBase.__init__ in concrete + # PSU class + _thermal_list = [] + def __init__(self): self._fan_list = [] + # List of ThermalBase-derived objects representing all thermals + # available on the PSU + self._thermal_list = [] + def get_num_fans(self): """ Retrieves the number of fan modules available on this PSU @@ -69,6 +80,46 @@ def get_fan(self, index): return fan + def get_num_thermals(self): + """ + Retrieves the number of thermals available on this PSU + + Returns: + An integer, the number of thermals available on this PSU + """ + return len(self._thermal_list) + + def get_all_thermals(self): + """ + Retrieves all thermals available on this PSU + + Returns: + A list of objects derived from ThermalBase representing all thermals + available on this PSU + """ + return self._thermal_list + + def get_thermal(self, index): + """ + Retrieves thermal unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the thermal to + retrieve + + Returns: + An object dervied from ThermalBase representing the specified thermal + """ + thermal = None + + try: + thermal = self._thermal_list[index] + except IndexError: + sys.stderr.write("THERMAL index {} out of range (0-{})\n".format( + index, len(self._thermal_list)-1)) + + return thermal + def get_voltage(self): """ Retrieves current PSU voltage output diff --git a/sonic_platform_base/sfp_base.py b/sonic_platform_base/sfp_base.py index ae95deee4d2e..51209409dadd 100644 --- a/sonic_platform_base/sfp_base.py +++ b/sonic_platform_base/sfp_base.py @@ -16,6 +16,58 @@ class SfpBase(device_base.DeviceBase): # Device type definition. Note, this is a constant. DEVICE_TYPE = "sfp" + # List of ThermalBase-derived objects representing all thermals + # available on the SFP. Put a class level _thermal_list here to + # avoid an exception when call get_num_thermals, get_all_thermals + # and get_thermal if vendor does not call SfpBase.__init__ in concrete + # SFP class + _thermal_list = [] + + def __init__(self): + # List of ThermalBase-derived objects representing all thermals + # available on the SFP + self._thermal_list = [] + + def get_num_thermals(self): + """ + Retrieves the number of thermals available on this SFP + + Returns: + An integer, the number of thermals available on this SFP + """ + return len(self._thermal_list) + + def get_all_thermals(self): + """ + Retrieves all thermals available on this SFP + + Returns: + A list of objects derived from ThermalBase representing all thermals + available on this SFP + """ + return self._thermal_list + + def get_thermal(self, index): + """ + Retrieves thermal unit represented by (0-based) index + + Args: + index: An integer, the index (0-based) of the thermal to + retrieve + + Returns: + An object derived from ThermalBase representing the specified thermal + """ + thermal = None + + try: + thermal = self._thermal_list[index] + except IndexError: + sys.stderr.write("THERMAL index {} out of range (0-{})\n".format( + index, len(self._thermal_list)-1)) + + return thermal + def get_transceiver_info(self): """ Retrieves transceiver info of this SFP