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

Update AS7816-64X thermal policy according to new spec #9356

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,18 @@ class Thermal(PddfThermal):

def __init__(self, index, pddf_data=None, pddf_plugin_data=None):
PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data)
self.__index = index + 1

# Provide the functions/variables below for which implementation is to be overwritten

def get_position_in_parent(self):
"""
Retrieves 1-based relative physical position in parent device.
If the agent cannot determine the parent-relative position
for some reason, or if the associated value of
entPhysicalContainedIn is'0', then the value '-1' is returned
Returns:
integer: The 1-based relative physical position in parent device
or -1 if cannot determine the position
"""
return self.__index
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,70 @@
import logging.config
import time # this is only being used as part of the example
import signal
from sonic_platform import platform
from sonic_platform import platform, fan
from collections import namedtuple
except ImportError as e:
raise ImportError('%s - required module not found' % str(e))

# Deafults
VERSION = '1.0'
FUNCTION_NAME = 'accton_as7816_monitor'
DUTY_MAX = 100
DUTY_DEF = 40

FANDUTY_BY_LEVEL={
'LV_5' : DUTY_DEF,
'LV_7' : 52,
'LV_9' : 64,
'LV_B' : 76,
'LV_D' : 88,
'LV_F' : DUTY_MAX,
}
FANLEVEL_BY_DUTY={
DUTY_DEF : 'LV_5',
52 : 'LV_7',
64 : 'LV_9',
76 : 'LV_B',
88 : 'LV_D',
DUTY_MAX : 'LV_F',
}

NA_L = 0
NA_H = 999999
Threshold = namedtuple('Threshold', ['val', 'next_lv'])

UP_TH_F2B = { #order :0x4D,0x4E,0x48,0x49,0x4A,0x4B
'LV_5': Threshold([36000,38000,57000,60000,40000,39000], 'LV_7'),
'LV_7': Threshold([43000,44000,62000,64000,46000,45000], 'LV_B'),
'LV_9': Threshold([ NA_L, NA_L, NA_L, NA_L, NA_L, NA_L], 'LV_B'), # NA, force to change level.
'LV_B': Threshold([48000,49000, NA_H, NA_H,51000,49000], 'LV_D'),
'LV_D': Threshold([53000,54000,67000,70000,55000,54000], 'LV_F'),
'LV_F': Threshold([ NA_H, NA_H, NA_H, NA_H, NA_H, NA_H], 'LV_F') # Won't go any higher.
}
DOWN_TH_F2B = {
'LV_5': Threshold([ NA_L, NA_L, NA_L, NA_L, NA_L, NA_L], 'LV_5'), # Won't go any lower.
'LV_7': Threshold([34000,36000,55000,58000,38000,37000], 'LV_5'),
'LV_9': Threshold([ NA_H, NA_H, NA_H, NA_H, NA_H, NA_H], 'LV_7'), # NA, force to change level.
'LV_B': Threshold([40000,41000,60000,62000,43000,42000], 'LV_7'),
'LV_D': Threshold([46000,47000,65000,68000,49000,47000], 'LV_B'),
'LV_F': Threshold([51000,52000, NA_H, NA_H,53000,52000], 'LV_D')
}
UP_TH_B2F = {
'LV_5': Threshold([26000,26000,52000,41000,34000,27000], 'LV_7'),
'LV_7': Threshold([31000,31000, NA_H, NA_H,38000,32000], 'LV_9'),
'LV_9': Threshold([37000,36000,57000,48000,42000,37000], 'LV_B'),
'LV_B': Threshold([42000,42000,61000,52000,46000,42000], 'LV_D'),
'LV_D': Threshold([47000,47000,66000,57000,51000,47000], 'LV_F'),
'LV_F': Threshold([ NA_H, NA_H, NA_H, NA_H, NA_H, NA_H], 'LV_F') # Won't go any higher.
}
DOWN_TH_B2F = {
'LV_5': Threshold([NA_L,NA_L,NA_L,NA_L,NA_L,NA_L], 'LV_5'), # Won't go any lower.
'LV_7': Threshold([24000,24000,50000,39000,32000,25000], 'LV_5'),
'LV_9': Threshold([29000,29000,55000,45000,36000,30000], 'LV_7'),
'LV_B': Threshold([34000,34000, NA_H, NA_H,40000,35000], 'LV_9'),
'LV_D': Threshold([40000,40000,59000,50000,44000,40000], 'LV_B'),
'LV_F': Threshold([45000,45000,63000,55000,48000,45000], 'LV_D')
}

platform_chassis = None
THERMAL_NUM_ON_MAIN_BROAD = 6
Expand All @@ -48,35 +104,26 @@
temp_test_data = 0


def get_thermal_avg_temp():
global platform_chassis
def get_temperature(thermal):
global test_temp_list
global test_temp
global temp_test_data
global test_temp_revert
sum_temp = 0

if test_temp == 0:
for x in range(THERMAL_NUM_ON_MAIN_BROAD):
sum_temp = sum_temp + platform_chassis.get_thermal(x).get_temperature()*1000

