blob: 8e21a6e6bd768c1afa1871b90d44cbacf663ae43 [file] [log] [blame]
Brad Bishop179b39b2016-05-12 16:45:57 -04001# Contributors Listed Below - COPYRIGHT 2016
2# [+] International Business Machines Corp.
3#
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14# implied. See the License for the specific language governing
15# permissions and limitations under the License.
16
17import os
18import subprocess
19import dbus
20import dbus.service
21from obmc.dbuslib.bindings import DbusProperties
22
23
24## Abstract class, must subclass
25class SensorValue(DbusProperties):
26 IFACE_NAME = 'org.openbmc.SensorValue'
27
28 def __init__(self, bus, name):
29 self.Set(SensorValue.IFACE_NAME, 'units', "")
30 self.Set(SensorValue.IFACE_NAME, 'error', False)
31
32 @dbus.service.method(
33 IFACE_NAME, in_signature='v', out_signature='')
34 def setValue(self, value):
35 self.Set(SensorValue.IFACE_NAME, 'value', value)
36
37 @dbus.service.method(
38 IFACE_NAME, in_signature='', out_signature='v')
39 def getValue(self):
40 return self.Get(SensorValue.IFACE_NAME, 'value')
41
42
43class SensorThresholds(DbusProperties):
44 IFACE_NAME = 'org.openbmc.SensorThresholds'
45
46 def __init__(self, bus, name):
47 self.Set(
48 SensorThresholds.IFACE_NAME,
49 'thresholds_enabled',
50 False)
51 self.Set(
52 SensorThresholds.IFACE_NAME,
53 'emergency_enabled',
54 False)
55 self.Set(
56 SensorThresholds.IFACE_NAME,
57 'warning_upper',
58 0)
59 self.Set(
60 SensorThresholds.IFACE_NAME,
61 'warning_lower',
62 0)
63 self.Set(
64 SensorThresholds.IFACE_NAME,
65 'critical_upper',
66 0)
67 self.Set(
68 SensorThresholds.IFACE_NAME,
69 'critical_lower',
70 0)
71 self.Set(
72 SensorThresholds.IFACE_NAME,
73 'critical_lower',
74 0)
75 self.Set(
76 SensorThresholds.IFACE_NAME,
77 'threshold_state',
78 "NORMAL")
79 self.Set(
80 SensorThresholds.IFACE_NAME,
81 'worst_threshold_state',
82 "NORMAL")
83
84 @dbus.service.method(
85 IFACE_NAME, in_signature='', out_signature='')
86 def resetThresholdState(self):
87 self.Set(
88 SensorThresholds.IFACE_NAME,
89 'worst_threshold_state',
90 "NORMAL")
91
92 def check_thresholds(self, value):
93 iface = SensorThresholds.IFACE_NAME
94 if (self.Get(iface, 'thresholds_enabled') is False):
95 return False
96 rtn = False
97 current_state = "NORMAL"
98 if (value >= self.properties[iface]['critical_upper']):
99 current_state = "CRITICAL"
100 rtn = True
101 elif (value <= self.properties[iface]['critical_lower']):
102 current_state = "CRITICAL"
103 rtn = True
104 elif (value >= self.properties[iface]['warning_upper']):
105 current_state = "WARNING"
106 rtn = True
107 elif (value <= self.properties[iface]['warning_lower']):
108 current_state = "WARNING"
109 rtn = True
110
111 if self.Get(iface, 'threshold_state') != current_state and \
112 current_state == "CRITICAL" and \
113 self.Get(iface, 'emergency_enabled') is True:
Yi Li3cb85e92016-07-01 16:47:16 +0800114 message = type(self).__name__ + \
115 ' SensorThresholds.check_thresholds(): trigger emergency' + \
116 ' signal, sensor value: ' + str(value)
117 self.Emergency(message)
Brad Bishop179b39b2016-05-12 16:45:57 -0400118
119 self.Set(iface, 'threshold_state', current_state)
120 worst = self.properties[iface]['worst_threshold_state']
121 if (current_state == "CRITICAL" or
122 (current_state == "WARNING" and worst != "CRITICAL")):
123 self.Set(iface, 'worst_threshold_state', current_state)
124
125 return rtn
126
Yi Li3cb85e92016-07-01 16:47:16 +0800127 @dbus.service.signal(IFACE_NAME, signature='s')
128 def Emergency(self, message):
Brad Bishop179b39b2016-05-12 16:45:57 -0400129 pass
130
131
132class VirtualSensor(SensorValue):
133 def __init__(self, bus, name):
134 DbusProperties.__init__(self)
135 SensorValue.__init__(self, bus, name)
136 dbus.service.Object.__init__(self, bus, name)
137
138
139class HwmonSensor(SensorValue, SensorThresholds):
140 IFACE_NAME = 'org.openbmc.HwmonSensor'
141
142 def __init__(self, bus, name):
143 DbusProperties.__init__(self)
144 SensorValue.__init__(self, bus, name)
145 SensorThresholds.__init__(self, bus, name)
146 self.Set(HwmonSensor.IFACE_NAME, 'scale', 1)
147 self.Set(HwmonSensor.IFACE_NAME, 'offset', 0)
148 self.Set(HwmonSensor.IFACE_NAME, 'filename', '')
149 self.value_dirty = False
150
151 # need to cache value to know if changed
152 self.value = None
153 dbus.service.Object.__init__(self, bus, name)
154
155 @dbus.service.method(
156 SensorValue.IFACE_NAME, in_signature='v', out_signature='')
157 def setValue(self, value):
158 self.value_dirty = True
159 SensorValue.setValue(self, value)
160
161 ## Called by sensor process to update value from polling
162 ## if returns not None, then sensor process will update hwmon value
163 @dbus.service.method(
164 IFACE_NAME, in_signature='v', out_signature='(bv)')
165 def setByPoll(self, value):
166 scale = self.properties[HwmonSensor.IFACE_NAME]['scale']
167 offset = self.properties[HwmonSensor.IFACE_NAME]['offset']
Edward A. Jamesecf8bd82016-08-15 16:22:25 -0500168 try:
169 adjust = self.properties[HwmonSensor.IFACE_NAME]['adjust']
170 if adjust == 0:
171 adjust = 1
172 except:
173 adjust = 1
174
Brad Bishop179b39b2016-05-12 16:45:57 -0400175 if self.value_dirty:
176 ## new value externally set, so just return to hwmon
177 ## process to write value
178 self.value_dirty = False
Edward A. Jamesecf8bd82016-08-15 16:22:25 -0500179 val = int((
Brad Bishop179b39b2016-05-12 16:45:57 -0400180 self.properties[SensorValue.IFACE_NAME]['value']
Edward A. Jamesecf8bd82016-08-15 16:22:25 -0500181 - offset) * adjust)
Brad Bishop179b39b2016-05-12 16:45:57 -0400182 return [True, val]
183 else:
Edward A. Jamesecf8bd82016-08-15 16:22:25 -0500184 # Keep the val as integer. adjust may be floating point
185 val = int(value/adjust + offset)
Brad Bishop179b39b2016-05-12 16:45:57 -0400186 if (val != self.value):
187 SensorValue.setValue(self, val)
Edward A. Jamesecf8bd82016-08-15 16:22:25 -0500188 # scale the value to check threshold
189 self.check_thresholds(val * (10 ** scale))
Brad Bishop179b39b2016-05-12 16:45:57 -0400190 self.value = val
191
192 return [False, 0]
193
194
195CONTROL_IFACE = 'org.openbmc.Control'
196
197
198class PowerCap(VirtualSensor):
199 def __init__(self, bus, name):
200 VirtualSensor.__init__(self, bus, name)
201 SensorValue.setValue(self, 0)
Brad Bishop179b39b2016-05-12 16:45:57 -0400202
203 ##override setValue method
204 @dbus.service.method(
205 SensorValue.IFACE_NAME, in_signature='v', out_signature='')
206 def setValue(self, value):
Jayanth Othayoth0a3eeb82017-04-18 06:13:34 -0500207 raise Exception("ERROR: Setting Power Cap is not allowed")
Brad Bishop179b39b2016-05-12 16:45:57 -0400208
209class BootProgressSensor(VirtualSensor):
210 def __init__(self, bus, name):
211 VirtualSensor.__init__(self, bus, name)
212 self.setValue("Off")
213 bus.add_signal_receiver(
214 self.SystemStateHandler, signal_name="GotoSystemState")
215
216 def SystemStateHandler(self, state):
217 if (state == "HOST_POWERED_OFF"):
218 self.setValue("Off")
219
220 ##override setValue method
221 @dbus.service.method(
222 SensorValue.IFACE_NAME,
223 in_signature='v', out_signature='')
224 def setValue(self, value):
225 SensorValue.setValue(self, value)
226 if (value == "FW Progress, Starting OS"):
227 self.GotoSystemState("HOST_BOOTED")
Yi Li57e3bf92016-09-08 17:58:00 +0800228 self.BootProgress(value)
Brad Bishop179b39b2016-05-12 16:45:57 -0400229
230 @dbus.service.signal(CONTROL_IFACE, signature='s')
231 def GotoSystemState(self, state):
232 pass
233
Yi Li57e3bf92016-09-08 17:58:00 +0800234 @dbus.service.signal(CONTROL_IFACE, signature='s')
235 def BootProgress(self, state):
236 pass
237
Brad Bishop179b39b2016-05-12 16:45:57 -0400238
239class OccStatusSensor(VirtualSensor):
240 def __init__(self, bus, name, sysfs=None):
241 ## default path. can be override
242 if sysfs is None:
243 self.sysfs_attr = "/sys/class/i2c-adapter/i2c-3/3-0050/online"
244 else:
245 self.sysfs_attr = sysfs
246 VirtualSensor.__init__(self, bus, name)
247 self.setValue("Disabled")
248 bus.add_signal_receiver(
249 self.SystemStateHandler, signal_name="GotoSystemState")
250
251 def SystemStateHandler(self, state):
252 if (state == "HOST_POWERED_OFF"):
253 self.setValue("Disabled")
254
255 ##override setValue method
256 @dbus.service.method(
257 SensorValue.IFACE_NAME, in_signature='v', out_signature='')
258 def setValue(self, value):
259 if (value == "Enabled"):
260 print "Installing OCC device"
261 os.system("echo 1 > " + self.sysfs_attr)
262 else:
263 print "Deleting OCC device"
264 os.system("echo 0 > " + self.sysfs_attr)
265 SensorValue.setValue(self, value)
266
267 @dbus.service.signal(CONTROL_IFACE, signature='s')
268 def GotoSystemState(self, state):
269 pass
270
271
272class BootCountSensor(VirtualSensor):
273 def __init__(self, bus, name):
274 VirtualSensor.__init__(self, bus, name)
Andrew Geissler9070d1b2017-05-22 14:46:34 -0500275 # Default boot count is 2. Add 1 onto this to allow for an
276 # SBE side switch boot attempt
277 self.setValue(3)
278
279 ## override setValue method for debug purposes
280 @dbus.service.method(
281 SensorValue.IFACE_NAME, in_signature='v', out_signature='')
282 def setValue(self, value):
283 print "Setting boot count to " + str(value)
284 SensorValue.setValue(self,value)
Brad Bishop179b39b2016-05-12 16:45:57 -0400285
286
287class OperatingSystemStatusSensor(VirtualSensor):
288 def __init__(self, bus, name):
289 VirtualSensor.__init__(self, bus, name)
290 self.setValue("Off")
291 bus.add_signal_receiver(
292 self.SystemStateHandler, signal_name="GotoSystemState")
293
294 def SystemStateHandler(self, state):
295 if (state == "HOST_POWERED_OFF"):
296 self.setValue("Off")
Dhruvaraj Sdc0dc122017-03-21 02:13:29 -0500297
298class PowerSupplyRedundancySensor(VirtualSensor):
299 def __init__(self, bus, name):
300 VirtualSensor.__init__(self, bus, name)
Dhruvaraj Subhashchandran93daccf2017-03-28 04:02:53 -0500301 super(PowerSupplyRedundancySensor,self).setValue("Disabled")
Dhruvaraj Sdc0dc122017-03-21 02:13:29 -0500302
303 ## override setValue method
304 @dbus.service.method(
305 SensorValue.IFACE_NAME, in_signature='v', out_signature='')
306 def setValue(self, value):
307 print "Setting Power Supply Redundancy is not allowed"
Jayanth Othayoth7a57f952017-03-28 07:15:29 -0500308
Jayanth Othayoth857e4b82017-03-27 08:25:45 -0500309class PowerSupplyDeratingSensor(VirtualSensor):
310 def __init__(self, bus, name):
311 VirtualSensor.__init__(self, bus, name)
312 super(PowerSupplyDeratingSensor,self).setValue(10)
313
314 ## override setValue method
315 @dbus.service.method(
316 SensorValue.IFACE_NAME, in_signature='v', out_signature='')
317 def setValue(self, value):
318 print "Setting Power Supply Derating is not allowed"
319
Jayanth Othayoth7a57f952017-03-28 07:15:29 -0500320class TurboAllowedSensor(VirtualSensor):
321 def __init__(self, bus, name):
322 VirtualSensor.__init__(self, bus, name)
323 self.setValue(0)
324
325 ## override setValue method
326 @dbus.service.method(
327 SensorValue.IFACE_NAME, in_signature='b', out_signature='')
328 def setValue(self, value):
329 super(TurboAllowedSensor,self).setValue(value)