9
9
import os
10
10
import os .path
11
11
import glob
12
+ from collections import namedtuple
12
13
13
14
try :
14
15
from sonic_platform_base .thermal_base import ThermalBase
15
16
except ImportError as e :
16
17
raise ImportError (str (e ) + "- required module not found" )
17
18
19
+ Threshold = namedtuple ('Threshold' , ['high_crit' , 'high_err' , 'high_warn' ,
20
+ 'low_warn' , 'low_err' , 'low_crit' ], defaults = [0 ]* 6 )
21
+
18
22
PSU_I2C_PATH = "/sys/bus/i2c/devices/{}-00{}/"
19
23
PSU_HWMON_I2C_MAPPING = {
20
24
0 : {
38
42
},
39
43
}
40
44
41
- THERMAL_NAME_LIST = [ "CPU Board 0x4B" , "Main Board 0x4C" ,
42
- "Main Board 0x49" , "Main Board 0x4A" ]
43
-
44
- PSU_THERMAL_NAME_LIST = [ "PSU-1 temp sensor 1" , "PSU-2 temp sensor 1" ]
45
+ THERMAL_NAME_LIST = ( "CPU Board 0x4B" , "Main Board 0x4C" ,
46
+ "Main Board 0x49" , "Main Board 0x4A" )
47
+ CPU_THERMAL_NAME = "CPU Core temp"
48
+ PSU_THERMAL_NAME_LIST = ( "PSU-1 temp sensor 1" , "PSU-2 temp sensor 1" )
45
49
46
50
SYSFS_PATH = "/sys/bus/i2c/devices"
47
51
52
+ def is_fan_dir_F2B ():
53
+ from sonic_platform .platform import Platform
54
+ fan = Platform ().get_chassis ().get_fan (0 )
55
+ return fan .get_direction ().lower () == fan .FAN_DIRECTION_EXHAUST
56
+
57
+
48
58
class Thermal (ThermalBase ):
49
59
"""Platform-specific Thermal class"""
50
-
51
- def __init__ (self , thermal_index = 0 , is_psu = False , psu_index = 0 ):
60
+ THRESHOLDS_F2B = {
61
+ 0 : Threshold (70.0 , 65.0 , 65.0 ),
62
+ 1 : Threshold (67.0 , 62.0 , 62.0 ),
63
+ 2 : Threshold (58.0 , 53.0 , 53.0 ),
64
+ 3 : Threshold (61.0 , 56.0 , 56.0 ),
65
+ }
66
+ THRESHOLDS_B2F = {
67
+ 0 : Threshold (57.0 , 52.0 , 52.0 ),
68
+ 1 : Threshold (66.0 , 61.0 , 61.0 ),
69
+ 2 : Threshold (60.0 , 55.0 , 55.0 ),
70
+ 3 : Threshold (59.0 , 54.0 , 54.0 ),
71
+ }
72
+ THRESHOLDS = None
73
+
74
+ def __init__ (self , thermal_index = 0 , is_psu = False , psu_index = 0 , is_cpu = False ):
52
75
self .index = thermal_index
53
76
self .is_psu = is_psu
54
77
self .psu_index = psu_index
78
+ self .is_cpu = is_cpu
79
+
80
+ if self .is_cpu :
81
+ self .cpu_paths = glob .glob ('/sys/devices/platform/coretemp.0/hwmon/hwmon*/temp*_input' )
82
+ self .cpu_path_idx = 0
55
83
56
84
if self .is_psu :
57
85
psu_i2c_bus = PSU_HWMON_I2C_MAPPING [psu_index ]["num" ]
@@ -97,21 +125,39 @@ def __get_temp(self, temp_file):
97
125
else :
98
126
return 0
99
127
100
-
101
- def __set_threshold (self , file_name , temperature ):
102
- if self .is_psu :
103
- return True
104
- temp_file_path = os .path .join (self .hwmon_path , file_name )
105
- for filename in glob .glob (temp_file_path ):
106
- try :
107
- with open (filename , 'w' ) as fd :
108
- fd .write (str (temperature ))
109
- fd .flush ()
110
- return True
111
- except IOError as e :
112
- print ("IOError" )
113
- return False
114
-
128
+ def __get_max_temp (self , paths ):
129
+ max_temp = - 1.0
130
+ max_idx = 0
131
+ for i , path in enumerate (paths ):
132
+ read_temp = self .__get_temp (path )
133
+ if (read_temp > max_temp ):
134
+ max_temp = read_temp
135
+ max_idx = i
136
+ return max_temp , max_idx
137
+
138
+ def __get_cpu_threshold (self , type ):
139
+ path = self .cpu_paths [self .cpu_path_idx ]
140
+ high_warn = self .__get_temp (path .replace ('_input' , '_max' ))
141
+ if type == 'high_warn' :
142
+ return high_warn
143
+ high_crit = self .__get_temp (path .replace ('_input' , '_crit' ))
144
+ if type == 'high_crit' :
145
+ return high_crit
146
+ if type == 'high_err' :
147
+ return (high_crit + high_warn ) / 2
148
+ return 0
149
+
150
+ def __try_get_threshold (self , type ):
151
+ if self .THRESHOLDS is None :
152
+ self .THRESHOLDS = self .THRESHOLDS_F2B if is_fan_dir_F2B () else self .THRESHOLDS_B2F
153
+
154
+ if self .is_cpu :
155
+ return self .__get_cpu_threshold (type )
156
+
157
+ if self .is_psu == False and self .index in self .THRESHOLDS :
158
+ return getattr (self .THRESHOLDS [self .index ], type )
159
+ else :
160
+ return None
115
161
116
162
def get_temperature (self ):
117
163
"""
@@ -120,46 +166,25 @@ def get_temperature(self):
120
166
A float number of current temperature in Celsius up to nearest thousandth
121
167
of one degree Celsius, e.g. 30.125
122
168
"""
169
+ if self .is_cpu :
170
+ cpu_temp , self .cpu_path_idx = self .__get_max_temp (self .cpu_paths )
171
+ return cpu_temp
172
+
123
173
if not self .is_psu :
124
174
temp_file = "temp{}_input" .format (self .ss_index )
125
175
else :
126
176
temp_file = self .psu_hwmon_path + "psu_temp1_input"
127
- return self .__get_temp (temp_file )
128
-
129
- def get_high_threshold (self ):
130
- """
131
- Retrieves the high threshold temperature of thermal
132
- Returns:
133
- A float number, the high threshold temperature of thermal in Celsius
134
- up to nearest thousandth of one degree Celsius, e.g. 30.125
135
- """
136
- if self .is_psu :
137
- return 80
138
177
139
- temp_file = "temp{}_max" .format (self .ss_index )
140
178
return self .__get_temp (temp_file )
141
179
142
- def set_high_threshold (self , temperature ):
143
- """
144
- Sets the high threshold temperature of thermal
145
- Args :
146
- temperature: A float number up to nearest thousandth of one degree Celsius,
147
- e.g. 30.125
148
- Returns:
149
- A boolean, True if threshold is set successfully, False if not
150
- """
151
- temp_file = "temp{}_max" .format (self .ss_index )
152
- temperature = temperature * 1000
153
- self .__set_threshold (temp_file , temperature )
154
-
155
- return True
156
-
157
180
def get_name (self ):
158
181
"""
159
182
Retrieves the name of the thermal device
160
183
Returns:
161
184
string: The name of the thermal device
162
185
"""
186
+ if self .is_cpu :
187
+ return CPU_THERMAL_NAME
163
188
if self .is_psu :
164
189
return PSU_THERMAL_NAME_LIST [self .psu_index ]
165
190
else :
@@ -171,6 +196,8 @@ def get_presence(self):
171
196
Returns:
172
197
bool: True if Thermal is present, False if not
173
198
"""
199
+ if self .is_cpu :
200
+ return True
174
201
if self .is_psu :
175
202
val = self .__read_txt_file (self .cpld_path + "psu_present" )
176
203
return int (val , 10 ) == 1
@@ -188,6 +215,8 @@ def get_status(self):
188
215
Returns:
189
216
A boolean value, True if device is operating properly, False if not
190
217
"""
218
+ if self .is_cpu :
219
+ return True
191
220
if self .is_psu :
192
221
temp_file = self .psu_hwmon_path + "psu_temp_fault"
193
222
return self .get_presence () and (not int (
@@ -235,3 +264,20 @@ def is_replaceable(self):
235
264
"""
236
265
return False
237
266
267
+ def get_high_critical_threshold (self ):
268
+ return self .__try_get_threshold ('high_crit' )
269
+
270
+ def get_low_critical_threshold (self ):
271
+ return self .__try_get_threshold ('low_crit' )
272
+
273
+ def get_high_threshold (self ):
274
+ return self .__try_get_threshold ('high_err' )
275
+
276
+ def get_low_threshold (self ):
277
+ return self .__try_get_threshold ('low_err' )
278
+
279
+ def get_high_warning_threshold (self ):
280
+ return self .__try_get_threshold ('high_warn' )
281
+
282
+ def get_low_warning_threshold (self ):
283
+ return self .__try_get_threshold ('low_warn' )
0 commit comments