Skip to content

Commit

Permalink
[Mellanox] Add support for set/get system led status (#4829)
Browse files Browse the repository at this point in the history
System health feature needs to set/get system led status

- Add a led object in chassis class and initialize it when the API is called on host side
- Read/write system led system fs to get/set the status
  • Loading branch information
Junchao-Mellanox authored Jul 13, 2020
1 parent e1f7fb1 commit 76d68ad
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 1 deletion.
29 changes: 29 additions & 0 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
class Chassis(ChassisBase):
"""Platform-specific Chassis class"""

# System status LED
_led = None

def __init__(self):
super(Chassis, self).__init__()

Expand Down Expand Up @@ -156,6 +159,10 @@ def initialize_components(self):
self._component_list.append(ComponentBIOS())
self._component_list.extend(ComponentCPLD.get_component_list())

def initizalize_system_led(self):
from .led import SystemLed
Chassis._led = SystemLed()


def get_name(self):
"""
Expand Down Expand Up @@ -467,3 +474,25 @@ def get_thermal_manager(self):
from .thermal_manager import ThermalManager
return ThermalManager

def set_status_led(self, color):
"""
Sets the state of the system LED
Args:
color: A string representing the color with which to set the
system LED
Returns:
bool: True if system LED state is set successfully, False if not
"""
return False if not Chassis._led else Chassis._led.set_status(color)

def get_status_led(self):
"""
Gets the state of the system LED
Returns:
A string, one of the valid LED color strings which could be vendor
specified.
"""
return None if not Chassis._led else Chassis._led.get_status()
113 changes: 112 additions & 1 deletion platform/mellanox/mlnx-platform-api/sonic_platform/led.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@

class Led(object):
STATUS_LED_COLOR_GREEN = 'green'
STATUS_LED_COLOR_GREEN_BLINK = 'green_blink'
STATUS_LED_COLOR_RED = 'red'
STATUS_LED_COLOR_RED_BLINK = 'red_blink'
STATUS_LED_COLOR_ORANGE = 'orange'
STATUS_LED_COLOR_ORANGE_BLINK = 'orange_blink'
STATUS_LED_COLOR_OFF = 'off'

LED_ON = '1'
LED_OFF = '0'
LED_BLINK = '50'

LED_PATH = "/var/run/hw-management/led/"

Expand All @@ -19,6 +23,11 @@ def set_status(self, color):

status = False
try:
self._stop_blink(led_cap_list)
blink_pos = color.find('blink')
if blink_pos != -1:
return self._set_status_blink(color, blink_pos, led_cap_list)

if color == Led.STATUS_LED_COLOR_GREEN:
with open(self.get_green_led_path(), 'w') as led:
led.write(Led.LED_ON)
Expand Down Expand Up @@ -54,12 +63,53 @@ def set_status(self, color):

return status

def _set_status_blink(self, color, blink_pos, led_cap_list):
if color not in led_cap_list:
if color == Led.STATUS_LED_COLOR_RED_BLINK and Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list:
color = Led.STATUS_LED_COLOR_ORANGE_BLINK
elif color == Led.STATUS_LED_COLOR_ORANGE_BLINK and Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list:
color = Led.STATUS_LED_COLOR_RED_BLINK
else:
return False

if Led.STATUS_LED_COLOR_GREEN_BLINK == color:
self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_BLINK)
elif Led.STATUS_LED_COLOR_RED_BLINK == color:
self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_BLINK)
elif Led.STATUS_LED_COLOR_ORANGE_BLINK == color:
self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_BLINK)
else:
return False

return True

def _stop_blink(self, led_cap_list):
try:
if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list:
self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_OFF)
if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list:
self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_OFF)
if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list:
self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_OFF)
except Exception as e:
return

def _set_led_blink_status(self, delay_on_file, delay_off_file, value):
with open(delay_on_file, 'w') as led:
led.write(value)
with open(delay_off_file, 'w') as led:
led.write(value)

def get_status(self):
led_cap_list = self.get_capability()
if led_cap_list is None:
return Led.STATUS_LED_COLOR_OFF

try:
blink_status = self._get_blink_status(led_cap_list)
if blink_status is not None:
return blink_status

with open(self.get_green_led_path(), 'r') as led:
if Led.LED_OFF != led.read().rstrip('\n'):
return Led.STATUS_LED_COLOR_GREEN
Expand All @@ -77,12 +127,35 @@ def get_status(self):

return Led.STATUS_LED_COLOR_OFF

def _get_blink_status(self, led_cap_list):
try:
if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list:
if self._is_led_blinking(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path()):
return Led.STATUS_LED_COLOR_GREEN_BLINK
if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list:
if self._is_led_blinking(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path()):
return Led.STATUS_LED_COLOR_RED_BLINK
if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list:
if self._is_led_blinking(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path()):
return Led.STATUS_LED_COLOR_ORANGE_BLINK
except Exception as e:
return None

return None

def _is_led_blinking(self, delay_on_file, delay_off_file):
with open(delay_on_file, 'r') as led:
delay_on = led.read().rstrip('\n')
with open(delay_off_file, 'r') as led:
delay_off = led.read().rstrip('\n')
return delay_on != Led.LED_OFF and delay_off != Led.LED_OFF

def get_capability(self):
cap_list = None
try:
with open(self.get_led_cap_path(), 'r') as led_cap:
caps = led_cap.read()
cap_list = caps.split()
cap_list = set(caps.split())
except (ValueError, IOError):
pass

Expand All @@ -91,12 +164,30 @@ def get_capability(self):
def get_green_led_path(self):
pass

def get_green_led_delay_off_path(self):
return '{}_delay_off'.format(self.get_green_led_path())

def get_green_led_delay_on_path(self):
return '{}_delay_on'.format(self.get_green_led_path())

def get_red_led_path(self):
pass

def get_red_led_delay_off_path(self):
return '{}_delay_off'.format(self.get_red_led_path())

def get_red_led_delay_on_path(self):
return '{}_delay_on'.format(self.get_red_led_path())

def get_orange_led_path(self):
pass

def get_orange_led_delay_off_path(self):
return '{}_delay_off'.format(self.get_orange_led_path())

def get_orange_led_delay_on_path(self):
return '{}_delay_on'.format(self.get_orange_led_path())

def get_led_cap_path(self):
pass

Expand Down Expand Up @@ -159,6 +250,26 @@ def get_led_cap_path(self):
return self._led_cap_path


class SystemLed(Led):
def __init__(self):
self._green_led_path = os.path.join(Led.LED_PATH, "led_status_green")
self._red_led_path = os.path.join(Led.LED_PATH, "led_status_red")
self._orange_led_path = os.path.join(Led.LED_PATH, "led_status_orange")
self._led_cap_path = os.path.join(Led.LED_PATH, "led_status_capability")

def get_green_led_path(self):
return self._green_led_path

def get_red_led_path(self):
return self._red_led_path

def get_orange_led_path(self):
return self._orange_led_path

def get_led_cap_path(self):
return self._led_cap_path


class SharedLed(object):
LED_PRIORITY = {
Led.STATUS_LED_COLOR_RED: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def __init__(self):
if self._is_host():
self._chassis = Chassis()
self._chassis.initialize_components()
self._chassis.initizalize_system_led()
else:
self._chassis = Chassis()
self._chassis.initialize_psu()
Expand Down

0 comments on commit 76d68ad

Please sign in to comment.