blob: ecdac9110f07dcd5a011d0e55fc92449cb48f7cf [file] [log] [blame]
Norman James323ed972015-12-09 09:06:37 -06001#!/usr/bin/python -u
2
3import sys
Yi Lif3be5ac2016-01-19 21:17:01 +08004import subprocess
Norman James323ed972015-12-09 09:06:37 -06005#from gi.repository import GObject
6import gobject
7import dbus
8import dbus.service
9import dbus.mainloop.glib
10import os
11import Openbmc
12
13## Abstract class, must subclass
14class SensorValue(Openbmc.DbusProperties):
15 IFACE_NAME = 'org.openbmc.SensorValue'
16 def __init__(self,bus,name):
17 #Openbmc.DbusProperties.__init__(self)
18 self.Set(SensorValue.IFACE_NAME,'units',"")
19 self.Set(SensorValue.IFACE_NAME,'error',False)
20
21 @dbus.service.method(IFACE_NAME,
22 in_signature='v', out_signature='')
23 def setValue(self,value):
24 self.Set(SensorValue.IFACE_NAME,'value',value)
25
26 @dbus.service.method(IFACE_NAME,
27 in_signature='', out_signature='v')
28 def getValue(self):
29 return self.Get(SensorValue.IFACE_NAME,'value')
30
31class SensorThresholds(Openbmc.DbusProperties):
32 IFACE_NAME = 'org.openbmc.SensorThresholds'
33 def __init__(self,bus,name):
34 self.Set(SensorThresholds.IFACE_NAME,'thresholds_enabled',False)
Norman James72567ba2016-01-13 16:57:48 -060035 self.Set(SensorThresholds.IFACE_NAME,'emergency_enabled',False)
Norman James323ed972015-12-09 09:06:37 -060036 self.Set(SensorThresholds.IFACE_NAME,'warning_upper',0)
37 self.Set(SensorThresholds.IFACE_NAME,'warning_lower',0)
38 self.Set(SensorThresholds.IFACE_NAME,'critical_upper',0)
39 self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
40 self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
41 self.Set(SensorThresholds.IFACE_NAME,'threshold_state',"NORMAL")
42 self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
43
44 @dbus.service.method(IFACE_NAME,
45 in_signature='', out_signature='')
46 def resetThresholdState(self):
47 self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
48
49 def check_thresholds(self,value):
50 iface = SensorThresholds.IFACE_NAME
51 if (self.Get(iface,'thresholds_enabled') == False):
52 return False
53 rtn = False
54 current_state = "NORMAL"
55 if (value >= self.properties[iface]['critical_upper']):
56 current_state = "CRITICAL"
Norman James323ed972015-12-09 09:06:37 -060057 rtn = True
Norman James72567ba2016-01-13 16:57:48 -060058 elif (value <= self.properties[iface]['critical_lower']):
59 current_state = "CRITICAL"
60 rtn = True
61 elif (value >= self.properties[iface]['warning_upper']):
62 current_state = "WARNING"
63 rtn = True
64 elif (value <= self.properties[iface]['warning_lower']):
65 current_state = "WARNING"
66 rtn = True
67
68 if (self.Get(iface,'threshold_state') != current_state and
69 current_state == "CRITICAL" and
70 self.Get(iface,'emergency_enabled') == True):
71 self.Emergency()
72
Norman James323ed972015-12-09 09:06:37 -060073 self.Set(iface,'threshold_state',current_state)
74 worst = self.properties[iface]['worst_threshold_state']
75 if (current_state == "CRITICAL" or
76 (current_state == "WARNING" and worst != "CRITICAL")):
77 self.Set(iface,'worst_threshold_state',current_state)
78
79 return rtn
80
Norman James72567ba2016-01-13 16:57:48 -060081 @dbus.service.signal(IFACE_NAME,signature='')
82 def Emergency(self):
83 pass
84
85
Norman James323ed972015-12-09 09:06:37 -060086class VirtualSensor(SensorValue):
87 def __init__(self,bus,name):
88 Openbmc.DbusProperties.__init__(self)
89 SensorValue.__init__(self,bus,name)
90 dbus.service.Object.__init__(self,bus,name)
91
92class HwmonSensor(SensorValue,SensorThresholds):
93 IFACE_NAME = 'org.openbmc.HwmonSensor'
94 def __init__(self,bus,name):
95 Openbmc.DbusProperties.__init__(self)
96 SensorValue.__init__(self,bus,name)
97 SensorThresholds.__init__(self,bus,name)
98 self.Set(HwmonSensor.IFACE_NAME,'scale',1)
99 self.Set(HwmonSensor.IFACE_NAME,'offset',0)
100 self.Set(HwmonSensor.IFACE_NAME,'filename','')
101 self.value_dirty = False
102
103 # need to cache value to know if changed
104 self.value = None
105 dbus.service.Object.__init__(self,bus,name)
106
107 @dbus.service.method(SensorValue.IFACE_NAME,
108 in_signature='v', out_signature='')
109 def setValue(self,value):
110 self.value_dirty = True
111 SensorValue.setValue(self,value)
112
113 ## Called by sensor process to update value from polling
114 ## if returns not None, then sensor process will update hwmon value
115 @dbus.service.method(IFACE_NAME,
116 in_signature='v', out_signature='(bv)')
117 def setByPoll(self,value):
118 scale = self.properties[HwmonSensor.IFACE_NAME]['scale']
119 offset = self.properties[HwmonSensor.IFACE_NAME]['offset']
120 if (self.value_dirty == True):
121 ## new value externally set, so just return to hwmon
122 ## process to write value
123 self.value_dirty = False
124 val = (self.properties[SensorValue.IFACE_NAME]['value']-offset) * scale
125 return [True,val]
126 else:
Yi Lia8260c82016-03-16 14:37:57 +0800127 # Keep the val as integer. scale may be floating point
128 val = int(value/scale + offset)
Norman James323ed972015-12-09 09:06:37 -0600129 if (val != self.value):
130 SensorValue.setValue(self,val)
131 self.check_thresholds(val)
132 self.value = val
133
134 return [False,0]
135
136CONTROL_IFACE = 'org.openbmc.Control'
Chris Austen4c9ea5d2015-12-09 23:26:08 -0600137class PowerCap(VirtualSensor):
Yi Lif3be5ac2016-01-19 21:17:01 +0800138 def __init__(self, bus, name):
139 VirtualSensor.__init__(self, bus, name)
140 SensorValue.setValue(self, 0)
141 self.sysfs_attr = "/sys/class/hwmon/hwmon3/user_powercap"
142 ##override setValue method
143 @dbus.service.method(SensorValue.IFACE_NAME,
144 in_signature='v', out_signature='')
145 def setValue(self, value):
146 try:
147 cmd_str = "echo "+str(value)+" > "+self.sysfs_attr
148 ret = subprocess.check_output(cmd_str, shell=True)
149 except subprocess.CalledProcessError as powerexc:
150 print "Set PowerCap Error", powerexc.returncode,
151 powerexc.output
152 return
153 print "Set PowerCap: ", value
154 SensorValue.setValue(self, value)
Norman James323ed972015-12-09 09:06:37 -0600155
156class BootProgressSensor(VirtualSensor):
157 def __init__(self,bus,name):
158 VirtualSensor.__init__(self,bus,name)
159 self.setValue("Off")
160 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
161
162 def SystemStateHandler(self,state):
163 if (state == "HOST_POWERED_OFF"):
164 self.setValue("Off")
165
166
167 ##override setValue method
168 @dbus.service.method(SensorValue.IFACE_NAME,
169 in_signature='v', out_signature='')
170 def setValue(self,value):
171 SensorValue.setValue(self,value)
172 if (value == "FW Progress, Starting OS"):
173 self.GotoSystemState("HOST_BOOTED")
174
175 @dbus.service.signal(CONTROL_IFACE,signature='s')
176 def GotoSystemState(self,state):
177 pass
178
179class OccStatusSensor(VirtualSensor):
Brad Bishop314c4e22016-04-27 11:00:00 -0400180 def __init__(self,bus,name, sysfs = None):
Yi Li99ed56f2016-01-20 13:39:15 +0800181 ## default path. can be override
Brad Bishop314c4e22016-04-27 11:00:00 -0400182 if sysfs is None:
183 self.sysfs_attr = "/sys/class/i2c-adapter/i2c-3/3-0050/online"
184 else:
185 self.sysfs_attr = sysfs
Norman James323ed972015-12-09 09:06:37 -0600186 VirtualSensor.__init__(self,bus,name)
187 self.setValue("Disabled")
188 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
189
190 def SystemStateHandler(self,state):
191 if (state == "HOST_POWERED_OFF"):
192 self.setValue("Disabled")
Norman James323ed972015-12-09 09:06:37 -0600193
194 ##override setValue method
195 @dbus.service.method(SensorValue.IFACE_NAME,
196 in_signature='v', out_signature='')
197 def setValue(self,value):
198 if (value == "Enabled"):
199 print "Installing OCC device"
Yi Li99ed56f2016-01-20 13:39:15 +0800200 os.system("echo 1 > " + self.sysfs_attr)
Norman James323ed972015-12-09 09:06:37 -0600201 else:
202 print "Deleting OCC device"
Yi Li99ed56f2016-01-20 13:39:15 +0800203 os.system("echo 0 > " + self.sysfs_attr)
Norman James323ed972015-12-09 09:06:37 -0600204 SensorValue.setValue(self,value)
205
206 @dbus.service.signal(CONTROL_IFACE,signature='s')
207 def GotoSystemState(self,state):
208 pass
209
210class BootCountSensor(VirtualSensor):
211 def __init__(self,bus,name):
212 VirtualSensor.__init__(self,bus,name)
Chris Austen4c9ea5d2015-12-09 23:26:08 -0600213 self.setValue(2)
Norman James323ed972015-12-09 09:06:37 -0600214
215class OperatingSystemStatusSensor(VirtualSensor):
216 def __init__(self,bus,name):
217 VirtualSensor.__init__(self,bus,name)
218 self.setValue("Off")
Chris Austenc0448f02016-01-12 16:01:30 -0600219 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
Norman James323ed972015-12-09 09:06:37 -0600220
Chris Austenc0448f02016-01-12 16:01:30 -0600221 def SystemStateHandler(self,state):
222 if (state == "HOST_POWERED_OFF"):
223 self.setValue("Off")