Norman James | cc7ae12 | 2015-08-24 14:26:09 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | |
| 4 | import gobject |
| 5 | import dbus |
| 6 | import dbus.service |
| 7 | import dbus.mainloop.glib |
| 8 | import xml.etree.ElementTree as ET |
| 9 | import System |
| 10 | |
| 11 | NORMAL = 0 |
| 12 | LOWER_WARNING = 1 |
| 13 | LOWER_CRITICAL = 2 |
| 14 | UPPER_WARNING = 3 |
| 15 | UPPER_CRITICAL = 4 |
| 16 | |
| 17 | |
| 18 | sensor_config = System.Barreleye() |
| 19 | |
| 20 | ## finds objects held by Dbus ObjectManager |
| 21 | def get_interface(obj_path): |
| 22 | bus_name = sensor_config[obj_path]['bus_name'] |
| 23 | obj_name = "/"+bus_name.replace('.','/') |
| 24 | obj = bus.get_object(bus_name, obj_name) |
| 25 | #Find object in object manager and retrieve interface name |
| 26 | manager = dbus.Interface(obj,'org.freedesktop.DBus.ObjectManager') |
| 27 | objects = manager.GetManagedObjects() |
| 28 | interface = None |
| 29 | if (objects.has_key(obj_path)): |
| 30 | for intf in objects[obj_path].keys(): |
| 31 | if (intf.find('Sensor') > 0): |
| 32 | interface = intf |
| 33 | |
| 34 | if (interface == None): |
| 35 | raise Exception("Unable to find sensor: "+obj_path) |
| 36 | |
| 37 | return interface |
| 38 | |
| 39 | |
| 40 | ## Maintains last value, handles sensor changed events, applies thresholds |
| 41 | ## The Sensor class is not exported onto dbus |
| 42 | class Sensor: |
| 43 | |
| 44 | def __init__(self, bus, obj_name, warning_callback, critical_callback): |
| 45 | obj = bus.get_object(sensor_config[obj_name]['bus_name'],obj_name) |
| 46 | |
| 47 | ## member variables |
| 48 | self.object_name = obj_name |
| 49 | interface_name = get_interface(obj_name) |
| 50 | self.interface = dbus.Interface(obj,interface_name) |
| 51 | self.value = self.interface.getValue() |
| 52 | self.upper_critical_threshold = None |
| 53 | self.lower_critical_threshold = None |
| 54 | self.upper_warning_threshold = None |
| 55 | self.lower_warning_threshold = None |
| 56 | self.threshold_state = NORMAL |
| 57 | self.emit_warning = warning_callback |
| 58 | self.emit_critical = critical_callback |
| 59 | |
| 60 | ## add signal handler to update cached value when sensor changes |
| 61 | bus.add_signal_receiver(self.sensor_changed_signal_handler, |
| 62 | dbus_interface = interface_name, signal_name = "Changed") |
| 63 | |
| 64 | def set_thresholds(self,lc,lw,uw,uc): |
| 65 | self.upper_critical_threshold = uc |
| 66 | self.lower_critical_threshold = lc |
| 67 | self.upper_warning_threshold = uw |
| 68 | self.lower_warning_threshold = lw |
| 69 | |
| 70 | def set_config(self,data): |
| 71 | self.interface.setConfigData(data) |
| 72 | |
| 73 | ## called when associated sensor dbus object emits a Changed signal |
| 74 | def sensor_changed_signal_handler(self,value): |
| 75 | ## update value from signal data |
| 76 | self.value = value |
| 77 | |
| 78 | ## check thresholds |
| 79 | state = NORMAL |
| 80 | if (value < self.lower_critical_threshold): |
| 81 | state = LOWER_CRITICAL |
| 82 | elif (value < self.lower_warning_threshold): |
| 83 | state = LOWER_WARNING |
| 84 | elif (value > self.upper_critical_threshold): |
| 85 | state = UPPER_CRITICAL |
| 86 | elif (value > self.upper_warning_threshold): |
| 87 | state = UPPER_WARNING |
| 88 | ## only emit signal if threshold state has changed |
| 89 | if (state != self.threshold_state): |
| 90 | self.threshold_state = state |
| 91 | if (state == LOWER_CRITICAL or state == UPPER_CRITICAL): |
| 92 | self.emit_critical(self.object_name) |
| 93 | if (state == LOWER_WARNING or state == UPPER_WARNING): |
| 94 | self.emit_warning(self.object_name) |
| 95 | |
| 96 | |
| 97 | def get_value(self): |
| 98 | return self.value |
| 99 | |
| 100 | |
| 101 | class SensorManagement(dbus.service.Object): |
| 102 | def __init__(self,bus,name): |
| 103 | dbus.service.Object.__init__(self,bus,name) |
| 104 | self.sensor_cache = {} |
| 105 | try: |
| 106 | for objname in sensor_config.keys(): |
| 107 | print "Loading: "+objname |
| 108 | sensor_new = Sensor(bus,objname, |
| 109 | self.WarningThreshold,self.CriticalThreshold) |
| 110 | sensor_new.set_thresholds(sensor_config[objname]['lower_critical'], |
| 111 | sensor_config[objname]['lower_warning'], |
| 112 | sensor_config[objname]['upper_warning'], |
| 113 | sensor_config[objname]['upper_critical']) |
| 114 | if (sensor_config[objname].has_key('parameters')): |
| 115 | sensor_new.set_config(sensor_config[objname]['parameters']) |
| 116 | self.sensor_cache[objname] = sensor_new |
| 117 | |
| 118 | except dbus.exceptions.DBusException, e: |
| 119 | # TODO: not sure what to do if can't find other services |
| 120 | print "Unable to find dependent services: ",e |
| 121 | |
| 122 | |
| 123 | @dbus.service.method("org.openbmc.SensorManagement", |
| 124 | in_signature='s', out_signature='a{ss}') |
| 125 | def getAllSensors(self,obj_name): |
| 126 | return None |
| 127 | |
| 128 | @dbus.service.method("org.openbmc.SensorManagement", |
| 129 | in_signature='s', out_signature='i') |
| 130 | def getSensorValue(self,obj_name): |
| 131 | sensor = self.sensor_cache[obj_name] |
| 132 | return sensor.get_value() |
| 133 | |
| 134 | @dbus.service.signal('org.openbmc.SensorManagement') |
| 135 | def CriticalThreshold(self, obj): |
| 136 | print "Critical: "+obj |
| 137 | |
| 138 | @dbus.service.signal('org.openbmc.SensorManagement') |
| 139 | def WarningThreshold(self, obj): |
| 140 | print "Warning: "+obj |
| 141 | |
| 142 | |
| 143 | if __name__ == '__main__': |
| 144 | dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
| 145 | bus = dbus.SessionBus() |
| 146 | name = dbus.service.BusName("org.openbmc.SensorManagement",bus) |
| 147 | obj = SensorManagement(bus,'/org/openbmc/SensorManagement') |
| 148 | mainloop = gobject.MainLoop() |
| 149 | |
| 150 | print "Running SensorManagementService" |
| 151 | mainloop.run() |
| 152 | |