blob: 12cfa05642fc687309b2f75a224db39817775a5b [file] [log] [blame]
Brad Bishop2fa78fb2016-08-30 19:51:51 -04001#!/usr/bin/env python
Norman James323ed972015-12-09 09:06:37 -06002
Norman James323ed972015-12-09 09:06:37 -06003import os
4import gobject
Norman James3bb97d92015-12-18 14:57:22 -06005import glob
Norman James323ed972015-12-09 09:06:37 -06006import dbus
7import dbus.service
8import dbus.mainloop.glib
Norman James3bb97d92015-12-18 14:57:22 -06009import re
Brad Bishop84e73b52016-05-12 15:57:52 -040010from obmc.dbuslib.bindings import get_dbus
Norman James3bb97d92015-12-18 14:57:22 -060011
Brad Bishopee1b1542016-05-12 16:55:00 -040012from obmc.sensors import SensorValue as SensorValue
13from obmc.sensors import HwmonSensor as HwmonSensor
14from obmc.sensors import SensorThresholds as SensorThresholds
Brad Bishop67a6f452016-08-30 19:56:58 -040015
16try:
17 import obmc_system_config as System
18 have_system = True
19except ImportError:
20 have_system = False
Norman James323ed972015-12-09 09:06:37 -060021
22SENSOR_BUS = 'org.openbmc.Sensors'
23SENSOR_PATH = '/org/openbmc/sensors'
Norman James3bb97d92015-12-18 14:57:22 -060024DIR_POLL_INTERVAL = 30000
Norman James323ed972015-12-09 09:06:37 -060025HWMON_PATH = '/sys/class/hwmon'
26
27## static define which interface each property is under
28## need a better way that is not slow
29IFACE_LOOKUP = {
Brad Bishop2fa78fb2016-08-30 19:51:51 -040030 'units': SensorValue.IFACE_NAME,
31 'adjust': HwmonSensor.IFACE_NAME,
32 'scale': HwmonSensor.IFACE_NAME,
33 'offset': HwmonSensor.IFACE_NAME,
34 'critical_upper': SensorThresholds.IFACE_NAME,
35 'warning_upper': SensorThresholds.IFACE_NAME,
36 'critical_lower': SensorThresholds.IFACE_NAME,
37 'warning_lower': SensorThresholds.IFACE_NAME,
38 'emergency_enabled': SensorThresholds.IFACE_NAME,
Norman James323ed972015-12-09 09:06:37 -060039}
40
Brad Bishop2fa78fb2016-08-30 19:51:51 -040041
Norman James323ed972015-12-09 09:06:37 -060042class Hwmons():
Brad Bishop2fa78fb2016-08-30 19:51:51 -040043 def __init__(self, bus):
44 self.sensors = {}
45 self.hwmon_root = {}
Brad Bishop67a6f452016-08-30 19:56:58 -040046
47 if have_system:
48 self.scanDirectory()
49 gobject.timeout_add(DIR_POLL_INTERVAL, self.scanDirectory)
Norman James323ed972015-12-09 09:06:37 -060050
Brad Bishop2fa78fb2016-08-30 19:51:51 -040051 def readAttribute(self, filename):
52 val = "-1"
53 try:
54 with open(filename, 'r') as f:
55 for line in f:
56 val = line.rstrip('\n')
57 except (OSError, IOError):
58 print "Cannot read attributes:", filename
59 return val
Norman James323ed972015-12-09 09:06:37 -060060
Brad Bishop2fa78fb2016-08-30 19:51:51 -040061 def writeAttribute(self, filename, value):
62 with open(filename, 'w') as f:
63 f.write(str(value)+'\n')
64
65 def poll(self, objpath, attribute):
66 try:
67 raw_value = int(self.readAttribute(attribute))
68 obj = bus.get_object(SENSOR_BUS, objpath, introspect=False)
69 intf = dbus.Interface(obj, HwmonSensor.IFACE_NAME)
70 rtn = intf.setByPoll(raw_value)
71 if rtn[0]:
72 self.writeAttribute(attribute, rtn[1])
73 except:
74 print "HWMON: Attibute no longer exists: "+attribute
75 self.sensors.pop(objpath, None)
76 return False
77
78 return True
79
80 def addObject(self, dpath, hwmon_path, hwmon):
81 objsuf = hwmon['object_path']
82 objpath = SENSOR_PATH+'/'+objsuf
83
84 if objpath not in self.sensors:
85 print "HWMON add: "+objpath+" : "+hwmon_path
86
87 ## register object with sensor manager
88 obj = bus.get_object(SENSOR_BUS, SENSOR_PATH, introspect=False)
89 intf = dbus.Interface(obj, SENSOR_BUS)
90 intf.register("HwmonSensor", objpath)
91
92 ## set some properties in dbus object
93 obj = bus.get_object(SENSOR_BUS, objpath, introspect=False)
94 intf = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
95 intf.Set(HwmonSensor.IFACE_NAME, 'filename', hwmon_path)
96
97 ## check if one of thresholds is defined to know
98 ## whether to enable thresholds or not
99 if 'critical_upper' in hwmon:
100 intf.Set(
101 SensorThresholds.IFACE_NAME, 'thresholds_enabled', True)
102
103 for prop in hwmon.keys():
104 if prop in IFACE_LOOKUP:
105 intf.Set(IFACE_LOOKUP[prop], prop, hwmon[prop])
106 print "Setting: "+prop+" = "+str(hwmon[prop])
107
108 self.sensors[objpath] = True
109 self.hwmon_root[dpath].append(objpath)
110 gobject.timeout_add(
111 hwmon['poll_interval'], self.poll, objpath, hwmon_path)
112
113 def scanDirectory(self):
114 devices = os.listdir(HWMON_PATH)
115 found_hwmon = {}
116 regx = re.compile('([a-z]+)\d+\_')
117 for d in devices:
118 dpath = HWMON_PATH+'/'+d+'/'
119 found_hwmon[dpath] = True
120 if dpath not in self.hwmon_root:
121 self.hwmon_root[dpath] = []
122 ## the instance name is a soft link
123 instance_name = os.path.realpath(dpath+'device').split('/').pop()
124
125 if instance_name in System.HWMON_CONFIG:
126 hwmon = System.HWMON_CONFIG[instance_name]
127
128 if 'labels' in hwmon:
129 label_files = glob.glob(dpath+'/*_label')
130 for f in label_files:
131 label_key = self.readAttribute(f)
132 if label_key in hwmon['labels']:
133 namef = f.replace('_label', '_input')
134 self.addObject(
135 dpath, namef, hwmon['labels'][label_key])
136 else:
137 pass
138
139 if 'names' in hwmon:
140 for attribute in hwmon['names'].keys():
141 self.addObject(
142 dpath, dpath+attribute, hwmon['names'][attribute])
143
144 else:
145 print "WARNING - hwmon: Unhandled hwmon: "+dpath
146
147 for k in self.hwmon_root.keys():
148 if k not in found_hwmon:
149 ## need to remove all objects associated with this path
150 print "Removing: "+k
151 for objpath in self.hwmon_root[k]:
152 if objpath in self.sensors:
153 print "HWMON remove: "+objpath
154 self.sensors.pop(objpath, None)
155 obj = bus.get_object(
156 SENSOR_BUS, SENSOR_PATH, introspect=False)
157 intf = dbus.Interface(obj, SENSOR_BUS)
158 intf.delete(objpath)
159
160 self.hwmon_root.pop(k, None)
161
162 return True
Norman James323ed972015-12-09 09:06:37 -0600163
164
Norman James323ed972015-12-09 09:06:37 -0600165if __name__ == '__main__':
Brad Bishop2fa78fb2016-08-30 19:51:51 -0400166 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
167 bus = get_dbus()
168 root_sensor = Hwmons(bus)
169 mainloop = gobject.MainLoop()
Norman James323ed972015-12-09 09:06:37 -0600170
Brad Bishop2fa78fb2016-08-30 19:51:51 -0400171 print "Starting HWMON sensors"
172 mainloop.run()