blob: d31eed317eaee942d9e500b2efe3f6d7b2289a7c [file] [log] [blame]
Norman James323ed972015-12-09 09:06:37 -06001#!/usr/bin/python -u
2
3import sys
4#from gi.repository import GObject
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import os
10import Openbmc
11
12## Abstract class, must subclass
13class SensorValue(Openbmc.DbusProperties):
14 IFACE_NAME = 'org.openbmc.SensorValue'
15 def __init__(self,bus,name):
16 #Openbmc.DbusProperties.__init__(self)
17 self.Set(SensorValue.IFACE_NAME,'units',"")
18 self.Set(SensorValue.IFACE_NAME,'error',False)
19
20 @dbus.service.method(IFACE_NAME,
21 in_signature='v', out_signature='')
22 def setValue(self,value):
23 self.Set(SensorValue.IFACE_NAME,'value',value)
24
25 @dbus.service.method(IFACE_NAME,
26 in_signature='', out_signature='v')
27 def getValue(self):
28 return self.Get(SensorValue.IFACE_NAME,'value')
29
30class SensorThresholds(Openbmc.DbusProperties):
31 IFACE_NAME = 'org.openbmc.SensorThresholds'
32 def __init__(self,bus,name):
33 self.Set(SensorThresholds.IFACE_NAME,'thresholds_enabled',False)
Norman James72567ba2016-01-13 16:57:48 -060034 self.Set(SensorThresholds.IFACE_NAME,'emergency_enabled',False)
Norman James323ed972015-12-09 09:06:37 -060035 self.Set(SensorThresholds.IFACE_NAME,'warning_upper',0)
36 self.Set(SensorThresholds.IFACE_NAME,'warning_lower',0)
37 self.Set(SensorThresholds.IFACE_NAME,'critical_upper',0)
38 self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
39 self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
40 self.Set(SensorThresholds.IFACE_NAME,'threshold_state',"NORMAL")
41 self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
42
43 @dbus.service.method(IFACE_NAME,
44 in_signature='', out_signature='')
45 def resetThresholdState(self):
46 self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
47
48 def check_thresholds(self,value):
49 iface = SensorThresholds.IFACE_NAME
50 if (self.Get(iface,'thresholds_enabled') == False):
51 return False
52 rtn = False
53 current_state = "NORMAL"
54 if (value >= self.properties[iface]['critical_upper']):
55 current_state = "CRITICAL"
Norman James323ed972015-12-09 09:06:37 -060056 rtn = True
Norman James72567ba2016-01-13 16:57:48 -060057 elif (value <= self.properties[iface]['critical_lower']):
58 current_state = "CRITICAL"
59 rtn = True
60 elif (value >= self.properties[iface]['warning_upper']):
61 current_state = "WARNING"
62 rtn = True
63 elif (value <= self.properties[iface]['warning_lower']):
64 current_state = "WARNING"
65 rtn = True
66
67 if (self.Get(iface,'threshold_state') != current_state and
68 current_state == "CRITICAL" and
69 self.Get(iface,'emergency_enabled') == True):
70 self.Emergency()
71
Norman James323ed972015-12-09 09:06:37 -060072 self.Set(iface,'threshold_state',current_state)
73 worst = self.properties[iface]['worst_threshold_state']
74 if (current_state == "CRITICAL" or
75 (current_state == "WARNING" and worst != "CRITICAL")):
76 self.Set(iface,'worst_threshold_state',current_state)
77
78 return rtn
79
Norman James72567ba2016-01-13 16:57:48 -060080 @dbus.service.signal(IFACE_NAME,signature='')
81 def Emergency(self):
82 pass
83
84
Norman James323ed972015-12-09 09:06:37 -060085class VirtualSensor(SensorValue):
86 def __init__(self,bus,name):
87 Openbmc.DbusProperties.__init__(self)
88 SensorValue.__init__(self,bus,name)
89 dbus.service.Object.__init__(self,bus,name)
90
91class HwmonSensor(SensorValue,SensorThresholds):
92 IFACE_NAME = 'org.openbmc.HwmonSensor'
93 def __init__(self,bus,name):
94 Openbmc.DbusProperties.__init__(self)
95 SensorValue.__init__(self,bus,name)
96 SensorThresholds.__init__(self,bus,name)
97 self.Set(HwmonSensor.IFACE_NAME,'scale',1)
98 self.Set(HwmonSensor.IFACE_NAME,'offset',0)
99 self.Set(HwmonSensor.IFACE_NAME,'filename','')
100 self.value_dirty = False
101
102 # need to cache value to know if changed
103 self.value = None
104 dbus.service.Object.__init__(self,bus,name)
105
106 @dbus.service.method(SensorValue.IFACE_NAME,
107 in_signature='v', out_signature='')
108 def setValue(self,value):
109 self.value_dirty = True
110 SensorValue.setValue(self,value)
111
112 ## Called by sensor process to update value from polling
113 ## if returns not None, then sensor process will update hwmon value
114 @dbus.service.method(IFACE_NAME,
115 in_signature='v', out_signature='(bv)')
116 def setByPoll(self,value):
117 scale = self.properties[HwmonSensor.IFACE_NAME]['scale']
118 offset = self.properties[HwmonSensor.IFACE_NAME]['offset']
119 if (self.value_dirty == True):
120 ## new value externally set, so just return to hwmon
121 ## process to write value
122 self.value_dirty = False
123 val = (self.properties[SensorValue.IFACE_NAME]['value']-offset) * scale
124 return [True,val]
125 else:
126 val = (value/scale) + offset
127 if (val != self.value):
128 SensorValue.setValue(self,val)
129 self.check_thresholds(val)
130 self.value = val
131
132 return [False,0]
133
134CONTROL_IFACE = 'org.openbmc.Control'
Chris Austen4c9ea5d2015-12-09 23:26:08 -0600135class PowerCap(VirtualSensor):
Norman James323ed972015-12-09 09:06:37 -0600136 def __init__(self,bus,name):
137 VirtualSensor.__init__(self,bus,name)
Chris Austen4c9ea5d2015-12-09 23:26:08 -0600138 self.setValue(100)
Norman James323ed972015-12-09 09:06:37 -0600139
Norman James323ed972015-12-09 09:06:37 -0600140
141class BootProgressSensor(VirtualSensor):
142 def __init__(self,bus,name):
143 VirtualSensor.__init__(self,bus,name)
144 self.setValue("Off")
145 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
146
147 def SystemStateHandler(self,state):
148 if (state == "HOST_POWERED_OFF"):
149 self.setValue("Off")
150
151
152 ##override setValue method
153 @dbus.service.method(SensorValue.IFACE_NAME,
154 in_signature='v', out_signature='')
155 def setValue(self,value):
156 SensorValue.setValue(self,value)
157 if (value == "FW Progress, Starting OS"):
158 self.GotoSystemState("HOST_BOOTED")
159
160 @dbus.service.signal(CONTROL_IFACE,signature='s')
161 def GotoSystemState(self,state):
162 pass
163
164class OccStatusSensor(VirtualSensor):
165 def __init__(self,bus,name):
Yi Li99ed56f2016-01-20 13:39:15 +0800166 ## default path. can be override
167 self.sysfs_attr = "/sys/class/i2c-adapter/i2c-3/3-0050/online"
Norman James323ed972015-12-09 09:06:37 -0600168 VirtualSensor.__init__(self,bus,name)
169 self.setValue("Disabled")
170 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
171
172 def SystemStateHandler(self,state):
173 if (state == "HOST_POWERED_OFF"):
174 self.setValue("Disabled")
Norman James323ed972015-12-09 09:06:37 -0600175
176 ##override setValue method
177 @dbus.service.method(SensorValue.IFACE_NAME,
178 in_signature='v', out_signature='')
179 def setValue(self,value):
180 if (value == "Enabled"):
181 print "Installing OCC device"
Yi Li99ed56f2016-01-20 13:39:15 +0800182 os.system("echo 1 > " + self.sysfs_attr)
Norman James323ed972015-12-09 09:06:37 -0600183 else:
184 print "Deleting OCC device"
Yi Li99ed56f2016-01-20 13:39:15 +0800185 os.system("echo 0 > " + self.sysfs_attr)
Norman James323ed972015-12-09 09:06:37 -0600186 SensorValue.setValue(self,value)
187
188 @dbus.service.signal(CONTROL_IFACE,signature='s')
189 def GotoSystemState(self,state):
190 pass
191
192class BootCountSensor(VirtualSensor):
193 def __init__(self,bus,name):
194 VirtualSensor.__init__(self,bus,name)
Chris Austen4c9ea5d2015-12-09 23:26:08 -0600195 self.setValue(2)
Norman James323ed972015-12-09 09:06:37 -0600196
197class OperatingSystemStatusSensor(VirtualSensor):
198 def __init__(self,bus,name):
199 VirtualSensor.__init__(self,bus,name)
200 self.setValue("Off")
Chris Austenc0448f02016-01-12 16:01:30 -0600201 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
Norman James323ed972015-12-09 09:06:37 -0600202
Chris Austenc0448f02016-01-12 16:01:30 -0600203 def SystemStateHandler(self,state):
204 if (state == "HOST_POWERED_OFF"):
205 self.setValue("Off")