1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
#!/usr/bin/python -u
import sys
import os
import gobject
import glob
import dbus
import dbus.service
import dbus.mainloop.glib
import re
from obmc.dbuslib.bindings import get_dbus
from obmc.sensors import SensorValue as SensorValue
from obmc.sensors import HwmonSensor as HwmonSensor
from obmc.sensors import SensorThresholds as SensorThresholds
import obmc_system_config as System
SENSOR_BUS = 'org.openbmc.Sensors'
SENSOR_PATH = '/org/openbmc/sensors'
DIR_POLL_INTERVAL = 30000
HWMON_PATH = '/sys/class/hwmon'
## static define which interface each property is under
## need a better way that is not slow
IFACE_LOOKUP = {
'units' : SensorValue.IFACE_NAME,
'scale' : HwmonSensor.IFACE_NAME,
'offset' : HwmonSensor.IFACE_NAME,
'critical_upper' : SensorThresholds.IFACE_NAME,
'warning_upper' : SensorThresholds.IFACE_NAME,
'critical_lower' : SensorThresholds.IFACE_NAME,
'warning_lower' : SensorThresholds.IFACE_NAME,
'emergency_enabled' : SensorThresholds.IFACE_NAME,
}
class Hwmons():
def __init__(self,bus):
self.sensors = { }
self.hwmon_root = { }
self.scanDirectory()
gobject.timeout_add(DIR_POLL_INTERVAL, self.scanDirectory)
self.cache = {}
def readAttribute(self,filename):
val = "-1"
try:
with open(filename, 'r') as f:
for line in f:
val = line.rstrip('\n')
except (OSError, IOError):
print "Cannot read attributes:", filename
return val
def writeAttribute(self,filename,value):
with open(filename, 'w') as f:
f.write(str(value)+'\n')
def should_update(self, attribute, value):
if attribute not in self.cache:
self.cache[attribute] = value
return True
update = (value != self.cache[attribute])
self.cache[attribute] = value
return update
def poll(self,objpath,attribute):
try:
raw_value = int(self.readAttribute(attribute))
if self.should_update(attribute, raw_value):
obj = bus.get_object(SENSOR_BUS,objpath,introspect=False)
intf = dbus.Interface(obj,HwmonSensor.IFACE_NAME)
rtn = intf.setByPoll(raw_value)
if (rtn[0] == True):
self.writeAttribute(attribute,rtn[1])
except:
print "HWMON: Attibute no longer exists: "+attribute
self.sensors.pop(objpath,None)
if attribute in self.cache:
del self.cache[attribute]
return False
return True
def addObject(self,dpath,hwmon_path,hwmon):
objsuf = hwmon['object_path']
objpath = SENSOR_PATH+'/'+objsuf
if (self.sensors.has_key(objpath) == False):
print "HWMON add: "+objpath+" : "+hwmon_path
## register object with sensor manager
obj = bus.get_object(SENSOR_BUS,SENSOR_PATH,introspect=False)
intf = dbus.Interface(obj,SENSOR_BUS)
intf.register("HwmonSensor",objpath)
## set some properties in dbus object
obj = bus.get_object(SENSOR_BUS,objpath,introspect=False)
intf = dbus.Interface(obj,dbus.PROPERTIES_IFACE)
intf.Set(HwmonSensor.IFACE_NAME,'filename',hwmon_path)
## check if one of thresholds is defined to know
## whether to enable thresholds or not
if (hwmon.has_key('critical_upper')):
intf.Set(SensorThresholds.IFACE_NAME,'thresholds_enabled',True)
for prop in hwmon.keys():
if (IFACE_LOOKUP.has_key(prop)):
intf.Set(IFACE_LOOKUP[prop],prop,hwmon[prop])
print "Setting: "+prop+" = "+str(hwmon[prop])
self.sensors[objpath]=True
self.hwmon_root[dpath].append(objpath)
gobject.timeout_add(hwmon['poll_interval'],self.poll,objpath,hwmon_path)
def scanDirectory(self):
devices = os.listdir(HWMON_PATH)
found_hwmon = {}
regx = re.compile('([a-z]+)\d+\_')
for d in devices:
dpath = HWMON_PATH+'/'+d+'/'
found_hwmon[dpath] = True
if (self.hwmon_root.has_key(dpath) == False):
self.hwmon_root[dpath] = []
## the instance name is a soft link
instance_name = os.path.realpath(dpath+'device').split('/').pop()
if (System.HWMON_CONFIG.has_key(instance_name)):
hwmon = System.HWMON_CONFIG[instance_name]
if (hwmon.has_key('labels')):
label_files = glob.glob(dpath+'/*_label')
for f in label_files:
label_key = self.readAttribute(f)
if (hwmon['labels'].has_key(label_key)):
namef = f.replace('_label','_input')
self.addObject(dpath,namef,hwmon['labels'][label_key])
else:
pass
#print "WARNING - hwmon: label ("+label_key+") not found in lookup: "+f
if hwmon.has_key('names'):
for attribute in hwmon['names'].keys():
self.addObject(dpath,dpath+attribute,hwmon['names'][attribute])
else:
print "WARNING - hwmon: Unhandled hwmon: "+dpath
for k in self.hwmon_root.keys():
if (found_hwmon.has_key(k) == False):
## need to remove all objects associated with this path
print "Removing: "+k
for objpath in self.hwmon_root[k]:
if (self.sensors.has_key(objpath) == True):
print "HWMON remove: "+objpath
self.sensors.pop(objpath,None)
obj = bus.get_object(SENSOR_BUS,SENSOR_PATH,introspect=False)
intf = dbus.Interface(obj,SENSOR_BUS)
intf.delete(objpath)
self.hwmon_root.pop(k,None)
return True
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = get_dbus()
root_sensor = Hwmons(bus)
mainloop = gobject.MainLoop()
print "Starting HWMON sensors"
mainloop.run()
|