157 lines
5.4 KiB
Python
157 lines
5.4 KiB
Python
|
#!/usr/bin/env python
|
||
|
#############################################################################
|
||
|
# Dell
|
||
|
#
|
||
|
# Module contains an implementation of SONiC FAN Base API and
|
||
|
# provides various info about the FANs which are available in the platform
|
||
|
#
|
||
|
#############################################################################
|
||
|
import logging
|
||
|
import commands
|
||
|
|
||
|
try:
|
||
|
from sonic_fan.fan_base import FanBase
|
||
|
except ImportError as e:
|
||
|
raise ImportError (str(e) + "- required module not found")
|
||
|
|
||
|
class FanUtil(FanBase):
|
||
|
"""Platform-specific FANutil class"""
|
||
|
FANTRAY_NUM_ON_MAIN_BOARD = 7
|
||
|
NUM_FANS_PERTRAY = 2
|
||
|
FANTRAY_NUM_START_IDX = 1
|
||
|
FRU_FAN_START_IDX = 1
|
||
|
IPMI_FAN_PRESENCE = "ipmitool sensor get FAN{0}_prsnt"
|
||
|
IPMI_FAN_FRONT_SPEED = "ipmitool sdr get Fan{0}_Front_rpm"
|
||
|
IPMI_FAN_REAR_SPEED = "ipmitool sdr get Fan{0}_Rear_rpm"
|
||
|
IPMI_FRU_DATA = "ipmitool fru print {0}"
|
||
|
|
||
|
def __init__(self, log_level=logging.DEBUG):
|
||
|
FanBase.__init__(self)
|
||
|
self.num_fans = (self.FANTRAY_NUM_ON_MAIN_BOARD*self.NUM_FANS_PERTRAY)
|
||
|
|
||
|
def get_fan_status(self,fan_id):
|
||
|
try:
|
||
|
ret_status, ipmi_cmd_ret = commands.getstatusoutput(self.IPMI_FAN_PRESENCE.format(fan_id))
|
||
|
if ret_status == 0:
|
||
|
return(ipmi_cmd_ret.splitlines()[5].strip(' ').strip('[]'))
|
||
|
except Exception:
|
||
|
logging.error('Failed to execute : %s'%self.IPMI_FAN_PRESENCE.format(fan_id))
|
||
|
|
||
|
def get_front_fan_speed(self,fan_id):
|
||
|
try:
|
||
|
ret_status, ipmi_cmd_ret = commands.getstatusoutput(self.IPMI_FAN_FRONT_SPEED.format(fan_id))
|
||
|
if ret_status == 0:
|
||
|
rdata = ipmi_cmd_ret.splitlines()[3].split(':')[1].split(' ')[1]
|
||
|
return rdata
|
||
|
except Exception:
|
||
|
logging.error('Failed to execute : %s'%self.IPMI_FAN_FRONT_SPEED.format(fan_id))
|
||
|
|
||
|
def get_rear_fan_speed(self,fan_id):
|
||
|
try:
|
||
|
ret_status, ipmi_cmd_ret = commands.getstatusoutput(self.IPMI_FAN_REAR_SPEED.format(fan_id))
|
||
|
if ret_status == 0:
|
||
|
rdata = ipmi_cmd_ret.splitlines()[3].split(':')[1].split(' ')[1]
|
||
|
return rdata
|
||
|
|
||
|
except Exception:
|
||
|
logging.error('Failed to execute : %s'%self.IPMI_FAN_REAR_SPEED.format(fan_id))
|
||
|
|
||
|
|
||
|
# Read FAN FRU info
|
||
|
def get_fan_direction_from_fru(self,fru_id,reg_name):
|
||
|
output = None
|
||
|
try:
|
||
|
status, ipmi_fru_list = commands.getstatusoutput(self.IPMI_FRU_DATA.format(fru_id))
|
||
|
if status == 0:
|
||
|
for item in ipmi_fru_list.split("\n"):
|
||
|
if reg_name in item:
|
||
|
output = item.strip()
|
||
|
if output is None:
|
||
|
logging.error('\nFailed to fetch: ' + reg_name + ' sensor ')
|
||
|
output = output.split(':')[1].strip(' ')
|
||
|
if output == 'F2B' or output == 'B2F':
|
||
|
return output
|
||
|
except Exception:
|
||
|
logging.error('Failed to execute:' + ipmi_fru_list)
|
||
|
|
||
|
def get_num_fans(self):
|
||
|
return self.num_fans
|
||
|
|
||
|
def get_presence(self, index):
|
||
|
if index is None:
|
||
|
return False
|
||
|
|
||
|
if index < self.FANTRAY_NUM_START_IDX or index > self.FANTRAY_NUM_START_IDX + self.num_fans - 1:
|
||
|
logging.error('Invalid FAN index:%d', index)
|
||
|
return False
|
||
|
|
||
|
tray_index = ((index-1)/self.NUM_FANS_PERTRAY) + 1
|
||
|
|
||
|
if (self.get_fan_status(tray_index) == 'Device Present'):
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
|
||
|
def get_status(self, index):
|
||
|
if index is None:
|
||
|
return False
|
||
|
|
||
|
if index < self.FANTRAY_NUM_START_IDX or index > self.FANTRAY_NUM_START_IDX + self.num_fans - 1:
|
||
|
logging.error('Invalid FAN index:%d', index)
|
||
|
return False
|
||
|
|
||
|
tray_index = ((index-1)/self.NUM_FANS_PERTRAY) + 1
|
||
|
fantray_front_speed=self.get_front_fan_speed(tray_index)
|
||
|
fantray_rear_speed=self.get_rear_fan_speed(tray_index)
|
||
|
|
||
|
if (fantray_front_speed != '0' and fantray_rear_speed != '0'):
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
|
||
|
|
||
|
def get_direction(self, index):
|
||
|
if index is None:
|
||
|
return None
|
||
|
|
||
|
if index < self.FANTRAY_NUM_START_IDX or index > self.FANTRAY_NUM_START_IDX + self.num_fans - 1:
|
||
|
logging.error('Invalid FAN index:%d', index)
|
||
|
return None
|
||
|
|
||
|
tray_index = ((index-1)/self.NUM_FANS_PERTRAY)
|
||
|
fru_id = self.FRU_FAN_START_IDX + tray_index
|
||
|
direction = self.get_fan_direction_from_fru(fru_id,'Board Extra')
|
||
|
|
||
|
if direction == 'B2F':
|
||
|
return "INTAKE"
|
||
|
elif direction == 'F2B':
|
||
|
return "EXHAUST"
|
||
|
else:
|
||
|
return None
|
||
|
|
||
|
|
||
|
def get_speed(self, index):
|
||
|
if index is None:
|
||
|
return 0
|
||
|
|
||
|
if index < self.FANTRAY_NUM_START_IDX or index > self.FANTRAY_NUM_START_IDX + self.num_fans - 1:
|
||
|
logging.error('Invalid FAN index:%d', index)
|
||
|
return 0
|
||
|
|
||
|
tray_index = ((index-1)/self.NUM_FANS_PERTRAY) + 1
|
||
|
|
||
|
if (index % 2 != 0):
|
||
|
fantray_speed=self.get_front_fan_speed(tray_index)
|
||
|
else:
|
||
|
fantray_speed=self.get_rear_fan_speed(tray_index)
|
||
|
|
||
|
if (self.get_presence(index) == True):
|
||
|
return int(fantray_speed.strip())
|
||
|
else:
|
||
|
return 0
|
||
|
|
||
|
def set_speed(self, val):
|
||
|
logging.error("Not allowed to set fan speed!")
|
||
|
|
||
|
return False
|