[device/celestica]: Fix failed test cases of DX010 platform APIs (#6564)
1. Add device/celestica/x86_64-cel_seastone-r0/platform.json 2. Update functions to support python3.7 3. Add more functions follow latest sonic_platform_base 4. Fix the bug Co-authored-by: 119064273 <2276096708@qq.com> Co-authored-by: Eric Zhu <erzhu@celestica.com> Co-authored-by: doni@celestica.com <doni@celestica.com>
This commit is contained in:
parent
27f4daba54
commit
fbcb9403e8
@ -1,4 +1,246 @@
|
|||||||
{
|
{
|
||||||
|
"chassis": {
|
||||||
|
"name": "Celestica-DX010-C32",
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"name": "CPLD1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CPLD2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CPLD3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CPLD4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BIOS"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-1F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-1R"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-2F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-2R"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-3F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-3R"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-4F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-4R"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-5F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-5R"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fan_drawers": [
|
||||||
|
{
|
||||||
|
"name": "Drawer1",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-1F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-1R"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Drawer2",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-2F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-2R"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Drawer3",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-3F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-3R"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Drawer4",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-4F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-4R"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Drawer5",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "FAN-5F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "FAN-5R"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"psus": [
|
||||||
|
{
|
||||||
|
"name": "PSU-1",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "PSU-1 FAN-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "PSU-2",
|
||||||
|
"fans": [
|
||||||
|
{
|
||||||
|
"name": "PSU-2 FAN-1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thermals": [
|
||||||
|
{
|
||||||
|
"name": "Front-panel temp sensor 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Front-panel temp sensor 2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ASIC temp sensor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rear-panel temp sensor 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rear-panel temp sensor 2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sfps": [
|
||||||
|
{
|
||||||
|
"name": "Ethernet124"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet28"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet36"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet44"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet48"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet52"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet56"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet60"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet68"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet72"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet76"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet80"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet84"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet88"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet92"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet96"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet104"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet108"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet112"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet116"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ethernet120"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"interfaces": {
|
"interfaces": {
|
||||||
"Ethernet0": {
|
"Ethernet0": {
|
||||||
"index": "1,1,1,1",
|
"index": "1,1,1,1",
|
||||||
|
@ -17,7 +17,6 @@ except ImportError as e:
|
|||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
NUM_FAN_TRAY = 5
|
NUM_FAN_TRAY = 5
|
||||||
NUM_FAN = 2
|
|
||||||
NUM_PSU = 2
|
NUM_PSU = 2
|
||||||
NUM_THERMAL = 5
|
NUM_THERMAL = 5
|
||||||
NUM_SFP = 32
|
NUM_SFP = 32
|
||||||
@ -28,6 +27,7 @@ REBOOT_CAUSE_FILE = "reboot-cause.txt"
|
|||||||
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
|
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
|
||||||
GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg"
|
GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg"
|
||||||
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
HOST_CHK_CMD = "docker > /dev/null 2>&1"
|
||||||
|
STATUS_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:stat/brightness"
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -40,12 +40,10 @@ class Chassis(ChassisBase):
|
|||||||
self.__initialize_eeprom()
|
self.__initialize_eeprom()
|
||||||
self.is_host = self._api_helper.is_host()
|
self.is_host = self._api_helper.is_host()
|
||||||
|
|
||||||
if not self.is_host:
|
self.__initialize_fan()
|
||||||
self.__initialize_fan()
|
self.__initialize_psu()
|
||||||
self.__initialize_psu()
|
self.__initialize_thermals()
|
||||||
self.__initialize_thermals()
|
self.__initialize_components()
|
||||||
else:
|
|
||||||
self.__initialize_components()
|
|
||||||
|
|
||||||
def __initialize_sfp(self):
|
def __initialize_sfp(self):
|
||||||
sfputil_helper = SfpUtilHelper()
|
sfputil_helper = SfpUtilHelper()
|
||||||
@ -54,8 +52,7 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
from sonic_platform.sfp import Sfp
|
from sonic_platform.sfp import Sfp
|
||||||
for index in range(0, NUM_SFP):
|
for index in range(0, NUM_SFP):
|
||||||
name_idx = 0 if index+1 == NUM_SFP else index+1
|
sfp = Sfp(index, sfputil_helper.logical[index])
|
||||||
sfp = Sfp(index, sfputil_helper.logical[name_idx])
|
|
||||||
self._sfp_list.append(sfp)
|
self._sfp_list.append(sfp)
|
||||||
self.sfp_module_initialized = True
|
self.sfp_module_initialized = True
|
||||||
|
|
||||||
@ -66,11 +63,11 @@ class Chassis(ChassisBase):
|
|||||||
self._psu_list.append(psu)
|
self._psu_list.append(psu)
|
||||||
|
|
||||||
def __initialize_fan(self):
|
def __initialize_fan(self):
|
||||||
from sonic_platform.fan import Fan
|
from sonic_platform.fan_drawer import FanDrawer
|
||||||
for fant_index in range(0, NUM_FAN_TRAY):
|
for i in range(NUM_FAN_TRAY):
|
||||||
for fan_index in range(0, NUM_FAN):
|
fandrawer = FanDrawer(i)
|
||||||
fan = Fan(fant_index, fan_index)
|
self._fan_drawer_list.append(fandrawer)
|
||||||
self._fan_list.append(fan)
|
self._fan_list.extend(fandrawer._fan_list)
|
||||||
|
|
||||||
def __initialize_thermals(self):
|
def __initialize_thermals(self):
|
||||||
from sonic_platform.thermal import Thermal
|
from sonic_platform.thermal import Thermal
|
||||||
@ -90,7 +87,9 @@ class Chassis(ChassisBase):
|
|||||||
self._component_list.append(component)
|
self._component_list.append(component)
|
||||||
|
|
||||||
def __get_air_flow(self):
|
def __get_air_flow(self):
|
||||||
air_flow_path = '/usr/share/sonic/device/{}/fan_airflow'.format(self._api_helper.platform) if self.is_host else '/usr/share/sonic/platform/fan_airflow'
|
air_flow_path = '/usr/share/sonic/device/{}/fan_airflow'.format(
|
||||||
|
self._api_helper.platform) \
|
||||||
|
if self.is_host else '/usr/share/sonic/platform/fan_airflow'
|
||||||
air_flow = self._api_helper.read_one_line_file(air_flow_path)
|
air_flow = self._api_helper.read_one_line_file(air_flow_path)
|
||||||
return air_flow or 'B2F'
|
return air_flow or 'B2F'
|
||||||
|
|
||||||
@ -155,7 +154,6 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
return prev_reboot_cause
|
return prev_reboot_cause
|
||||||
|
|
||||||
|
|
||||||
def get_change_event(self, timeout=0):
|
def get_change_event(self, timeout=0):
|
||||||
"""
|
"""
|
||||||
Returns a nested dictionary containing all devices which have
|
Returns a nested dictionary containing all devices which have
|
||||||
@ -231,7 +229,7 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# The index will start from 1
|
# The index will start from 1
|
||||||
sfp = self._sfp_list[index-1]
|
sfp = self._sfp_list[index - 1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
|
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
|
||||||
index, len(self._sfp_list)))
|
index, len(self._sfp_list)))
|
||||||
@ -254,6 +252,10 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
return self._watchdog
|
return self._watchdog
|
||||||
|
|
||||||
|
def get_thermal_manager(self):
|
||||||
|
from .thermal_manager import ThermalManager
|
||||||
|
return ThermalManager
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
###################### Device methods ########################
|
###################### Device methods ########################
|
||||||
##############################################################
|
##############################################################
|
||||||
@ -298,6 +300,53 @@ class Chassis(ChassisBase):
|
|||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_thermal_manager(self):
|
def get_position_in_parent(self):
|
||||||
from .thermal_manager import ThermalManager
|
"""
|
||||||
return ThermalManager
|
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
|
||||||
|
"""
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def set_status_led(self, color):
|
||||||
|
"""
|
||||||
|
Sets the state of the PSU status LED
|
||||||
|
Args:
|
||||||
|
color: A string representing the color with which to set the PSU status LED
|
||||||
|
Note: Only support green and off
|
||||||
|
Returns:
|
||||||
|
bool: True if status LED state is set successfully, False if not
|
||||||
|
"""
|
||||||
|
|
||||||
|
set_status_str = {
|
||||||
|
self.STATUS_LED_COLOR_GREEN: '1',
|
||||||
|
self.STATUS_LED_COLOR_OFF: '0'
|
||||||
|
}.get(color, None)
|
||||||
|
|
||||||
|
if not set_status_str:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return self._api_helper.write_txt_file(STATUS_LED_PATH, set_status_str)
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the PSU status LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
status = self._api_helper.read_txt_file(STATUS_LED_PATH)
|
||||||
|
status_str = {
|
||||||
|
'255': self.STATUS_LED_COLOR_GREEN,
|
||||||
|
'0': self.STATUS_LED_COLOR_OFF
|
||||||
|
}.get(status, None)
|
||||||
|
|
||||||
|
return status_str
|
||||||
|
@ -128,3 +128,61 @@ class Component(ComponentBase):
|
|||||||
# install_command = "afulnx_64 %s /p /b /n /x /r" % image_path
|
# install_command = "afulnx_64 %s /p /b /n /x /r" % image_path
|
||||||
|
|
||||||
return self.__run_command(install_command)
|
return self.__run_command(install_command)
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the FAN
|
||||||
|
Returns:
|
||||||
|
bool: True if FAN is present, False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
return 'N/A'
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
return 'N/A'
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if device is operating properly, False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
@ -8,24 +8,22 @@
|
|||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import glob
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
from array import array
|
|
||||||
|
|
||||||
if sys.version_info.major == 3:
|
if sys.version_info.major == 3:
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
else:
|
else:
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
from sonic_platform_base.sonic_eeprom import eeprom_dts
|
|
||||||
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
|
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
|
CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
|
||||||
CACHE_FILE = 'syseeprom_cache'
|
CACHE_FILE = 'syseeprom_cache'
|
||||||
|
NULL = 'N/A'
|
||||||
|
|
||||||
|
|
||||||
class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
||||||
@ -52,7 +50,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
value = match.group(3).rstrip('\0')
|
value = match.group(3).rstrip('\0')
|
||||||
|
|
||||||
_eeprom_info_dict[idx] = value
|
_eeprom_info_dict[idx] = value
|
||||||
except:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
return _eeprom_info_dict
|
return _eeprom_info_dict
|
||||||
|
|
||||||
@ -61,7 +59,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
sys.stdout = StringIO()
|
sys.stdout = StringIO()
|
||||||
try:
|
try:
|
||||||
self.read_eeprom_db()
|
self.read_eeprom_db()
|
||||||
except:
|
except BaseException:
|
||||||
decode_output = sys.stdout.getvalue()
|
decode_output = sys.stdout.getvalue()
|
||||||
sys.stdout = original_stdout
|
sys.stdout = original_stdout
|
||||||
return self.__parse_output(decode_output)
|
return self.__parse_output(decode_output)
|
||||||
@ -73,7 +71,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
if not os.path.exists(CACHE_ROOT):
|
if not os.path.exists(CACHE_ROOT):
|
||||||
try:
|
try:
|
||||||
os.makedirs(CACHE_ROOT)
|
os.makedirs(CACHE_ROOT)
|
||||||
except:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -82,7 +80,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
#
|
#
|
||||||
try:
|
try:
|
||||||
self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE))
|
self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE))
|
||||||
except:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
e = self.read_eeprom()
|
e = self.read_eeprom()
|
||||||
@ -91,7 +89,7 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.update_cache(e)
|
self.update_cache(e)
|
||||||
except:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.decode_eeprom(e)
|
self.decode_eeprom(e)
|
||||||
@ -104,11 +102,40 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
|
|||||||
|
|
||||||
return self.__parse_output(decode_output)
|
return self.__parse_output(decode_output)
|
||||||
|
|
||||||
|
def _valid_tlv(self, eeprom_data):
|
||||||
|
tlvinfo_type_codes_list = [
|
||||||
|
self._TLV_CODE_PRODUCT_NAME,
|
||||||
|
self._TLV_CODE_PART_NUMBER,
|
||||||
|
self._TLV_CODE_SERIAL_NUMBER,
|
||||||
|
self._TLV_CODE_MAC_BASE,
|
||||||
|
self._TLV_CODE_MANUF_DATE,
|
||||||
|
self._TLV_CODE_DEVICE_VERSION,
|
||||||
|
self._TLV_CODE_LABEL_REVISION,
|
||||||
|
self._TLV_CODE_PLATFORM_NAME,
|
||||||
|
self._TLV_CODE_ONIE_VERSION,
|
||||||
|
self._TLV_CODE_MAC_SIZE,
|
||||||
|
self._TLV_CODE_MANUF_NAME,
|
||||||
|
self._TLV_CODE_MANUF_COUNTRY,
|
||||||
|
self._TLV_CODE_VENDOR_NAME,
|
||||||
|
self._TLV_CODE_DIAG_VERSION,
|
||||||
|
self._TLV_CODE_SERVICE_TAG,
|
||||||
|
self._TLV_CODE_VENDOR_EXT,
|
||||||
|
self._TLV_CODE_CRC_32
|
||||||
|
]
|
||||||
|
|
||||||
|
for code in tlvinfo_type_codes_list:
|
||||||
|
code_str = "0x{:X}".format(code)
|
||||||
|
eeprom_data[code_str] = eeprom_data.get(code_str, NULL)
|
||||||
|
return eeprom_data
|
||||||
|
|
||||||
def get_eeprom(self):
|
def get_eeprom(self):
|
||||||
return self._eeprom
|
return self._valid_tlv(self._eeprom)
|
||||||
|
|
||||||
|
def get_pn(self):
|
||||||
|
return self._eeprom.get('0x22', NULL)
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
return self._eeprom.get('0x23', "Undefined.")
|
return self._eeprom.get('0x23', NULL)
|
||||||
|
|
||||||
def get_mac(self):
|
def get_mac(self):
|
||||||
return self._eeprom.get('0x24', "Undefined.")
|
return self._eeprom.get('0x24', NULL)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
import json
|
from __future__ import division
|
||||||
import math
|
import math
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
@ -25,6 +25,7 @@ EMC2305_FAN_TARGET = "fan{}_target"
|
|||||||
EMC2305_FAN_INPUT = "pwm{}"
|
EMC2305_FAN_INPUT = "pwm{}"
|
||||||
FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R",
|
FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R",
|
||||||
"FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R"]
|
"FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R"]
|
||||||
|
FAN_SPEED_TOLERANCE = 10
|
||||||
PSU_FAN_MAX_RPM = 11000
|
PSU_FAN_MAX_RPM = 11000
|
||||||
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
PSU_I2C_MAPPING = {
|
PSU_I2C_MAPPING = {
|
||||||
@ -82,7 +83,7 @@ class Fan(FanBase):
|
|||||||
try:
|
try:
|
||||||
with open(file_path, 'w') as fd:
|
with open(file_path, 'w') as fd:
|
||||||
fd.write(str(value))
|
fd.write(str(value))
|
||||||
except:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -97,7 +98,8 @@ class Fan(FanBase):
|
|||||||
def __get_gpio_base(self):
|
def __get_gpio_base(self):
|
||||||
for r in os.listdir(GPIO_DIR):
|
for r in os.listdir(GPIO_DIR):
|
||||||
label_path = os.path.join(GPIO_DIR, r, "label")
|
label_path = os.path.join(GPIO_DIR, r, "label")
|
||||||
if "gpiochip" in r and GPIO_LABEL in self._api_helper.read_txt_file(label_path):
|
if "gpiochip" in r and GPIO_LABEL in \
|
||||||
|
self._api_helper.read_txt_file(label_path):
|
||||||
return int(r[8:], 10)
|
return int(r[8:], 10)
|
||||||
return 216 # Reserve
|
return 216 # Reserve
|
||||||
|
|
||||||
@ -148,7 +150,6 @@ class Fan(FanBase):
|
|||||||
self.psu_hwmon_path, fan_speed_sysfs_name)
|
self.psu_hwmon_path, fan_speed_sysfs_name)
|
||||||
fan_speed_rpm = self._api_helper.read_txt_file(
|
fan_speed_rpm = self._api_helper.read_txt_file(
|
||||||
fan_speed_sysfs_path) or 0
|
fan_speed_sysfs_path) or 0
|
||||||
fan_speed_raw = float(fan_speed_rpm)/PSU_FAN_MAX_RPM * 100
|
|
||||||
speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM)
|
speed = math.ceil(float(fan_speed_rpm) * 100 / PSU_FAN_MAX_RPM)
|
||||||
elif self.get_presence():
|
elif self.get_presence():
|
||||||
chip = self.emc2305_chip_mapping[self.fan_index]
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
@ -176,7 +177,19 @@ class Fan(FanBase):
|
|||||||
0 : when PWM mode is use
|
0 : when PWM mode is use
|
||||||
pwm : when pwm mode is not use
|
pwm : when pwm mode is not use
|
||||||
"""
|
"""
|
||||||
return 'N/A'
|
target = NULL_VAL
|
||||||
|
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
chip = self.emc2305_chip_mapping[self.fan_index]
|
||||||
|
device = chip['device']
|
||||||
|
fan_index = chip['index_map']
|
||||||
|
sysfs_path = "%s%s/%s" % (
|
||||||
|
EMC2305_PATH, device, EMC2305_FAN_PWM)
|
||||||
|
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
|
||||||
|
pwm = self._api_helper.read_txt_file(sysfs_path)
|
||||||
|
target = round(int(pwm) / 255 * 100.0)
|
||||||
|
|
||||||
|
return target
|
||||||
|
|
||||||
def get_speed_tolerance(self):
|
def get_speed_tolerance(self):
|
||||||
"""
|
"""
|
||||||
@ -185,7 +198,7 @@ class Fan(FanBase):
|
|||||||
An integer, the percentage of variance from target speed which is
|
An integer, the percentage of variance from target speed which is
|
||||||
considered tolerable
|
considered tolerable
|
||||||
"""
|
"""
|
||||||
return 10
|
return FAN_SPEED_TOLERANCE
|
||||||
|
|
||||||
def set_speed(self, speed):
|
def set_speed(self, speed):
|
||||||
"""
|
"""
|
||||||
@ -225,41 +238,67 @@ class Fan(FanBase):
|
|||||||
bool: True if status LED state is set successfully, False if not
|
bool: True if status LED state is set successfully, False if not
|
||||||
"""
|
"""
|
||||||
set_status_led = False
|
set_status_led = False
|
||||||
|
|
||||||
|
s1_gpio = self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red']
|
||||||
|
s2_gpio = self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green']
|
||||||
|
|
||||||
if not self.is_psu_fan:
|
if not self.is_psu_fan:
|
||||||
s1, s2 = False, False
|
|
||||||
try:
|
try:
|
||||||
if color == self.STATUS_LED_COLOR_GREEN:
|
if color == self.STATUS_LED_COLOR_GREEN:
|
||||||
s1 = self.__set_gpio_value(
|
s1 = self.__set_gpio_value(s1_gpio, 1)
|
||||||
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 1)
|
s2 = self.__set_gpio_value(s2_gpio, 0)
|
||||||
s2 = self.__set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 0)
|
|
||||||
|
|
||||||
elif color == self.STATUS_LED_COLOR_RED:
|
elif color == self.STATUS_LED_COLOR_RED:
|
||||||
s1 = self.__set_gpio_value(
|
s1 = self.__set_gpio_value(s1_gpio, 0)
|
||||||
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 0)
|
s2 = self.__set_gpio_value(s2_gpio, 1)
|
||||||
s2 = self.__set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 1)
|
|
||||||
|
|
||||||
elif color == self.STATUS_LED_COLOR_OFF:
|
elif color == self.STATUS_LED_COLOR_OFF:
|
||||||
s1 = self.__set_gpio_value(
|
s1 = self.__set_gpio_value(s1_gpio, 1)
|
||||||
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'], 1)
|
s2 = self.__set_gpio_value(s2_gpio, 1)
|
||||||
s2 = self.__set_gpio_value(
|
|
||||||
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'], 1)
|
elif color == self.STATUS_LED_COLOR_AMBER:
|
||||||
|
s1 = self.__set_gpio_value(s1_gpio, 0)
|
||||||
|
s2 = self.__set_gpio_value(s2_gpio, 0)
|
||||||
|
else:
|
||||||
|
s1, s2 = True, True
|
||||||
|
|
||||||
set_status_led = s1 and s2
|
set_status_led = s1 and s2
|
||||||
return set_status_led
|
|
||||||
except IOError:
|
except IOError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return set_status_led
|
return set_status_led
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the fan status LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
s1 = self.__get_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['red'])
|
||||||
|
s2 = self.__get_gpio_value(
|
||||||
|
self.dx010_fan_gpio[self.fan_tray_index+1]['color']['green'])
|
||||||
|
|
||||||
|
return {
|
||||||
|
'10': self.STATUS_LED_COLOR_GREEN,
|
||||||
|
'01': self.STATUS_LED_COLOR_RED,
|
||||||
|
'00': self.STATUS_LED_COLOR_AMBER
|
||||||
|
}.get(s1+s2, self.STATUS_LED_COLOR_OFF)
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the device
|
||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the device
|
||||||
"""
|
"""
|
||||||
fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format(
|
fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] \
|
||||||
self.psu_index+1, self.fan_index+1)
|
if not self.is_psu_fan \
|
||||||
|
else "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1)
|
||||||
|
|
||||||
return fan_name
|
return fan_name
|
||||||
|
|
||||||
@ -321,3 +360,24 @@ class Fan(FanBase):
|
|||||||
status = self._api_helper.read_one_line_file(sysfs_path)
|
status = self._api_helper.read_one_line_file(sysfs_path)
|
||||||
|
|
||||||
return False if int(status) != 0 else True
|
return False if int(status) != 0 else True
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
return (self.fan_tray_index*2 + self.fan_index + 1) \
|
||||||
|
if not self.is_psu_fan else (self.fan_index+1)
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return True if not self.is_psu_fan else False
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# Celestica
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the the Fan-Drawers' information available in the platform
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sonic_platform_base.fan_drawer_base import FanDrawerBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
NUM_FAN = 2
|
||||||
|
|
||||||
|
|
||||||
|
class FanDrawer(FanDrawerBase):
|
||||||
|
def __init__(self, fantray_index):
|
||||||
|
FanDrawerBase.__init__(self)
|
||||||
|
self._index = fantray_index + 1
|
||||||
|
self._init_fan(fantray_index)
|
||||||
|
|
||||||
|
def _init_fan(self, fantray_index):
|
||||||
|
from sonic_platform.fan import Fan
|
||||||
|
for index in range(NUM_FAN):
|
||||||
|
fan = Fan(fantray_index, index)
|
||||||
|
self._fan_list.append(fan)
|
||||||
|
|
||||||
|
def set_status_led(self, color):
|
||||||
|
"""
|
||||||
|
Sets the state of the fan drawer status LED
|
||||||
|
Args:
|
||||||
|
color: A string representing the color with which to set the
|
||||||
|
fan drawer status LED
|
||||||
|
Returns:
|
||||||
|
bool: True if status LED state is set successfully, False if not
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].set_status_led(color)
|
||||||
|
|
||||||
|
def get_status_led(self, color=None):
|
||||||
|
"""
|
||||||
|
Gets the state of the fan drawer LED
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings above
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_status_led()
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
###################### Device methods ########################
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the device
|
||||||
|
Returns:
|
||||||
|
string: The name of the device
|
||||||
|
"""
|
||||||
|
return "Drawer{}".format(self._index)
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the device
|
||||||
|
Returns:
|
||||||
|
bool: True if device is present, False if not
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_presence()
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_model()
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_serial()
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the device
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if device is operating properly, False if not
|
||||||
|
"""
|
||||||
|
return self._fan_list[0].get_status()
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves 1-based relative physical position in parent device
|
||||||
|
Returns:
|
||||||
|
integer: The 1-based relative physical position in parent device
|
||||||
|
"""
|
||||||
|
return self._index
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return True
|
@ -7,7 +7,6 @@
|
|||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sonic_platform
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from sonic_platform_base.psu_base import PsuBase
|
from sonic_platform_base.psu_base import PsuBase
|
||||||
@ -16,6 +15,9 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
TLV_ATTR_TYPE_MODEL = 2
|
||||||
|
TLV_ATTR_TYPE_SERIAL = 5
|
||||||
|
PSU_EEPROM_PATH = "/sys/bus/i2c/devices/{}-00{}/eeprom"
|
||||||
GREEN_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:p-{}/brightness"
|
GREEN_LED_PATH = "/sys/devices/platform/leds_dx010/leds/dx010:green:p-{}/brightness"
|
||||||
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
|
||||||
GPIO_DIR = "/sys/class/gpio"
|
GPIO_DIR = "/sys/class/gpio"
|
||||||
@ -25,11 +27,13 @@ PSU_NUM_FAN = [1, 1]
|
|||||||
PSU_I2C_MAPPING = {
|
PSU_I2C_MAPPING = {
|
||||||
0: {
|
0: {
|
||||||
"num": 10,
|
"num": 10,
|
||||||
"addr": "5a"
|
"addr": "5a",
|
||||||
|
"eeprom_addr": "52"
|
||||||
},
|
},
|
||||||
1: {
|
1: {
|
||||||
"num": 11,
|
"num": 11,
|
||||||
"addr": "5b"
|
"addr": "5b",
|
||||||
|
"eeprom_addr": "53"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +45,7 @@ class Psu(PsuBase):
|
|||||||
PsuBase.__init__(self)
|
PsuBase.__init__(self)
|
||||||
self.index = psu_index
|
self.index = psu_index
|
||||||
self._api_helper = APIHelper()
|
self._api_helper = APIHelper()
|
||||||
self.green_led_path = GREEN_LED_PATH.format(self.index+1)
|
self.green_led_path = GREEN_LED_PATH.format(self.index + 1)
|
||||||
self.dx010_psu_gpio = [
|
self.dx010_psu_gpio = [
|
||||||
{'base': self.__get_gpio_base()},
|
{'base': self.__get_gpio_base()},
|
||||||
{'prs': 27, 'status': 22},
|
{'prs': 27, 'status': 22},
|
||||||
@ -50,6 +54,7 @@ class Psu(PsuBase):
|
|||||||
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
|
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
|
||||||
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
|
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
|
||||||
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
|
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
|
||||||
|
self.eeprom_addr = PSU_EEPROM_PATH.format(self.i2c_num, PSU_I2C_MAPPING[self.index]["eeprom_addr"])
|
||||||
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
for fan_index in range(0, PSU_NUM_FAN[self.index]):
|
||||||
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
|
||||||
self._fan_list.append(fan)
|
self._fan_list.append(fan)
|
||||||
@ -71,11 +76,37 @@ class Psu(PsuBase):
|
|||||||
|
|
||||||
def __get_gpio_value(self, pinnum):
|
def __get_gpio_value(self, pinnum):
|
||||||
gpio_base = self.dx010_psu_gpio[0]['base']
|
gpio_base = self.dx010_psu_gpio[0]['base']
|
||||||
gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base+pinnum)
|
gpio_dir = GPIO_DIR + '/gpio' + str(gpio_base + pinnum)
|
||||||
gpio_file = gpio_dir + "/value"
|
gpio_file = gpio_dir + "/value"
|
||||||
retval = self._api_helper.read_txt_file(gpio_file)
|
retval = self._api_helper.read_txt_file(gpio_file)
|
||||||
return retval.rstrip('\r\n')
|
return retval.rstrip('\r\n')
|
||||||
|
|
||||||
|
def read_fru(self, path, attr_type):
|
||||||
|
content = []
|
||||||
|
attr_idx = 0
|
||||||
|
attr_length = 0
|
||||||
|
|
||||||
|
if(os.path.exists(path)):
|
||||||
|
with open(path, 'r', encoding='unicode_escape') as f:
|
||||||
|
content = f.read()
|
||||||
|
target_offset = ord(content[4])
|
||||||
|
target_offset *= 8 # spec defined: offset are in multiples of 8 bytes
|
||||||
|
|
||||||
|
attr_idx = target_offset + 3
|
||||||
|
for i in range(1, attr_type):
|
||||||
|
if attr_idx > len(content):
|
||||||
|
raise SyntaxError
|
||||||
|
attr_length = (ord(content[attr_idx])) & (0x3f)
|
||||||
|
attr_idx += (attr_length + 1)
|
||||||
|
|
||||||
|
attr_length = (ord(content[attr_idx])) & (0x3f)
|
||||||
|
attr_idx += 1
|
||||||
|
else:
|
||||||
|
print("[PSU] Can't find path to eeprom : %s" % path)
|
||||||
|
return SyntaxError
|
||||||
|
|
||||||
|
return content[attr_idx:attr_idx + attr_length]
|
||||||
|
|
||||||
def get_voltage(self):
|
def get_voltage(self):
|
||||||
"""
|
"""
|
||||||
Retrieves current PSU voltage output
|
Retrieves current PSU voltage output
|
||||||
@ -209,7 +240,7 @@ class Psu(PsuBase):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if PSU is present, False if not
|
bool: True if PSU is present, False if not
|
||||||
"""
|
"""
|
||||||
raw = self.__get_gpio_value(self.dx010_psu_gpio[self.index+1]['prs'])
|
raw = self.__get_gpio_value(self.dx010_psu_gpio[self.index + 1]['prs'])
|
||||||
return int(raw, 10) == 0
|
return int(raw, 10) == 0
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
@ -219,5 +250,142 @@ class Psu(PsuBase):
|
|||||||
A boolean value, True if device is operating properly, False if not
|
A boolean value, True if device is operating properly, False if not
|
||||||
"""
|
"""
|
||||||
raw = self.__get_gpio_value(
|
raw = self.__get_gpio_value(
|
||||||
self.dx010_psu_gpio[self.index+1]['status'])
|
self.dx010_psu_gpio[self.index + 1]['status'])
|
||||||
return int(raw, 10) == 1
|
return int(raw, 10) == 1
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the device
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of device
|
||||||
|
"""
|
||||||
|
model = self.read_fru(self.eeprom_addr, TLV_ATTR_TYPE_MODEL)
|
||||||
|
if not model:
|
||||||
|
return "N/A"
|
||||||
|
return model
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the device
|
||||||
|
Returns:
|
||||||
|
string: Serial number of device
|
||||||
|
"""
|
||||||
|
serial = self.read_fru(self.eeprom_addr, TLV_ATTR_TYPE_SERIAL)
|
||||||
|
if not serial:
|
||||||
|
return "N/A"
|
||||||
|
return serial
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Indicate whether this device is replaceable.
|
||||||
|
Returns:
|
||||||
|
bool: True if it is replaceable.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_temperature(self):
|
||||||
|
"""
|
||||||
|
Retrieves current temperature reading from PSU
|
||||||
|
Returns:
|
||||||
|
A float number of current temperature in Celsius up to nearest thousandth
|
||||||
|
of one degree Celsius, e.g. 30.125
|
||||||
|
there are three temp sensors , we choose one of them
|
||||||
|
"""
|
||||||
|
psu_temperature = None
|
||||||
|
temperature_name = "temp{}_input"
|
||||||
|
temperature_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, temperature_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
temp_path = os.path.join(
|
||||||
|
dir_name, temperature_name.format(in_num))
|
||||||
|
vout_val = self._api_helper.read_txt_file(temp_path)
|
||||||
|
psu_temperature = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_temperature
|
||||||
|
|
||||||
|
def get_temperature_high_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the high threshold temperature of PSU
|
||||||
|
Returns:
|
||||||
|
A float number, the high threshold temperature of PSU in Celsius
|
||||||
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
|
there are three temp sensors , we choose one of them
|
||||||
|
"""
|
||||||
|
psu_temperature = None
|
||||||
|
temperature_name = "temp{}_max"
|
||||||
|
temperature_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, temperature_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
temp_path = os.path.join(
|
||||||
|
dir_name, temperature_name.format(in_num))
|
||||||
|
vout_val = self._api_helper.read_txt_file(temp_path)
|
||||||
|
psu_temperature = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_temperature
|
||||||
|
|
||||||
|
def get_voltage_high_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the high threshold PSU voltage output
|
||||||
|
Returns:
|
||||||
|
A float number, the high threshold output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
psu_voltage = 0.0
|
||||||
|
voltage_name = "in{}_crit"
|
||||||
|
voltage_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, voltage_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
vout_path = os.path.join(
|
||||||
|
dir_name, voltage_name.format(in_num))
|
||||||
|
vout_val = self._api_helper.read_txt_file(vout_path)
|
||||||
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_voltage
|
||||||
|
|
||||||
|
def get_voltage_low_threshold(self):
|
||||||
|
"""
|
||||||
|
Retrieves the low threshold PSU voltage output
|
||||||
|
Returns:
|
||||||
|
A float number, the low threshold output voltage in volts,
|
||||||
|
e.g. 12.1
|
||||||
|
"""
|
||||||
|
psu_voltage = 0.0
|
||||||
|
voltage_name = "in{}_lcrit"
|
||||||
|
voltage_label = "vout1"
|
||||||
|
|
||||||
|
vout_label_path = self.__search_file_by_contain(
|
||||||
|
self.hwmon_path, voltage_label, "in")
|
||||||
|
if vout_label_path:
|
||||||
|
dir_name = os.path.dirname(vout_label_path)
|
||||||
|
basename = os.path.basename(vout_label_path)
|
||||||
|
in_num = ''.join(list(filter(str.isdigit, basename)))
|
||||||
|
vout_path = os.path.join(
|
||||||
|
dir_name, voltage_name.format(in_num))
|
||||||
|
vout_val = self._api_helper.read_txt_file(vout_path)
|
||||||
|
psu_voltage = float(vout_val) / 1000
|
||||||
|
|
||||||
|
return psu_voltage
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,6 @@
|
|||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -19,14 +18,18 @@ except ImportError as e:
|
|||||||
THERMAL_INFO = {
|
THERMAL_INFO = {
|
||||||
0: {
|
0: {
|
||||||
"F2B_max": 50,
|
"F2B_max": 50,
|
||||||
|
"F2B_max_crit": 75,
|
||||||
"B2F_max": 55,
|
"B2F_max": 55,
|
||||||
|
"B2F_max_crit": 75,
|
||||||
"postion": "asic",
|
"postion": "asic",
|
||||||
"name": "Front-panel temp sensor 1",
|
"name": "Front-panel temp sensor 1",
|
||||||
"i2c_path": "i2c-5/5-0048/hwmon/hwmon1", # u4 system-inlet
|
"i2c_path": "i2c-5/5-0048/hwmon/hwmon1", # u4 system-inlet
|
||||||
},
|
},
|
||||||
1: {
|
1: {
|
||||||
"F2B_max": 50,
|
"F2B_max": 50,
|
||||||
|
"F2B_max_crit": 75,
|
||||||
"B2F_max": 55,
|
"B2F_max": 55,
|
||||||
|
"B2F_max_crit": 75,
|
||||||
"postion": "asic",
|
"postion": "asic",
|
||||||
"name": "Front-panel temp sensor 2",
|
"name": "Front-panel temp sensor 2",
|
||||||
"i2c_path": "i2c-6/6-0049/hwmon/hwmon2", # u2 system-inlet
|
"i2c_path": "i2c-6/6-0049/hwmon/hwmon2", # u2 system-inlet
|
||||||
@ -51,7 +54,9 @@ THERMAL_INFO = {
|
|||||||
},
|
},
|
||||||
4: {
|
4: {
|
||||||
"F2B_max": 70,
|
"F2B_max": 70,
|
||||||
|
"F2B_max_crit": 75,
|
||||||
"B2F_max": 55,
|
"B2F_max": 55,
|
||||||
|
"B2F_max_crit": 75,
|
||||||
"postion": "cpu",
|
"postion": "cpu",
|
||||||
"name": "Rear-panel temp sensor 2",
|
"name": "Rear-panel temp sensor 2",
|
||||||
"i2c_path": "i2c-15/15-004e/hwmon/hwmon5" # u9201 system-outlet
|
"i2c_path": "i2c-15/15-004e/hwmon/hwmon5" # u9201 system-outlet
|
||||||
@ -72,8 +77,7 @@ class Thermal(ThermalBase):
|
|||||||
self._api_helper = APIHelper()
|
self._api_helper = APIHelper()
|
||||||
self._airflow = airflow
|
self._airflow = airflow
|
||||||
self._thermal_info = THERMAL_INFO[self.index]
|
self._thermal_info = THERMAL_INFO[self.index]
|
||||||
self._hwmon_path = "{}/{}".format(I2C_ADAPTER_PATH,
|
self._hwmon_path = "{}/{}".format(I2C_ADAPTER_PATH, self._thermal_info["i2c_path"])
|
||||||
self._thermal_info["i2c_path"])
|
|
||||||
self.name = self.get_name()
|
self.name = self.get_name()
|
||||||
self.postion = self._thermal_info["postion"]
|
self.postion = self._thermal_info["postion"]
|
||||||
self.ss_index = 1
|
self.ss_index = 1
|
||||||
@ -110,8 +114,9 @@ class Thermal(ThermalBase):
|
|||||||
A float number, the high threshold temperature of thermal in Celsius
|
A float number, the high threshold temperature of thermal in Celsius
|
||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
max_crit_key = '{}_max'.format(self._airflow)
|
temp_file = "temp{}_max".format(self.ss_index)
|
||||||
return self._thermal_info.get(max_crit_key, None)
|
temp = float(self.__get_temp(temp_file))
|
||||||
|
return temp
|
||||||
|
|
||||||
def get_low_threshold(self):
|
def get_low_threshold(self):
|
||||||
"""
|
"""
|
||||||
@ -120,7 +125,7 @@ class Thermal(ThermalBase):
|
|||||||
A float number, the low threshold temperature of thermal in Celsius
|
A float number, the low threshold temperature of thermal in Celsius
|
||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
return 0.0
|
return 0.001
|
||||||
|
|
||||||
def set_high_threshold(self, temperature):
|
def set_high_threshold(self, temperature):
|
||||||
"""
|
"""
|
||||||
@ -133,31 +138,33 @@ class Thermal(ThermalBase):
|
|||||||
"""
|
"""
|
||||||
temp_file = "temp{}_max".format(self.ss_index)
|
temp_file = "temp{}_max".format(self.ss_index)
|
||||||
is_set = self.__set_threshold(temp_file, int(temperature*1000))
|
is_set = self.__set_threshold(temp_file, int(temperature*1000))
|
||||||
file_set = False
|
file_set = True
|
||||||
if is_set:
|
if self._api_helper.is_host():
|
||||||
try:
|
file_set = False
|
||||||
with open(self.SS_CONFIG_PATH, 'r+') as f:
|
if is_set:
|
||||||
content = f.readlines()
|
try:
|
||||||
f.seek(0)
|
with open(self.SS_CONFIG_PATH, 'r+') as f:
|
||||||
ss_found = False
|
content = f.readlines()
|
||||||
for idx, val in enumerate(content):
|
f.seek(0)
|
||||||
if self.name in val:
|
ss_found = False
|
||||||
ss_found = True
|
for idx, val in enumerate(content):
|
||||||
elif ss_found and temp_file in val:
|
if self.name in val:
|
||||||
content[idx] = " set {} {}\n".format(
|
ss_found = True
|
||||||
temp_file, temperature)
|
elif ss_found and temp_file in val:
|
||||||
f.writelines(content)
|
content[idx] = " set {} {}\n".format(
|
||||||
file_set = True
|
temp_file, temperature)
|
||||||
break
|
f.writelines(content)
|
||||||
except IOError:
|
file_set = True
|
||||||
file_set = False
|
break
|
||||||
|
except IOError as err:
|
||||||
|
file_set = False
|
||||||
|
|
||||||
return is_set & file_set
|
return is_set & file_set
|
||||||
|
|
||||||
def set_low_threshold(self, temperature):
|
def set_low_threshold(self, temperature):
|
||||||
"""
|
"""
|
||||||
Sets the low threshold temperature of thermal
|
Sets the low threshold temperature of thermal
|
||||||
Args :
|
Args :
|
||||||
temperature: A float number up to nearest thousandth of one degree Celsius,
|
temperature: A float number up to nearest thousandth of one degree Celsius,
|
||||||
e.g. 30.125
|
e.g. 30.125
|
||||||
Returns:
|
Returns:
|
||||||
@ -173,7 +180,10 @@ class Thermal(ThermalBase):
|
|||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
max_crit_key = '{}_max_crit'.format(self._airflow)
|
max_crit_key = '{}_max_crit'.format(self._airflow)
|
||||||
return self._thermal_info.get(max_crit_key, None)
|
max_crit_threshold = self._thermal_info.get(max_crit_key, None)
|
||||||
|
if max_crit_threshold is not None:
|
||||||
|
max_crit_threshold = float(max_crit_threshold)
|
||||||
|
return max_crit_threshold
|
||||||
|
|
||||||
def get_low_critical_threshold(self):
|
def get_low_critical_threshold(self):
|
||||||
"""
|
"""
|
||||||
@ -182,7 +192,7 @@ class Thermal(ThermalBase):
|
|||||||
A float number, the low critical threshold temperature of thermal in Celsius
|
A float number, the low critical threshold temperature of thermal in Celsius
|
||||||
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
up to nearest thousandth of one degree Celsius, e.g. 30.125
|
||||||
"""
|
"""
|
||||||
return 0.0
|
return 0.001
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
@ -234,3 +244,21 @@ class Thermal(ThermalBase):
|
|||||||
|
|
||||||
raw_txt = self.__read_txt_file(fault_file_path)
|
raw_txt = self.__read_txt_file(fault_file_path)
|
||||||
return int(raw_txt) == 0
|
return int(raw_txt) == 0
|
||||||
|
|
||||||
|
def is_replaceable(self):
|
||||||
|
"""
|
||||||
|
Retrieves whether thermal module is replaceable
|
||||||
|
Returns:
|
||||||
|
A boolean value, True if replaceable, False if not
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_position_in_parent(self):
|
||||||
|
"""
|
||||||
|
Retrieves the thermal position information
|
||||||
|
Returns:
|
||||||
|
A int value, 0 represent ASIC thermal, 1 represent CPU thermal info
|
||||||
|
"""
|
||||||
|
if self.postion == "cpu":
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
@ -135,6 +135,9 @@ class Watchdog(WatchdogBase):
|
|||||||
ret = WDT_COMMON_ERROR
|
ret = WDT_COMMON_ERROR
|
||||||
if seconds < 0:
|
if seconds < 0:
|
||||||
return ret
|
return ret
|
||||||
|
if seconds > 16779:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.timeout != seconds:
|
if self.timeout != seconds:
|
||||||
|
@ -89,10 +89,19 @@ start)
|
|||||||
echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-13/new_device
|
echo emc2305 0x2e > /sys/bus/i2c/devices/i2c-13/new_device
|
||||||
echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-13/new_device
|
echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-13/new_device
|
||||||
|
|
||||||
|
echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-18/new_device
|
||||||
|
echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-19/new_device
|
||||||
|
echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-20/new_device
|
||||||
|
echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-21/new_device
|
||||||
|
echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-22/new_device
|
||||||
|
|
||||||
# Attach PSUs
|
# Attach PSUs
|
||||||
echo dps460 0x5a > /sys/bus/i2c/devices/i2c-10/new_device
|
echo dps460 0x5a > /sys/bus/i2c/devices/i2c-10/new_device
|
||||||
echo dps460 0x5b > /sys/bus/i2c/devices/i2c-11/new_device
|
echo dps460 0x5b > /sys/bus/i2c/devices/i2c-11/new_device
|
||||||
|
|
||||||
|
echo 24c02 0x52 > /sys/bus/i2c/devices/i2c-10/new_device
|
||||||
|
echo 24c02 0x53 > /sys/bus/i2c/devices/i2c-11/new_device
|
||||||
|
|
||||||
# Attach PCA9506 GPIO expander for 40 pins
|
# Attach PCA9506 GPIO expander for 40 pins
|
||||||
echo pca9505 0x20 > /sys/bus/i2c/devices/i2c-17/new_device
|
echo pca9505 0x20 > /sys/bus/i2c/devices/i2c-17/new_device
|
||||||
|
|
||||||
@ -117,16 +126,16 @@ start)
|
|||||||
export_gpio 27 "in" # PSU L ABS
|
export_gpio 27 "in" # PSU L ABS
|
||||||
export_gpio 28 "in" # PSU R ABS
|
export_gpio 28 "in" # PSU R ABS
|
||||||
|
|
||||||
export_gpio 29 "out" # Fan 1 LED: Red
|
export_gpio 29 "out" # Fan 2 LED: Red
|
||||||
export_gpio 30 "out" # Fan 1 LED: Yellow
|
export_gpio 30 "out" # Fan 2 LED: Green
|
||||||
export_gpio 31 "out" # Fan 2 LED: Red
|
export_gpio 31 "out" # Fan 1 LED: Red
|
||||||
export_gpio 32 "out" # Fan 2 LED: Yellow
|
export_gpio 32 "out" # Fan 1 LED: Green
|
||||||
export_gpio 33 "out" # Fan 3 LED: Red
|
export_gpio 33 "out" # Fan 5 LED: Red
|
||||||
export_gpio 34 "out" # Fan 3 LED: Yellow
|
export_gpio 34 "out" # Fan 5 LED: Green
|
||||||
export_gpio 35 "out" # Fan 4 LED: Red
|
export_gpio 35 "out" # Fan 3 LED: Red
|
||||||
export_gpio 36 "out" # Fan 4 LED: Yellow
|
export_gpio 36 "out" # Fan 3 LED: Green
|
||||||
export_gpio 37 "out" # Fan 5 LED: Red
|
export_gpio 37 "out" # Fan 4 LED: Red
|
||||||
export_gpio 38 "out" # Fan 5 LED: Yellow
|
export_gpio 38 "out" # Fan 4 LED: Green
|
||||||
|
|
||||||
# Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow)
|
# Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow)
|
||||||
echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode
|
echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode
|
||||||
|
@ -5,4 +5,5 @@ dx010/scripts/fancontrol.sh etc/init.d
|
|||||||
dx010/scripts/fancontrol.service lib/systemd/system
|
dx010/scripts/fancontrol.service lib/systemd/system
|
||||||
services/fancontrol/fancontrol usr/local/bin
|
services/fancontrol/fancontrol usr/local/bin
|
||||||
dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0
|
dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0
|
||||||
|
dx010/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0
|
||||||
services/platform_api/platform_api_mgnt.sh usr/local/bin
|
services/platform_api/platform_api_mgnt.sh usr/local/bin
|
||||||
|
@ -4,13 +4,20 @@ PREV_REBOOT_CAUSE="/host/reboot-cause/"
|
|||||||
DEVICE="/usr/share/sonic/device"
|
DEVICE="/usr/share/sonic/device"
|
||||||
PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
|
PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
|
||||||
FILES=$DEVICE/$PLATFORM/api_files
|
FILES=$DEVICE/$PLATFORM/api_files
|
||||||
|
PY2_PACK=$DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl
|
||||||
|
PY3_PACK=$DEVICE/$PLATFORM/sonic_platform-1.0-py3-none-any.whl
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
# Install sonic-platform package
|
# Install python2.7 sonic-platform package
|
||||||
if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl ]; then
|
if [ -e $PY2_PACK ]; then
|
||||||
pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py2-none-any.whl
|
pip install $PY2_PACK
|
||||||
pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Install python3 sonic-platform package
|
||||||
|
if [ -e $PY3_PACK ]; then
|
||||||
|
pip3 install $PY3_PACK
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
Reference in New Issue
Block a user