diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py index ca0f3f9da1e..52889cd5895 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/fanutil.py @@ -1,26 +1,22 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 11/13/2017: Polly Hsu, Create -# 1/10/2018: Jostar modify for as7716_32 -# 12/03/2018: Jostar modify for as7726_32 +# 8/27/2019:Jostar craete for as9716_32d # ------------------------------------------------------------------ try: @@ -46,8 +42,8 @@ class FanUtil(object): FAN_NODE_FAULT_IDX_OF_MAP = 1 FAN_NODE_DIR_IDX_OF_MAP = 2 - BASE_VAL_PATH = '/sys/bus/i2c/devices/54-0066/{0}' - FAN_DUTY_PATH = '/sys/bus/i2c/devices/54-0066/fan_duty_cycle_percentage' + BASE_VAL_PATH = '/sys/bus/i2c/devices/17-0066/{0}' + FAN_DUTY_PATH = '/sys/bus/i2c/devices/17-0066/fan_duty_cycle_percentage' #logfile = '' #loglevel = logging.INFO @@ -56,14 +52,14 @@ class FanUtil(object): key1 = fan id index (integer) starting from 1 key2 = fan node index (interger) starting from 1 value = path to fan device file (string) """ - _fan_to_device_path_mapping = {} + _fan_device_path_mapping = {} #fan1_direction #fan1_fault #fan1_present #(FAN_NUM_2_IDX, FAN_NODE_DUTY_IDX_OF_MAP): 'fan2_duty_cycle_percentage', - _fan_to_device_node_mapping = { + _fan_device_node_mapping = { (FAN_NUM_1_IDX, FAN_NODE_FAULT_IDX_OF_MAP): 'fan1_fault', (FAN_NUM_1_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan1_direction', @@ -83,8 +79,8 @@ class FanUtil(object): (FAN_NUM_6_IDX, FAN_NODE_DIR_IDX_OF_MAP): 'fan6_direction', } - def _get_fan_to_device_node(self, fan_num, node_num): - return self._fan_to_device_node_mapping[(fan_num, node_num)] + def _get_fan_device_node(self, fan_num, node_num): + return self._fan_device_node_mapping[(fan_num, node_num)] def _get_fan_node_val(self, fan_num, node_num): if fan_num < self.FAN_NUM_1_IDX or fan_num > self.FAN_NUM_ON_MAIN_BROAD: @@ -95,7 +91,7 @@ def _get_fan_node_val(self, fan_num, node_num): logging.debug('GET. Parameter error. node_num:%d', node_num) return None - device_path = self.get_fan_to_device_path(fan_num, node_num) + device_path = self.get_fan_device_path(fan_num, node_num) try: val_file = open(device_path, 'r') @@ -131,7 +127,7 @@ def _set_fan_node_val(self, fan_num, node_num, val): logging.debug('GET. content is NULL. device_path:%s', device_path) return None - device_path = self.get_fan_to_device_path(fan_num, node_num) + device_path = self.get_fan_device_path(fan_num, node_num) try: val_file = open(device_path, 'w') except IOError as e: @@ -153,8 +149,8 @@ def __init__(self): for fan_num in range(self.FAN_NUM_1_IDX, self.FAN_NUM_ON_MAIN_BROAD+1): for node_num in range(self.FAN_NODE_FAULT_IDX_OF_MAP, self.FAN_NODE_NUM_OF_MAP+1): - self._fan_to_device_path_mapping[(fan_num, node_num)] = fan_path.format( - self._fan_to_device_node_mapping[(fan_num, node_num)]) + self._fan_device_path_mapping[(fan_num, node_num)] = fan_path.format( + self._fan_device_node_mapping[(fan_num, node_num)]) def get_num_fans(self): return self.FAN_NUM_ON_MAIN_BROAD @@ -169,20 +165,17 @@ def get_idx_node_start(self): return self.FAN_NODE_FAULT_IDX_OF_MAP def get_size_node_map(self): - return len(self._fan_to_device_node_mapping) + return len(self._fan_device_node_mapping) def get_size_path_map(self): - return len(self._fan_to_device_path_mapping) + return len(self._fan_device_path_mapping) - def get_fan_to_device_path(self, fan_num, node_num): - return self._fan_to_device_path_mapping[(fan_num, node_num)] + def get_fan_device_path(self, fan_num, node_num): + return self._fan_device_path_mapping[(fan_num, node_num)] def get_fan_fault(self, fan_num): return self._get_fan_node_val(fan_num, self.FAN_NODE_FAULT_IDX_OF_MAP) - #def get_fan_speed(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FAN_NODE_SPEED_IDX_OF_MAP) - def get_fan_dir(self, fan_num): return self._get_fan_node_val(fan_num, self.FAN_NODE_DIR_IDX_OF_MAP) @@ -198,28 +191,18 @@ def get_fan_duty_cycle(self): val_file.close() return int(content) - #self._get_fan_node_val(fan_num, self.FAN_NODE_DUTY_IDX_OF_MAP) -#static u32 reg_val_to_duty_cycle(u8 reg_val) -#{ -# reg_val &= FAN_DUTY_CYCLE_REG_MASK; -# return ((u32)(reg_val+1) * 625 + 75)/ 100; -#} -# + def set_fan_duty_cycle(self, val): - try: fan_file = open(self.FAN_DUTY_PATH, 'r+') except IOError as e: print "Error: unable to open file: %s" % str(e) return False - #val = ((val + 1 ) * 625 +75 ) / 100 + fan_file.write(str(val)) fan_file.close() return True - - #def get_fanr_fault(self, fan_num): - # return self._get_fan_node_val(fan_num, self.FANR_NODE_FAULT_IDX_OF_MAP) - + def get_fanr_speed(self, fan_num): return self._get_fan_node_val(fan_num, self.FANR_NODE_SPEED_IDX_OF_MAP) @@ -232,20 +215,4 @@ def get_fan_status(self, fan_num): logging.debug('GET. FAN fault. fan_num, %d', fan_num) return False - #if self.get_fanr_fault(fan_num) is not None and self.get_fanr_fault(fan_num) > 0: - # logging.debug('GET. FANR fault. fan_num, %d', fan_num) - # return False - - return True -#def main(): -# fan = FanUtil() -# -# print 'get_size_node_map : %d' % fan.get_size_node_map() -# print 'get_size_path_map : %d' % fan.get_size_path_map() -# for x in range(fan.get_idx_fan_start(), fan.get_num_fans()+1): -# for y in range(fan.get_idx_node_start(), fan.get_num_nodes()+1): -# print fan.get_fan_to_device_path(x, y) -# -#if __name__ == '__main__': -# main() diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py index 00c9950d52b..abbc5e819a8 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/classes/thermalutil.py @@ -1,24 +1,22 @@ #!/usr/bin/env python +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # ------------------------------------------------------------------ # HISTORY: # mm/dd/yyyy (A.D.) -# 12/18/2018:Jostar craete for as9716_32d +# 8/27/2019:Jostar craete for as9716_32d # ------------------------------------------------------------------ try: @@ -34,38 +32,29 @@ class ThermalUtil(object): """Platform-specific ThermalUtil class""" THERMAL_NUM_MAX = 8 - THERMAL_NUM_1_IDX = 1 # 1_ON_MAIN_BROAD. LM75 - THERMAL_NUM_2_IDX = 2 # 2_ON_MAIN_BROAD. LM75 - THERMAL_NUM_3_IDX = 3 # 3_ON_MAIN_BROAD. LM75 - THERMAL_NUM_4_IDX = 4 # 4_ON_MAIN_BROAD. LM75 - THERMAL_NUM_5_IDX = 5 # 5_ON_MAIN_BROAD. LM75 - THERMAL_NUM_6_IDX = 6 # 6_ON_MAIN_BROAD. LM75 - THERMAL_NUM_7_IDX = 7 # 7_ON_MAIN_BROAD. LM75 - THERMAL_NUM_8_IDX = 8 # 8_ON_MAIN_BROAD. LM75 - + THERMAL_NUM_1_IDX = 1 # 1~7 are mainboard thermal sensors + THERMAL_NUM_2_IDX = 2 + THERMAL_NUM_3_IDX = 3 + THERMAL_NUM_4_IDX = 4 + THERMAL_NUM_5_IDX = 5 + THERMAL_NUM_6_IDX = 6 + THERMAL_NUM_7_IDX = 7 # CPU core + THERMAL_NUM_8_IDX = 8 + """ Dictionary where key1 = thermal id index (integer) starting from 1 value = path to fan device file (string) """ #_thermal_to_device_path_mapping = {} - - _thermal_to_device_node_mapping = { - THERMAL_NUM_1_IDX: ['18', '48'], - THERMAL_NUM_2_IDX: ['18', '49'], - THERMAL_NUM_3_IDX: ['18', '4a'], - THERMAL_NUM_4_IDX: ['18', '4b'], - THERMAL_NUM_5_IDX: ['18', '4c'], - THERMAL_NUM_6_IDX: ['18', '4e'], - THERMAL_NUM_7_IDX: ['18', '4f'], - } + thermal_sysfspath ={ THERMAL_NUM_1_IDX: ["/sys/bus/i2c/devices/18-0048/hwmon/hwmon*/temp1_input"], THERMAL_NUM_2_IDX: ["/sys/bus/i2c/devices/18-0049/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/18-004a/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/18-004c/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_6_IDX: ["/sys/bus/i2c/devices/18-004e/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_7_IDX: ["/sys/bus/i2c/devices/18-004f/hwmon/hwmon*/temp1_input"], - THERMAL_NUM_8_IDX: ["/sys/class/hwmon/hwmon0/temp1_input"], + THERMAL_NUM_3_IDX: ["/sys/bus/i2c/devices/18-004a/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_4_IDX: ["/sys/bus/i2c/devices/18-004c/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_5_IDX: ["/sys/bus/i2c/devices/18-004e/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_6_IDX: ["/sys/bus/i2c/devices/18-004f/hwmon/hwmon*/temp1_input"], + THERMAL_NUM_7_IDX: ["/sys/class/hwmon/hwmon0/temp1_input"], + THERMAL_NUM_8_IDX: ["/sys/bus/i2c/devices/18-004b/hwmon/hwmon*/temp1_input"], } #def __init__(self): @@ -75,7 +64,7 @@ def _get_thermal_val(self, thermal_num): logging.debug('GET. Parameter error. thermal_num, %d', thermal_num) return None - device_path = self.get_thermal_to_device_path(thermal_num) + device_path = self.get_thermal_path(thermal_num) for filename in glob.glob(device_path): try: val_file = open(filename, 'r') @@ -97,39 +86,17 @@ def _get_thermal_val(self, thermal_num): return 0 def get_num_thermals(self): - return self.THERMAL_NUM_MAX - - def get_idx_thermal_start(self): - return self.THERMAL_NUM_1_IDX - - def get_size_node_map(self): - return len(self._thermal_to_device_node_mapping) + return self.THERMAL_NUM_MAX def get_size_path_map(self): return len(self.thermal_sysfspath) - def get_thermal_to_device_path(self, thermal_num): + def get_thermal_path(self, thermal_num): return self.thermal_sysfspath[thermal_num][0] - - def get_thermal_temp(self): - return (self._get_thermal_node_val(self.THERMAL_NUM_1_IDX) + self._get_thermal_node_val(self.THERMAL_NUM_2_IDX) +self._get_thermal_node_val(self.THERMAL_NUM_3_IDX)) + def main(): - thermal = ThermalUtil() - print "termal1=%d" %thermal._get_thermal_val(1) - print "termal2=%d" %thermal._get_thermal_val(2) - print "termal3=%d" %thermal._get_thermal_val(3) - print "termal4=%d" %thermal._get_thermal_val(4) - print "termal5=%d" %thermal._get_thermal_val(5) - print "termal7=%d" %thermal._get_thermal_val(6) - print "termal8=%d" %thermal._get_thermal_val(7) - print "termal9=%d" %thermal._get_thermal_val(8) - -# -# print 'get_size_node_map : %d' % thermal.get_size_node_map() -# print 'get_size_path_map : %d' % thermal.get_size_path_map() -# for x in range(thermal.get_idx_thermal_start(), thermal.get_num_thermals()+1): -# print thermal.get_thermal_to_device_path(x) -# + thermal = ThermalUtil() + if __name__ == '__main__': main() \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py index f80c1223a83..3752161d3eb 100755 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py @@ -1,28 +1,27 @@ #!/usr/bin/env python +# -*- coding: utf-8 -* +# Copyright (c) 2019 Edgecore Networks Corporation # -# Copyright (C) 2017 Accton Technology Corporation +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT +# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS +# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# ------------------------------------------------------------------ +# See the Apache Version 2.0 License for specific language governing +# permissions and limitations under the License. +# # HISTORY: # mm/dd/yyyy (A.D.)# -# 12/19/2018:Jostar create for as9716_32d thermal plan +# 8/27/2019:Jostar create for as9716_32d thermal plan # ------------------------------------------------------------------ try: import os + import commands import sys, getopt import subprocess import click @@ -41,31 +40,11 @@ # Deafults VERSION = '1.0' -FUNCTION_NAME = '/usr/local/bin/accton_as9716_32x_monitor' +FUNCTION_NAME = '/usr/local/bin/accton_as9716_32d_monitor' global log_file global log_level - -# Air Flow Front to Back : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=38C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 38C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 46C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 58C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 66C : Shut down system -# One Fan fail : Change Fan speed to 100%(0x0E) - - -# Air Flow Back to Front : -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 <=34C : Keep 37.5%(0x04) Fan speed -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 34C : Change Fan speed from 37.5%(0x04) to 62.5%(0x08) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 44C : Change Fan speed from 62.5%(0x08) to 100%(0x0E) -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 59C : Send alarm message -# (Thermal sensor_LM75_4A + Thermal sensor_LM75_CPU) /2 > 67C : Shut down system -# One Fan fail: Change Fan speed to 100%(0x0E) -# sensor_LM75_CPU == sensor_LM75_4B - - class switch(object): def __init__(self, value): self.value = value @@ -87,20 +66,217 @@ def match(self, *args): return False -fan_policy_state=1 + +# Read fanN_direction=1: The air flow of Fan6 is “AFI-Back to Front” +# 0: The air flow of Fan6 is “AFO-Front to back” +# +# Thermal policy: +# a.Defaut fan duty_cycle=100% +# b.One fan fail, set to fan duty_cycle=100% +# 1.For AFI: +# Default fan duty_cycle will be 100%(fan_policy_state=LEVEL_FAN_MAX). +# If all below case meet with, set to 75%(LEVEL_FAN_MID). +# MB board +# LM75-1(0X48)<=57 +# LM75-2(0X49)<=47.3 +# LM75-3(0X4A)<=45 +# LM75-4(0X4C)<=45.1 +# LM75-5(0X4E)<=40.75 +# LM75-6(0X4F)<=42.1 +# CPU board +# Core<=44 +# LM75-1(0X4B)<=35 + +# When fan_policy_state=LEVEL_FAN_MID, meet with below case, Fan duty_cycle will be 100%(LEVEL_FAN_DAX) +# (MB board) +# LM75-1(0X48)>=61.5 +# LM75-2(0X49)>=51.5 +# LM75-3(0X4A)>=49.4 +# LM75-4(0X4C)>=49.4 +# LM75-5(0X4E)>=45.1 +# LM75-6(0X4F)>=46.75 +# (CPU board) +# Core>=48 +# LM75-1(0X4B)>=38.5 + +# 2. For AFO: +# At default, FAN duty_cycle was 100%(LEVEL_FAN_MAX). If all below case meet with, set to 75%(LEVEL_FAN_MID). +# (MB board) +# LM75-1(0X48)<=59 +# LM75-2(0X49)<=53.5 +# LM75-3(0X4A)<=55.3 +# LM75-4(0X4C)<=50.3 +# LM75-5(0X4E)<=50 +# LM75-6(0X4F)<=52.5 +# (CPU board) +# Core<=59 +# LM75-1(0X4B)<=41.1 + +# When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 50%(LEVEL_FAN_DEF). +# (MB board) +# LM75-1(0X48)<=55.8 +# LM75-2(0X49)<=50.5 +# LM75-3(0X4A)<=51.1 +# LM75-4(0X4C)<=47.6 +# LM75-5(0X4E)<=45.75 +# LM75-6(0X4F)<=50.1 +# (CPU board) +# Core<=57 +# LM75-1(0X4B)<=36.6 + +# When fan_speed 50%(LEVEL_FAN_DEF). +# Meet with below case, Fan duty_cycle will be 75%(LEVEL_FAN_MID) +# (MB board) +# LM75-1(0X48)>=70 +# LM75-2(0X49)>=66 +# LM75-3(0X4A)>=68 +# LM75-4(0X4C)>=62 +# LM75-5(0X4E)>=62 +# LM75-6(0X4F)>=67 +# (CPU board) +# Core>=77 +# LM75-1(0X4B)>=50 + +# When FAN duty_cycle was 75%(LEVEL_FAN_MID). If all below case meet with, set to 100%(LEVEL_FAN_MAX). +# (MB board) +# LM75-1(0X48)>=67 +# LM75-2(0X49)>=62.5 +# LM75-3(0X4A)>=65 +# LM75-4(0X4C)>=59 +# LM75-5(0X4E)>=58.5 +# LM75-6(0X4F)>=63 + +# (CPU board) +# Core >=69 +# LM75-1(0X4B)>=49 + + +#Yellow Alarm +#MB board +#LM75-1(0X48)>=68 +#LM75-2(0X49)>=64 +#LM75-3(0X4A)>=65 +#LM75-4(0X4C)>=61 +#LM75-5(0X4E)>=60 +#LM75-6(0X4F)>=64 +#CPU Board +#Core>=70 +#LM75-1(0X4B)>=68 + +#Red Alarm +#MB board +#LM75-1(0X48)>=72 +#LM75-2(0X49)>=68 +#LM75-3(0X4A)>=69 +#LM75-4(0X4C)>=65 +#LM75-5(0X4E)>=64 +#LM75-6(0X4F)>=68 +#CPU Board +#Core>=74 +#LM75-1(0X4B)>=72 + +#Shut down +#MB board +#LM75-1(0X48)>=77 +#LM75-2(0X49)>=73 +#LM75-3(0X4A)>=74 +#LM75-4(0X4C)>=70 +#LM75-5(0X4E)>=69 +#LM75-6(0X4F)>=73 +#CPU Board +#Core>=79 +#LM75-1(0X4B)>=77 + + + +def power_off_dut(): + cmd_str="i2cset -y -f 19 0x60 0x60 0x10" + status, output = commands.getstatusoutput(cmd_str) + return status + +#If only one PSU insert(or one of PSU pwoer fail), and watt >800w. Must let DUT fan pwm >= 75% in AFO. +#Because the psu temp is high. +# Return 1: full load +# Return 0: Not full load +def check_psu_loading(): + psu_power_status=[1, 1] + + psu_power_good = { + 2: "/sys/bus/i2c/devices/10-0051/psu_power_good", + 1: "/sys/bus/i2c/devices/9-0050/psu_power_good", + } + psu_power_in = { + 2: "/sys/bus/i2c/devices/10-0059/psu_p_in", + 1: "/sys/bus/i2c/devices/9-0058/psu_p_in", + } + psu_power_out = { + 2: "/sys/bus/i2c/devices/10-0059/psu_p_out", + 1: "/sys/bus/i2c/devices/9-0058/psu_p_out", + } + + check_psu_watt=0 + for i in range(1,3): + node = psu_power_good[i] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return None + + psu_power_status[i-1]=int(status) + if status==0: + check_psu_watt=1 + + if check_psu_watt: + for i in range(1,3): + if psu_power_status[i-1]==1: + #check watt + node = psu_power_in[i] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return None + + psu_p_in= int(status) + if psu_p_in/1000 > 800: + return True + + node = psu_power_out[i] + try: + with open(node, 'r') as power_status: + status = int(power_status.read()) + except IOError: + return None + psu_p_out= int(status) + if psu_p_out/1000 > 800: + return True + else: + return False + + + return False + +fan_policy_state=0 +fan_policy_alarm=0 +send_yellow_alarm=0 +send_red_alarm=0 fan_fail=0 -alarm_state = 0 #0->default or clear, 1-->alarm detect +count_check=0 + test_temp = 0 -test_temp_list = [0, 0, 0, 0, 0, 0] +test_temp_list = [0, 0, 0, 0, 0, 0, 0, 0] temp_test_data=0 +test_temp_revert=0 + # Make a class we can use to capture stdout and sterr in the log class device_monitor(object): # static temp var temp = 0 - new_pwm = 0 - pwm=0 - ori_pwm = 0 - default_pwm=0x4 + new_duty_cycle = 0 + duty_cycle=0 + ori_duty_cycle = 0 + def __init__(self, log_file, log_level): """Needs a logger and a logger level.""" @@ -123,179 +299,197 @@ def __init__(self, log_file, log_level): sys_handler = handler = logging.handlers.SysLogHandler(address = '/dev/log') sys_handler.setLevel(logging.WARNING) logging.getLogger('').addHandler(sys_handler) - #logging.debug('SET. logfile:%s / loglevel:%d', log_file, log_level) - def get_state_from_fan_policy(self, temp, policy): - state=0 - - logging.debug('temp=%d', temp) - for i in range(0, len(policy)): - #logging.debug('policy[%d][0]=%d, policy[%d][1]=%d, policy[%d][2]=%d', i,policy[i][0],i, policy[i][1], i, policy[i][2]) - if temp > policy[i][2]: - if temp <= policy[i][3]: - state =i - logging.debug ('temp=%d >= policy[%d][2]=%d, temp=%d < policy[%d][3]=%d' , temp, i, policy[i][2], temp, i, policy[i][3]) - logging.debug ('fan_state=%d', state) - break - - return state - def manage_fans(self): global fan_policy_state + global fan_policy_alarm + global send_yellow_alarm + global send_red_alarm global fan_fail + global count_check global test_temp - global test_temp_list - global alarm_state + global test_temp_list global temp_test_data - - LEVEL_FAN_DEF=0 - LEVEL_FAN_MID=1 - LEVEL_FAN_MAX=2 - LEVEL_TEMP_HIGH=3 - LEVEL_TEMP_CRITICAL=4 - - - fan_policy_f2b = { - LEVEL_FAN_DEF: [38, 0x4, 0, 38000], - LEVEL_FAN_MID: [63, 0x6, 38000, 46000], - LEVEL_FAN_MAX: [100, 0xE, 46000, 58000], - LEVEL_TEMP_HIGH: [100, 0xE, 58000, 66000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 58000, 200000], + global test_temp_revert + + CHECK_TIMES=3 + + LEVEL_FAN_INIT=0 + LEVEL_FAN_MIN=1 + LEVEL_FAN_MID=2 + LEVEL_FAN_MAX=3 + LEVEL_FAN_DEF=LEVEL_FAN_MAX + LEVEL_FAN_YELLOW_ALARM=4 + LEVEL_FAN_RED_ALARM=5 + LEVEL_FAN_SHUTDOWN=6 + + fan_policy_f2b = { #AFO + LEVEL_FAN_MIN: [50, 0x7], + LEVEL_FAN_MID: [75, 0xb], + LEVEL_FAN_MAX: [100, 0xf] + } + fan_policy_b2f = { #AFI + LEVEL_FAN_MID: [75, 0xb], + LEVEL_FAN_MAX: [100, 0xf] } - fan_policy_b2f = { - LEVEL_FAN_DEF: [38, 0x4, 0, 34000], - LEVEL_FAN_MID: [63, 0x8, 34000, 44000], - LEVEL_FAN_MAX: [100, 0xE, 44000, 59000], - LEVEL_TEMP_HIGH: [100, 0xE, 59000, 67000], - LEVEL_TEMP_CRITICAL: [100, 0xE, 59000, 200000], + + afi_thermal_spec={ + "mid_to_max_temp":[61500, 51500, 49400, 49400, 45100, 46750, 48000, 38500], + "max_to_mid_temp":[57000, 47300, 45000, 45100, 40750, 42100, 44000, 35000] } + afo_thermal_spec={ + "min_to_mid_temp": [70000, 66000, 68000, 62000, 62000, 67000, 77000, 50000], + "mid_to_max_temp": [67000, 62000, 65000, 59000, 58500, 63000, 69000, 49000], + "max_to_mid_temp": [59000, 53500, 55300, 50300, 50000, 52500, 59000, 41100], + "mid_to_min_temp": [55800, 50500, 51100, 47600, 45750, 50100, 57000, 36600], + "max_to_yellow_alarm": [68000, 64000, 65000, 61000, 60000, 64000, 70000, 68000], + "yellow_to_red_alarm": [72000, 68000, 69000, 65000, 64000, 68000, 74000, 72000], + "red_alarm_to_shutdown": [77000, 73000, 74000, 70000, 69000, 73000, 79000, 77000] + } + + thermal_val=[0,0,0,0,0,0,0,0] + max_to_mid=0 + mid_to_min=0 - fan_policy = fan_policy_f2b + fan = FanUtil() + if fan_policy_state==LEVEL_FAN_INIT: + fan_policy_state=LEVEL_FAN_MAX #This is default state + logging.debug("fan_policy_state=LEVEL_FAN_MAX") + return + + count_check=count_check+1 + if count_check < CHECK_TIMES: + return + else: + count_check=0 thermal = ThermalUtil() - fan = FanUtil() - fan_dir=fan.get_fan_dir(1) - if fan_dir == 1: - fan_dri=1 #something wrong, set fan_dir to default val + fan_dir=1 + fan_dir=fan.get_fan_dir(1) + + if fan_dir==1: # AFI + fan_thermal_spec = afi_thermal_spec + fan_policy=fan_policy_b2f + elif fan_dir==0: # AFO + fan_thermal_spec = afo_thermal_spec + fan_policy=fan_policy_f2b else: - fan_policy = fan_policy_b2f + logging.debug( "NULL case") - ori_pwm=fan.get_fan_duty_cycle() - new_pwm=0 - logging.debug('fan_dir=%d, ori_pwm=%d', fan_dir, ori_pwm) - logging.debug('test_temp=%d', test_temp) - if test_temp==0: - temp1 = thermal._get_thermal_val(1) - temp2 = thermal._get_thermal_val(2) - temp3 = thermal._get_thermal_val(3) - temp4 = thermal._get_thermal_val(4) - temp5 = thermal._get_thermal_val(5) + ori_duty_cycle=fan.get_fan_duty_cycle() + new_duty_cycle=0 + + if test_temp_revert==0: + temp_test_data=temp_test_data+2000 + else: + temp_test_data=temp_test_data-2000 + + if test_temp==0: + for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1): + thermal_val[i-1]=thermal._get_thermal_val(i) else: - temp1 = test_temp_list[0] - temp2 = test_temp_list[1] - temp3 = test_temp_list[2] - temp4 = test_temp_list[3] - temp5 = test_temp_list[4] + for i in range (thermal.THERMAL_NUM_1_IDX, thermal.THERMAL_NUM_MAX+1): + thermal_val[i-1]=test_temp_list[i-1] + thermal_val[i-1]= thermal_val[i-1] + temp_test_data + fan_fail=0 - if temp3==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_49 detect fail, so set temp_get=50000, let fan to 75%') - elif temp4==0: - temp_get=50000 # if one detect sensor is fail or zero, assign temp=50000, let fan to 75% - logging.debug('lm75_4b detect fail, so set temp_get=50000, let fan to 75%') - else: - temp_get= (temp3 + temp4)/2 # Use (sensor_LM75_4a + sensor_LM75_4b) /2 - ori_state=fan_policy_state - - #temp_test_data=temp_test_data+1000 - #temp_get = temp_get + temp_test_data - #print "Unit test:temp_get=%d"%temp_get + ori_state=fan_policy_state; + current_state=fan_policy_state; + + if fan_dir==1: #AFI + for i in range (0, thermal.THERMAL_NUM_MAX): + if ori_state==LEVEL_FAN_MID: + if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]: + current_state=LEVEL_FAN_MAX + logging.debug("current_state=LEVEL_FAN_MAX") + break + else: + if (thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i]): + max_to_mid=max_to_mid+1 - fan_policy_state=self.get_state_from_fan_policy(temp_get, fan_policy) - #print "temp3=%d"%temp3 - #print "temp4=%d"%temp4 - #print "temp_get=%d"%temp_get + if max_to_mid==thermal.THERMAL_NUM_MAX and fan_policy_state==LEVEL_FAN_MAX: + current_state=LEVEL_FAN_MID + logging.debug("current_state=LEVEL_FAN_MID") + else: #AFO + psu_full_load=check_psu_loading() + for i in range (0, thermal.THERMAL_NUM_MAX): + if ori_state==LEVEL_FAN_MID: + if thermal_val[i] >= fan_thermal_spec["mid_to_max_temp"][i]: + current_state=LEVEL_FAN_MAX + break + else: + if psu_full_load!=True and thermal_val[i] <= fan_thermal_spec["mid_to_min_temp"][i]: + mid_to_min=mid_to_min+1 + elif ori_state==LEVEL_FAN_MIN: + if psu_full_load==True: + current_state=LEVEL_FAN_MID + logging.debug("psu_full_load, set current_state=LEVEL_FAN_MID") + if thermal_val[i] >= fan_thermal_spec["min_to_mid_temp"][i]: + current_state=LEVEL_FAN_MID + + else: + if thermal_val[i] <= fan_thermal_spec["max_to_mid_temp"][i] : + max_to_mid=max_to_mid+1 + if fan_policy_alarm==0: + if thermal_val[i] >= fan_thermal_spec["max_to_yellow_alarm"][i]: + if send_yellow_alarm==0: + logging.warning('Alarm-Yellow for temperature high is detected') + fan_policy_alarm=LEVEL_FAN_YELLOW_ALARM + send_yellow_alarm=1 + elif fan_policy_alarm==LEVEL_FAN_YELLOW_ALARM: + if thermal_val[i] >= fan_thermal_spec["yellow_to_red_alarm"][i]: + if send_red_alarm==0: + logging.warning('Alarm-Red for temperature high is detected') + fan_policy_alarm=LEVEL_FAN_RED_ALARM + send_red_alarm=1 + elif fan_policy_alarm==LEVEL_FAN_RED_ALARM: + if thermal_val[i] >= fan_thermal_spec["red_alarm_to_shutdown"][i]: + logging.critical('Alarm-Critical for temperature high is detected, shutdown DUT') + fan_policy_alarm=LEVEL_FAN_SHUTDOWN + time.sleep(2) + power_off_dut() - logging.debug('lm75_48=%d, lm75_49=%d, lm75_4a=%d, lm_4b=%d, lm_4b=%d', temp1,temp2,temp3,temp4,temp5) - logging.debug('ori_state=%d, fan_policy_state=%d', ori_state, fan_policy_state) - new_pwm = fan_policy[fan_policy_state][0] - if fan_fail==0: - logging.debug('new_fan_cycle=%d', new_pwm) - - if fan_fail==0: - if new_pwm!=ori_pwm: - fan.set_fan_duty_cycle(new_pwm) - logging.info('Set fan speed from %d to %d', ori_pwm, new_pwm) - + if max_to_mid==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MAX: + current_state=LEVEL_FAN_MID + if fan_policy_alarm!=0: + logging.warning('Alarm for temperature high is cleared') + fan_policy_alarm=0 + send_yellow_alarm=0 + send_red_alarm=0 + test_temp_revert=0 + logging.debug("current_state=LEVEL_FAN_MID") + + if mid_to_min==thermal.THERMAL_NUM_MAX and ori_state==LEVEL_FAN_MID: + if psu_full_load==0: + current_state=LEVEL_FAN_MIN + logging.debug("current_state=LEVEL_FAN_MIN") + #Check Fan status for i in range (fan.FAN_NUM_1_IDX, fan.FAN_NUM_ON_MAIN_BROAD+1): if fan.get_fan_status(i)==0: - new_pwm=100 - logging.debug('fan_%d fail, set pwm to 100',i) + new_duty_cycle=100 + logging.debug('fan_%d fail, set duty_cycle to 100',i) if test_temp==0: fan_fail=1 - fan.set_fan_duty_cycle(new_pwm) + fan.set_fan_duty_cycle(new_duty_cycle) break else: fan_fail=0 - - #if fan_policy_state == ori_state: - # return True - #else: - new_state = fan_policy_state - - #logging.warning('Temperature high alarm testing') - if ori_state==LEVEL_FAN_DEF: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected, reboot DUT') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MID: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if ori_state==LEVEL_FAN_MAX: - if new_state==LEVEL_TEMP_HIGH: - if alarm_state==0: - logging.warning('Alarm for temperature high is detected') - alarm_state=1 - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if alarm_state==1: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_HIGH: - if new_state==LEVEL_TEMP_CRITICAL: - logging.critical('Alarm for temperature critical is detected') - time.sleep(2) - os.system('reboot') - if new_state <= LEVEL_FAN_MID: - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if new_state <= LEVEL_FAN_MAX: - if temp_get < (fan_policy[3][0] - 5000): #below 65 C, clear alarm - logging.warning('Alarm for temperature high is cleared') - alarm_state=0 - if ori_state==LEVEL_TEMP_CRITICAL: - if new_state <= LEVEL_FAN_MAX: - logging.warning('Alarm for temperature critical is cleared') - + + if current_state!=ori_state: + fan_policy_state=current_state + new_duty_cycle=fan_policy[current_state][0] + logging.debug("fan_policy_state=%d, new_duty_cycle=%d", fan_policy_state, new_duty_cycle) + if new_duty_cycle!=ori_duty_cycle and fan_fail==0: + fan.set_fan_duty_cycle(new_duty_cycle) + return True + if new_duty_cycle==0 and fan_fail==0: + fan.set_fan_duty_cycle(FAN_DUTY_CYCLE_MAX) + return True def main(argv): @@ -318,26 +512,25 @@ def main(argv): log_file = arg if sys.argv[1]== '-t': - if len(sys.argv)!=7: - print "temp test, need input six temp" + if len(sys.argv)!=10: + print "temp test, need input 8 temp" return 0 - i=0 - for x in range(2, 7): + for x in range(2, 10): test_temp_list[i]= int(sys.argv[x])*1000 i=i+1 - test_temp = 1 + test_temp = 1 log_level = logging.DEBUG - print test_temp_list + print test_temp_list fan = FanUtil() - fan.set_fan_duty_cycle(38) - print "set default fan speed to 37.5%" + fan.set_fan_duty_cycle(100) monitor = device_monitor(log_file, log_level) # Loop forever, doing something useful hopefully: while True: - #monitor.manage_fans() - time.sleep(5) + monitor.manage_fans() + time.sleep(10) + if __name__ == '__main__': main(sys.argv[1:])