else:
for x in range(THERMAL_NUM_ON_MAIN_BROAD):
sum_temp = sum_temp + test_temp_list[x]
return thermal.get_temperature() * 1000

avg = sum_temp/THERMAL_NUM_ON_MAIN_BROAD
idx = thermal.get_position_in_parent() - 1
temp = test_temp_list[idx] + temp_test_data

if test_temp == 1:
if idx == THERMAL_NUM_ON_MAIN_BROAD - 1:
if test_temp_revert == 0:
temp_test_data = temp_test_data+2000
else:
temp_test_data = temp_test_data-2000

avg = avg + temp_test_data

avg = (avg/1000)*1000 # round down for hysteresis.

return avg
temp = (temp/1000)*1000
logging.debug('set test temp %d to thermal%d', temp, idx)
return temp


# Make a class we can use to capture stdout and sterr in the log
Expand All @@ -85,10 +132,16 @@ class accton_as7816_monitor(object):
_ori_temp = 0
_new_perc = 0
_ori_perc = 0
THERMAL_NUM_ON_MAIN_BROAD = 6

def __init__(self, log_file, log_level):
"""Needs a logger and a logger level."""
global platform_chassis
self.thermals = platform_chassis.get_all_thermals()
self.fans = platform_chassis.get_all_fans()
self.is_fan_f2b = self.fans[0].get_direction().lower() == fan.Fan.FAN_DIRECTION_EXHAUST
self.up_th = UP_TH_F2B if self.is_fan_f2b == True else UP_TH_B2F
self.down_th = DOWN_TH_F2B if self.is_fan_f2b == True else DOWN_TH_B2F

# set up logging to file
logging.basicConfig(
filename=log_file,
Expand All @@ -109,46 +162,48 @@ def __init__(self, log_file, log_level):
logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level)

def manage_fans(self):
global platform_chassis
FAN_NUM = 2
FAN_TRAY_NUM = 4
max_duty = DUTY_MAX
fan_policy = {
0: [52, 0, 43000],
1: [63, 43000, 46000],
2: [75, 46000, 52000],
3: [88, 52000, 57000],
4: [max_duty, 57000, 100000],
}

for x in range(FAN_TRAY_NUM * FAN_NUM):
if not platform_chassis.get_fan(x).get_status() or not platform_chassis.get_fan(x).get_speed_rpm():
logging.debug('INFO. SET new_perc to %d (FAN stauts is None/Fault. fan_num:%d)', max_duty, x+1)
platform_chassis.get_fan(0).set_speed(max_duty)
if not self.fans[x].get_status() or not self.fans[x].get_speed_rpm():
logging.debug('INFO. SET new_perc to %d (FAN stauts is None/Fault. fan_num:%d)', DUTY_MAX, x+1)
self.fans[0].set_speed(DUTY_MAX)
return True

# Find if current duty matched any of define duty.
# If not, set it to highest one.
#cur_duty_cycle = fan.get_fan_duty_cycle()
cur_duty_cycle = platform_chassis.get_fan(0).get_speed()
new_duty_cycle = cur_duty_cycle
for x in range(0, len(fan_policy)):
if cur_duty_cycle == fan_policy[x][0]:
cur_duty_cycle = self.fans[0].get_speed()
fanlevel = FANLEVEL_BY_DUTY.get(cur_duty_cycle, 'LV_F')

# decide target level by thermal sensor input.
can_level_up = False
can_level_down = True
for thermal in self.thermals:
temp = get_temperature(thermal)
th_idx= thermal.get_position_in_parent() - 1
high = self.up_th[fanlevel].val[th_idx]
low = self.down_th[fanlevel].val[th_idx]
# perform level up if anyone is higher than high_th.
if temp >= high:
can_level_up = True
break
if x == len(fan_policy):
platform_chassis.get_fan(0).set_speed(fan_policy[0][0])
cur_duty_cycle = max_duty

# Decide fan duty by if avg of sensors falls into any of fan_policy{}
get_temp = get_thermal_avg_temp()
# cancel level down if anyone is higher than low_th.
if temp > low:
can_level_down = False

if can_level_up:
next_fanlevel = self.up_th[fanlevel].next_lv
elif can_level_down:
next_fanlevel = self.down_th[fanlevel].next_lv
else:
next_fanlevel = fanlevel
new_duty_cycle = FANDUTY_BY_LEVEL.get(next_fanlevel, DUTY_MAX)

for x in range(0, len(fan_policy)):
y = len(fan_policy) - x - 1 # checked from highest
if get_temp > fan_policy[y][1] and get_temp < fan_policy[y][2]:
new_duty_cycle = fan_policy[y][0]

if(new_duty_cycle != cur_duty_cycle):
platform_chassis.get_fan(0).set_speed(new_duty_cycle)
logging.debug(f'set fanduty from {cur_duty_cycle} to {new_duty_cycle}')
self.fans[0].set_speed(new_duty_cycle)
return True


Expand Down