diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py index 2f27386814..e5e5c8a19d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py @@ -15,8 +15,9 @@ # limitations under the License. # import os -from sonic_py_common.logger import Logger +import time +from sonic_py_common.logger import Logger from . import utils logger = Logger() @@ -88,10 +89,13 @@ class Led(object): return False if Led.STATUS_LED_COLOR_GREEN_BLINK == color: + 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._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._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 @@ -99,19 +103,47 @@ class Led(object): 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): + 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() if led_cap_list is None: diff --git a/platform/mellanox/mlnx-platform-api/tests/test_led.py b/platform/mellanox/mlnx-platform-api/tests/test_led.py index 71be3685ce..2a32eca2b6 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_led.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_led.py @@ -34,6 +34,7 @@ from sonic_platform.led import Led from sonic_platform.psu import FixedPsu, Psu class TestLed: + @mock.patch('sonic_platform.led.Led._wait_files_ready', mock.MagicMock(return_value=True)) def test_chassis_led(self): chassis = Chassis() assert chassis._led is None @@ -94,6 +95,7 @@ class TestLed: led.get_orange_led_delay_on_path(): Led.LED_OFF, } + @mock.patch('sonic_platform.led.Led._wait_files_ready', mock.MagicMock(return_value=True)) def test_fan_led(self): fan_drawer = RealDrawer(0) self._verify_fan_led(fan_drawer) @@ -133,12 +135,14 @@ class TestLed: assert obj1.get_status_led() == Led.STATUS_LED_COLOR_GREEN assert obj1.get_status_led() == Led.STATUS_LED_COLOR_GREEN + @mock.patch('sonic_platform.led.Led._wait_files_ready', mock.MagicMock(return_value=True)) def test_psu_led(self): psu1 = Psu(0) psu2 = Psu(1) physical_led = Psu.get_shared_led()._led self._verify_shared_led(physical_led, psu1, psu2) + @mock.patch('sonic_platform.led.Led._wait_files_ready', mock.MagicMock(return_value=True)) def test_fixed_psu_led(self): psu = FixedPsu(0) physical_led = psu.led