blob: 19a23094e94a3ccee7312080c8bbe742016fdc31 [file] [log] [blame]
#!/usr/bin/python -u
import sys
import os
import gobject
import glob
import dbus
import dbus.service
import dbus.mainloop.glib
import Openbmc
import re
from Sensors import SensorValue as SensorValue
from Sensors import HwmonSensor as HwmonSensor
from Sensors import SensorThresholds as SensorThresholds
if (len(sys.argv) < 2):
print "Usage: sensors_hwmon.py [system name]"
exit(1)
System = __import__(sys.argv[1])
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(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 = Openbmc.getDBus()
root_sensor = Hwmons(bus)
mainloop = gobject.MainLoop()
print "Starting HWMON sensors"
mainloop.run()