Skip to content

Commit

Permalink
[Mellanox] add PSU fan direction support (sonic-net#14508)
Browse files Browse the repository at this point in the history
- Why I did it
Add PSU fan direction support

- How I did it
Implement fan.get_direction for PSU fan

- How to verify it
Manual test
Unit test
  • Loading branch information
Junchao-Mellanox authored and mssonicbld committed Jun 10, 2023
1 parent c99e035 commit 26858ce
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 18 deletions.
31 changes: 28 additions & 3 deletions platform/mellanox/mlnx-platform-api/sonic_platform/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from .led import ComponentFaultyIndicator
from . import utils
from .thermal import Thermal
from .fan_drawer import VirtualDrawer
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

Expand All @@ -45,7 +46,10 @@
FAN_DIR = "/var/run/hw-management/thermal/fan{}_dir"
FAN_DIR_VALUE_EXHAUST = 0
FAN_DIR_VALUE_INTAKE = 1

FAN_DIR_MAPPING = {
FAN_DIR_VALUE_EXHAUST: FanBase.FAN_DIRECTION_EXHAUST,
FAN_DIR_VALUE_INTAKE: FanBase.FAN_DIRECTION_INTAKE,
}

class MlnxFan(FanBase):
def __init__(self, fan_index, position):
Expand Down Expand Up @@ -125,6 +129,20 @@ def is_replaceable(self):
"""
return False

@classmethod
def get_fan_direction(cls, dir_path):
try:
fan_dir = utils.read_int_from_file(dir_path, raise_exception=True)
ret = FAN_DIR_MAPPING.get(fan_dir)
if ret is None:
logger.log_error(f"Got wrong value {fan_dir} for fan direction {dir_path}")
return FanBase.FAN_DIRECTION_NOT_APPLICABLE
else:
return ret
except (ValueError, IOError) as e:
logger.log_error(f"Failed to read fan direction from {dir_path} - {e}")
return FanBase.FAN_DIRECTION_NOT_APPLICABLE


class PsuFan(MlnxFan):
# PSU fan speed vector
Expand All @@ -145,6 +163,7 @@ def __init__(self, fan_index, position, psu):
self.psu_i2c_bus_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_bus'.format(self.index))
self.psu_i2c_addr_path = os.path.join(CONFIG_PATH, 'psu{0}_i2c_addr'.format(self.index))
self.psu_i2c_command_path = os.path.join(CONFIG_PATH, 'fan_command')
self.psu_fan_dir_path = os.path.join(FAN_PATH, "psu{}_fan_dir".format(self.index))

def get_direction(self):
"""
Expand All @@ -165,7 +184,10 @@ def get_direction(self):
1 stands for forward, in other words intake
0 stands for reverse, in other words exhaust
"""
return self.FAN_DIRECTION_NOT_APPLICABLE
if not os.path.exists(self.psu_fan_dir_path) or not self.get_presence():
return self.FAN_DIRECTION_NOT_APPLICABLE

return MlnxFan.get_fan_direction(self.psu_fan_dir_path)

def get_status(self):
"""
Expand Down Expand Up @@ -263,7 +285,10 @@ def get_direction(self):
1 stands for forward, in other words intake
0 stands for reverse, in other words exhaust
"""
return self.fan_drawer.get_direction()
if not isinstance(self.fan_drawer, VirtualDrawer):
return self.fan_drawer.get_direction()
else:
return MlnxFan.get_fan_direction(FAN_DIR.format(self.index))

def get_status(self):
"""
Expand Down
15 changes: 2 additions & 13 deletions platform/mellanox/mlnx-platform-api/sonic_platform/fan_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,8 @@ def get_direction(self):
if not self.get_presence():
return FanBase.FAN_DIRECTION_NOT_APPLICABLE

try:
from .fan import FAN_DIR, FAN_DIR_VALUE_INTAKE, FAN_DIR_VALUE_EXHAUST
fan_dir = utils.read_int_from_file(FAN_DIR.format(self._index), raise_exception=True)
if fan_dir == FAN_DIR_VALUE_INTAKE:
return FanBase.FAN_DIRECTION_INTAKE
elif fan_dir == FAN_DIR_VALUE_EXHAUST:
return FanBase.FAN_DIRECTION_EXHAUST
else:
logger.log_error("Got wrong value {} for fan direction {}".format(fan_dir, self._index))
return FanBase.FAN_DIRECTION_NOT_APPLICABLE
except (ValueError, IOError) as e:
logger.log_error("Failed to read fan direction status to {}".format(repr(e)))
return FanBase.FAN_DIRECTION_NOT_APPLICABLE
from .fan import FAN_DIR, MlnxFan
return MlnxFan.get_fan_direction(FAN_DIR.format(self._index))

def set_status_led(self, color):
"""
Expand Down
11 changes: 9 additions & 2 deletions platform/mellanox/mlnx-platform-api/tests/test_fan_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
sys.path.insert(0, modules_path)

from sonic_platform import utils
from sonic_platform.fan import Fan, PsuFan
from sonic_platform.fan import Fan, PsuFan, FAN_DIR_VALUE_INTAKE, FAN_DIR_VALUE_EXHAUST
from sonic_platform.fan_drawer import RealDrawer, VirtualDrawer
from sonic_platform.psu import Psu

Expand Down Expand Up @@ -107,11 +107,12 @@ def test_system_fan_set_speed(self, mock_write_file):
fan.set_speed(60)
mock_write_file.assert_called_with(fan.fan_speed_set_path, 153, raise_exception=True)

@patch('sonic_platform.utils.read_int_from_file')
@patch('sonic_platform.thermal.Thermal.get_cooling_level')
@patch('sonic_platform.psu.Psu.get_presence')
@patch('sonic_platform.psu.Psu.get_powergood_status')
@patch('os.path.exists')
def test_psu_fan_basic(self, mock_path_exists, mock_powergood, mock_presence, mock_cooling_level):
def test_psu_fan_basic(self, mock_path_exists, mock_powergood, mock_presence, mock_cooling_level, mock_read_int):
mock_path_exists.return_value = False
psu = Psu(0)
fan = PsuFan(0, 1, psu)
Expand All @@ -126,6 +127,12 @@ def test_psu_fan_basic(self, mock_path_exists, mock_powergood, mock_presence, mo
assert fan.get_presence() is True
mock_cooling_level.return_value = 7
assert fan.get_target_speed() == 70
mock_read_int.return_value = FAN_DIR_VALUE_INTAKE
assert fan.get_direction() == Fan.FAN_DIRECTION_INTAKE
mock_read_int.return_value = FAN_DIR_VALUE_EXHAUST
assert fan.get_direction() == Fan.FAN_DIRECTION_EXHAUST
mock_read_int.return_value = -1 # invalid value
assert fan.get_direction() == Fan.FAN_DIRECTION_NOT_APPLICABLE

def test_psu_fan_set_speed(self):
psu = Psu(0)
Expand Down

0 comments on commit 26858ce

Please sign in to comment.