blob: 3574b6065c9d4683c5b19cebbc80032ce8976daf [file] [log] [blame]
Norman James3cb0f982015-12-03 01:07:16 -06001#!/usr/bin/python -u
2
3import sys
4import os
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import Openbmc
10if (len(sys.argv) < 2):
11 print "Usage: sensors_hwmon.py [system name]"
12 exit(1)
13
14System = __import__(sys.argv[1])
15
16DBUS_NAME = 'org.openbmc.sensors.hwmon'
17OBJ_PATH = '/org/openbmc/sensors'
18DIR_POLL_INTERVAL = 10000
19HWMON_PATH = '/sys/class/hwmon'
20
21class SensorValue(Openbmc.DbusProperties):
22 IFACE_NAME = 'org.openbmc.SensorValue'
23 def __init__(self,bus,name):
24 Openbmc.DbusProperties.__init__(self)
25 self.Set(SensorValue.IFACE_NAME,'units',"")
26 dbus.service.Object.__init__(self,bus,name)
27
28 @dbus.service.method(IFACE_NAME,
29 in_signature='v', out_signature='')
30 def setValue(self,value):
31 changed = False
32 try:
33 old_value = self.Get(SensorValue.IFACE_NAME,'value')
34 if (value != old_value):
35 changed = True
36 except:
37 changed = True
38
39 if (changed == True):
40 self.Set(SensorValue.IFACE_NAME,'value',value)
41 self.Changed(self.getValue(),self.getUnits())
42
43
44
45 @dbus.service.method(IFACE_NAME,
46 in_signature='', out_signature='v')
47 def getValue(self):
48 return self.Get(SensorValue.IFACE_NAME,'value')
49
50 @dbus.service.method(IFACE_NAME,
51 in_signature='', out_signature='s')
52 def getUnits(self):
53 return self.Get(SensorValue.IFACE_NAME,'units')
54
55 @dbus.service.signal(IFACE_NAME,signature='vs')
56 def Changed(self,value,units):
57 pass
58
59def readAttribute(filename):
60 val = ""
61 with open(filename, 'r') as f:
62 for line in f:
63 val = line.rstrip('\n')
64 return val
65
66class HwmonSensor(SensorValue):
67 def __init__(self, bus ,name, attribute ,poll_interval ,units, scale):
68 SensorValue.__init__(self,bus,name)
69 self.attribute = attribute
70 self.scale = 1
71 if scale > 0:
72 self.scale = scale
73
74 self.Set(SensorValue.IFACE_NAME,'units',units)
75 self.pollSensor()
76
77 if (poll_interval > 0):
78 gobject.timeout_add(poll_interval, self.pollSensor)
79 else:
80 print "ERROR HWMON: poll_interval must be > 0"
81 self.ObjectAdded(name,SensorValue.IFACE_NAME)
82
83
84 def pollSensor(self):
85 try:
86 with open(self.attribute, 'r') as f:
87 for line in f:
88 val = int(line.rstrip('\n'))/self.scale
89 SensorValue.setValue(self,val)
90 except:
91 print "Attribute no longer exists: "+self.attribute
92 return False
93
94 return True
95
96 @dbus.service.method(SensorValue.IFACE_NAME,
97 in_signature='v', out_signature='')
98 def setValue(self,value):
99 try:
100 with open(self.attribute, 'w') as f:
101 val = int(value*self.scale)
102 f.write(str(val)+'\n')
103 SensorValue.setValue(self,value)
104 except Exception as e:
105 print e
106 print "Unable to write: "+self.attribute
107
108 SensorValue.setValue(self,value)
109
110
111
112
113
114class Sensors(Openbmc.DbusProperties):
115 def __init__(self,bus,name):
116 dbus.service.Object.__init__(self,bus,name)
117 self.sensors = { }
118 self.hwmon_root = { }
119 bus.add_signal_receiver(self.OccActiveHandler,
120 dbus_interface = "org.openbmc.SensorValue", signal_name = "Changed",
121 path="/org/openbmc/sensor/virtual/OccStatus" )
122
123 gobject.timeout_add(DIR_POLL_INTERVAL, self.scanDirectory)
124 self.ObjectAdded(name,DBUS_NAME)
125
126 def OccActiveHandler(self,value,units):
127 print "OCC "+value
128 if (value == "Enabled"):
129 print "Installing OCC device"
130 os.system("echo occ-i2c 0x50 > /sys/bus/i2c/devices/i2c-3/new_device")
131 os.system("echo occ-i2c 0x51 > /sys/bus/i2c/devices/i2c-3/new_device")
132 if (value == "Disabled"):
133 print "Deleting OCC device"
134 os.system("echo 0x50 > /sys/bus/i2c/devices/i2c-3/delete_device")
135 os.system("echo 0x51 > /sys/bus/i2c/devices/i2c-3/delete_device")
136
137 def addObject(self,dpath,instance_name,attribute):
138 hwmon = System.HWMON_CONFIG[instance_name][attribute]
139 objsuf = hwmon['object_path']
140 if (objsuf.find('<label>') > -1):
141 label_file = attribute.replace('_input','_label')
142 label = readAttribute(dpath+label_file)
143 objsuf = objsuf.replace('<label>',label)
144
145 objpath = OBJ_PATH+'/'+objsuf
146 spath = dpath+attribute
147 if (self.sensors.has_key(objpath) == False):
148 if os.path.isfile(spath):
149 print "HWMON add: "+objpath+" : "+spath
150 self.sensors[objpath]= HwmonSensor(bus,objpath,spath,
151 hwmon['poll_interval'],hwmon['units'],hwmon['scale'])
152 self.hwmon_root[dpath].append(objpath)
153
154
155 def scanDirectory(self):
156 devices = os.listdir(HWMON_PATH)
157 found_hwmon = {}
158 for d in devices:
159 dpath = HWMON_PATH+'/'+d+'/'
160 found_hwmon[dpath] = True
161 if (self.hwmon_root.has_key(dpath) == False):
162 self.hwmon_root[dpath] = []
163 ## the instance name is a soft link
164 instance_name = os.path.realpath(dpath+'device').split('/').pop()
165 if (System.HWMON_CONFIG.has_key(instance_name)):
166 for attribute in System.HWMON_CONFIG[instance_name].keys():
167 self.addObject(dpath,instance_name,attribute)
168 else:
169 print "WARNING: Unhandled hwmon: "+dpath
170
171
172 for k in self.hwmon_root.keys():
173 if (found_hwmon.has_key(k) == False):
174 ## need to remove all objects associated with this path
175 print "Removing: "+k
176 for objpath in self.hwmon_root[k]:
177 if (self.sensors.has_key(objpath) == True):
178 print "HWMON remove: "+objpath
179 obj = self.sensors.pop(objpath,None)
180 obj.remove_from_connection()
181 self.hwmon_root.pop(k,None)
182
183 return True
184
185
186if __name__ == '__main__':
187
188 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
189 bus = Openbmc.getDBus()
190 name = dbus.service.BusName(DBUS_NAME,bus)
191 root_sensor = Sensors(bus,OBJ_PATH)
192 mainloop = gobject.MainLoop()
193
194 print "Starting HWMON sensors"
195 mainloop.run()
196