Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mellanox] [202106] Add a trigger to set LED to blink #90

Closed
wants to merge 1 commit into from
Closed
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
206 changes: 88 additions & 118 deletions platform/mellanox/mlnx-platform-api/sonic_platform/led.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os
import time
from . import utils


class Led(object):
Expand All @@ -10,7 +12,7 @@ class Led(object):
STATUS_LED_COLOR_ORANGE_BLINK = 'orange_blink'
STATUS_LED_COLOR_OFF = 'off'

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

Expand All @@ -26,12 +28,11 @@ def set_status(self, color):
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)
return self._set_status_blink(color, 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)
status = True
utils.write_file(self.get_green_led_path(), Led.LED_ON)
status = True
elif color == Led.STATUS_LED_COLOR_RED:
# Some led don't support red led but support orange led, in this case we set led to orange
if Led.STATUS_LED_COLOR_RED in led_cap_list:
Expand All @@ -41,19 +42,15 @@ def set_status(self, color):
else:
return False

with open(led_path, 'w') as led:
led.write(Led.LED_ON)
status = True
utils.write_file(led_path, Led.LED_ON)
status = True
elif color == Led.STATUS_LED_COLOR_OFF:
if Led.STATUS_LED_COLOR_GREEN in led_cap_list:
with open(self.get_green_led_path(), 'w') as led:
led.write(Led.LED_OFF)
utils.write_file(self.get_green_led_path(), Led.LED_OFF)
if Led.STATUS_LED_COLOR_RED in led_cap_list:
with open(self.get_red_led_path(), 'w') as led:
led.write(Led.LED_OFF)
utils.write_file(self.get_red_led_path(), Led.LED_OFF)
if Led.STATUS_LED_COLOR_ORANGE in led_cap_list:
with open(self.get_orange_led_path(), 'w') as led:
led.write(Led.LED_OFF)
utils.write_file(self.get_orange_led_path(), Led.LED_OFF)

status = True
else:
Expand All @@ -63,7 +60,7 @@ def set_status(self, color):

return status

def _set_status_blink(self, color, blink_pos, led_cap_list):
def _set_status_blink(self, color, 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
Expand All @@ -73,32 +70,60 @@ def _set_status_blink(self, color, blink_pos, led_cap_list):
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)
self._trigger_blink(self.get_green_led_trigger())
return 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)
self._trigger_blink(self.get_red_led_trigger())
return 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)
self._trigger_blink(self.get_orange_led_trigger())
return 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)
self._untrigger_blink(self.get_green_led_trigger())
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)
self._untrigger_blink(self.get_red_led_trigger())
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)
self._untrigger_blink(self.get_orange_led_trigger())
except Exception as e:
return

def _trigger_blink(self, blink_trigger_file):
utils.write_file(blink_trigger_file, 'timer')

def _untrigger_blink(self, blink_trigger_file):
utils.write_file(blink_trigger_file, 'none')

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)
if not self._wait_files_ready((delay_on_file, delay_off_file)):
return False

utils.write_file(delay_on_file, value)
utils.write_file(delay_off_file, value)
return True

def _wait_files_ready(self, file_list):
"""delay_off and delay_on sysfs will be available only if _trigger_blink is called. And once
_trigger_blink is called, driver might need time to prepare delay_off and delay_on. So,
need wait a few seconds here to make sure the sysfs is ready

Args:
file_list (list of str): files to be checked
"""
wait_time = 5.0
initial_sleep = 0.01
while wait_time > 0:
if all([os.path.exists(x) for x in file_list]):
return True
time.sleep(initial_sleep)
wait_time -= initial_sleep
initial_sleep = initial_sleep * 2

return False

def get_status(self):
led_cap_list = self.get_capability()
Expand All @@ -110,18 +135,15 @@ def get_status(self):
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
if utils.read_str_from_file(self.get_green_led_path()) != Led.LED_OFF:
return Led.STATUS_LED_COLOR_GREEN

if Led.STATUS_LED_COLOR_RED in led_cap_list:
with open(self.get_red_led_path(), 'r') as led:
if Led.LED_OFF != led.read().rstrip('\n'):
return Led.STATUS_LED_COLOR_RED
if utils.read_str_from_file(self.get_red_led_path()) != Led.LED_OFF:
return Led.STATUS_LED_COLOR_RED
if Led.STATUS_LED_COLOR_ORANGE in led_cap_list:
with open(self.get_orange_led_path(), 'r') as led:
if Led.LED_OFF != led.read().rstrip('\n'):
return Led.STATUS_LED_COLOR_RED
if utils.read_str_from_file(self.get_orange_led_path()) != Led.LED_OFF:
return Led.STATUS_LED_COLOR_RED
except (ValueError, IOError) as e:
raise RuntimeError("Failed to read led status due to {}".format(repr(e)))

