[Mellanox] add PSU fan direction support (#14508)
- 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
This commit is contained in:
parent
602b945f76
commit
7962a5c0fa
@ -31,6 +31,7 @@ try:
|
||||
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")
|
||||
|
||||
@ -45,7 +46,10 @@ CONFIG_PATH = "/var/run/hw-management/config"
|
||||
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):
|
||||
@ -125,6 +129,20 @@ class MlnxFan(FanBase):
|
||||
"""
|
||||
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
|
||||
@ -145,6 +163,7 @@ class PsuFan(MlnxFan):
|
||||
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):
|
||||
"""
|
||||
@ -165,8 +184,11 @@ class PsuFan(MlnxFan):
|
||||
1 stands for forward, in other words intake
|
||||
0 stands for reverse, in other words exhaust
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
Retrieves the operational status of fan
|
||||
@ -263,7 +285,10 @@ class Fan(MlnxFan):
|
||||
1 stands for forward, in other words intake
|
||||
0 stands for reverse, in other words exhaust
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
@ -58,19 +58,8 @@ class MellanoxFanDrawer(FanDrawerBase):
|
||||
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):
|
||||
"""
|
||||
|
@ -25,7 +25,7 @@ modules_path = os.path.dirname(test_path)
|
||||
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
|
||||
|
||||
@ -107,11 +107,12 @@ class TestFan:
|
||||
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)
|
||||
@ -126,6 +127,12 @@ class TestFan:
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user