Expand All @@ -132,6 +154,7 @@ def _get_blink_status(self, led_cap_list):
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
Expand All @@ -144,126 +167,73 @@ def _get_blink_status(self, led_cap_list):
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')
delay_on = utils.read_str_from_file(delay_on_file, default=Led.LED_OFF)
delay_off = utils.read_str_from_file(delay_off_file, default=Led.LED_OFF)
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 = set(caps.split())
except (ValueError, IOError):
pass

return cap_list
caps = utils.read_str_from_file(self.get_led_cap_path())
return set(caps.split())

def get_green_led_path(self):
pass
return os.path.join(Led.LED_PATH, 'led_{}_green'.format(self._led_id))

def get_green_led_delay_off_path(self):
return '{}_delay_off'.format(self.get_green_led_path())
return os.path.join(Led.LED_PATH, 'led_{}_green_delay_off'.format(self._led_id))

def get_green_led_delay_on_path(self):
return '{}_delay_on'.format(self.get_green_led_path())
return os.path.join(Led.LED_PATH, 'led_{}_green_delay_on'.format(self._led_id))

def get_green_led_trigger(self):
return os.path.join(Led.LED_PATH, 'led_{}_green_trigger'.format(self._led_id))

def get_red_led_path(self):
pass
return os.path.join(Led.LED_PATH, 'led_{}_red'.format(self._led_id))

def get_red_led_delay_off_path(self):
return '{}_delay_off'.format(self.get_red_led_path())
return os.path.join(Led.LED_PATH, 'led_{}_red_delay_off'.format(self._led_id))

def get_red_led_delay_on_path(self):
return '{}_delay_on'.format(self.get_red_led_path())
return os.path.join(Led.LED_PATH, 'led_{}_red_delay_on'.format(self._led_id))

def get_red_led_trigger(self):
return os.path.join(Led.LED_PATH, 'led_{}_red_trigger'.format(self._led_id))

def get_orange_led_path(self):
pass
return os.path.join(Led.LED_PATH, 'led_{}_orange'.format(self._led_id))

def get_orange_led_delay_off_path(self):
return '{}_delay_off'.format(self.get_orange_led_path())
return os.path.join(Led.LED_PATH, 'led_{}_orange_delay_off'.format(self._led_id))

def get_orange_led_delay_on_path(self):
return '{}_delay_on'.format(self.get_orange_led_path())
return os.path.join(Led.LED_PATH, 'led_{}_orange_delay_on'.format(self._led_id))

def get_orange_led_trigger(self):
return os.path.join(Led.LED_PATH, 'led_{}_orange_trigger'.format(self._led_id))

def get_led_cap_path(self):
pass
return os.path.join(Led.LED_PATH, 'led_{}_capability'.format(self._led_id))


class FanLed(Led):
LED_PATH = "/var/run/hw-management/led/"

class FanLed(Led):
def __init__(self, index):
if index is not None:
self._green_led_path = os.path.join(Led.LED_PATH, "led_fan{}_green".format(index))
self._red_led_path = os.path.join(Led.LED_PATH, "led_fan{}_red".format(index))
self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan{}_orange".format(index))
self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan{}_capability".format(index))
self._led_id = 'fan{}'.format(index)
else:
self._green_led_path = os.path.join(Led.LED_PATH, "led_fan_green")
self._red_led_path = os.path.join(Led.LED_PATH, "led_fan_red")
self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan_orange")
self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan_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
self._led_id = 'fan'


class PsuLed(Led):
def __init__(self, index):
if index is not None:
self._green_led_path = os.path.join(Led.LED_PATH, "led_psu{}_green".format(index))
self._red_led_path = os.path.join(Led.LED_PATH, "led_psu{}_red".format(index))
self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu{}_orange".format(index))
self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu{}_capability".format(index))
self._led_id = 'psu{}'.format(index)
else:
self._green_led_path = os.path.join(Led.LED_PATH, "led_psu_green")
self._red_led_path = os.path.join(Led.LED_PATH, "led_psu_red")
self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu_orange")
self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu_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
self._led_id = 'psu'


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
self._led_id = 'status'


class SharedLed(object):
Expand Down