Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 3 | import sys |
Norman James | 5d78b4d | 2015-09-05 13:34:34 -0500 | [diff] [blame] | 4 | from gi.repository import GObject |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 5 | import dbus |
| 6 | import dbus.service |
| 7 | import dbus.mainloop.glib |
| 8 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 9 | DBUS_NAME = 'org.openbmc.control.Chassis' |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 10 | OBJ_NAME = '/org/openbmc/control/Chassis/'+sys.argv[1] |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 11 | |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 12 | POWER_OFF = 0 |
| 13 | POWER_ON = 1 |
| 14 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 15 | BOOTED = 100 |
| 16 | |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 17 | class ChassisControlObject(dbus.service.Object): |
| 18 | def __init__(self,bus,name): |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 19 | self.dbus_objects = { } |
Norman James | 90baede | 2015-09-02 20:32:49 -0500 | [diff] [blame] | 20 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 21 | dbus.service.Object.__init__(self,bus,name) |
Norman James | 90baede | 2015-09-02 20:32:49 -0500 | [diff] [blame] | 22 | ## load utilized objects |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 23 | self.dbus_busses = { |
Norman James | 90baede | 2015-09-02 20:32:49 -0500 | [diff] [blame] | 24 | 'org.openbmc.control.Power' : |
| 25 | [ { 'name' : 'PowerControl1' , 'intf' : 'org.openbmc.control.Power' } ], |
| 26 | 'org.openbmc.leds.ChassisIdentify' : |
| 27 | [ { 'name' : 'ChassisIdentify1', 'intf' : 'org.openbmc.control.Chassis' } ], |
| 28 | 'org.openbmc.control.Host' : |
| 29 | [ { 'name' : 'HostControl1', 'intf' : 'org.openbmc.control.Host' } ] |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 30 | } |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 31 | self.power_sequence = 0 |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 32 | self.reboot = 0 |
| 33 | self.last_power_state = 0 |
Norman James | 90baede | 2015-09-02 20:32:49 -0500 | [diff] [blame] | 34 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 35 | bus = dbus.SessionBus() |
Norman James | 90baede | 2015-09-02 20:32:49 -0500 | [diff] [blame] | 36 | |
| 37 | ## add signal handler to detect when new objects show up on dbus |
| 38 | bus.add_signal_receiver(self.request_name, |
| 39 | dbus_interface = 'org.freedesktop.DBus', |
| 40 | signal_name = "NameOwnerChanged") |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 41 | |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 42 | bus.add_signal_receiver(self.power_button_signal_handler, |
| 43 | dbus_interface = "org.openbmc.Button", signal_name = "ButtonPressed", |
| 44 | path="/org/openbmc/buttons/ButtonPower/PowerButton1" ) |
| 45 | bus.add_signal_receiver(self.power_good_signal_handler, |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 46 | dbus_interface = "org.openbmc.control.Power", signal_name = "PowerGood") |
| 47 | bus.add_signal_receiver(self.power_lost_signal_handler, |
| 48 | dbus_interface = "org.openbmc.control.Power", signal_name = "PowerLost") |
| 49 | bus.add_signal_receiver(self.host_watchdog_signal_handler, |
| 50 | dbus_interface = "org.openbmc.Watchdog", signal_name = "WatchdogError") |
| 51 | bus.add_signal_receiver(self.host_status_signal_handler, |
| 52 | dbus_interface = "org.openbmc.SensorMatch", signal_name = "SensorMatch", |
| 53 | path="/org/openbmc/sensors/HostStatus/HostStatus1") |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 54 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 55 | try: |
| 56 | for bus_name in self.dbus_busses.keys(): |
| 57 | self.request_name(bus_name,"",bus_name) |
| 58 | |
| 59 | except: |
| 60 | ## its ok if this fails. hotplug will detect too |
| 61 | print "Warning: One of processes not started yet." |
| 62 | pass |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 63 | |
| 64 | |
| 65 | def request_name(self, bus_name, a, b): |
| 66 | # bus added |
| 67 | if (len(b) > 0 ): |
Norman James | 90baede | 2015-09-02 20:32:49 -0500 | [diff] [blame] | 68 | ## if bus in required list for this object, then save a pointer to interface |
| 69 | ## for method calls |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 70 | if (self.dbus_busses.has_key(bus_name)): |
| 71 | obj_path = "/"+bus_name.replace('.','/') |
| 72 | for objs in self.dbus_busses[bus_name]: |
| 73 | inst_name = objs['name'] |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 74 | print "Chassis control: "+inst_name |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 75 | obj = bus.get_object(bus_name,obj_path+"/"+inst_name) |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 76 | self.dbus_objects[inst_name] = dbus.Interface(obj, objs['intf']) |
| 77 | |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 78 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 79 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 80 | in_signature='', out_signature='s') |
| 81 | def getID(self): |
| 82 | return id |
| 83 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 84 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 85 | in_signature='', out_signature='') |
| 86 | def setIdentify(self): |
| 87 | print "Turn on identify" |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 88 | self.dbus_objects['ChassisIdentify1'].setOn() |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 89 | return None |
| 90 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 91 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 92 | in_signature='', out_signature='') |
| 93 | def clearIdentify(self): |
| 94 | print "Turn off identify" |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 95 | r=self.dbus_objects['ChassisIdentify1'].setOff() |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 96 | return None |
| 97 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 98 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 99 | in_signature='', out_signature='') |
| 100 | def setPowerOn(self): |
| 101 | print "Turn on power and boot" |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 102 | self.power_sequence = 0 |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 103 | self.reboot = 0 |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 104 | if (self.getPowerState()==0): |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 105 | self.dbus_objects['PowerControl1'].setPowerState(POWER_ON) |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 106 | self.power_sequence = 1 |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 107 | return None |
| 108 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 109 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 110 | in_signature='', out_signature='') |
| 111 | def setPowerOff(self): |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 112 | self.power_sequence = 0 |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 113 | print "Turn off power" |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 114 | self.dbus_objects['PowerControl1'].setPowerState(POWER_OFF); |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 115 | return None |
| 116 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 117 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 118 | in_signature='', out_signature='i') |
| 119 | def getPowerState(self): |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 120 | state = self.dbus_objects['PowerControl1'].getPowerState(); |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 121 | return state |
| 122 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 123 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 124 | in_signature='', out_signature='') |
| 125 | def setDebugMode(self): |
| 126 | return None |
| 127 | |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 128 | @dbus.service.method(DBUS_NAME, |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 129 | in_signature='i', out_signature='') |
| 130 | def setPowerPolicy(self,policy): |
| 131 | return None |
| 132 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 133 | |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 134 | ## Signal handler |
| 135 | def power_button_signal_handler(self): |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 136 | # toggle power |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 137 | state = self.getPowerState() |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 138 | if state == POWER_OFF: |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 139 | self.setPowerOn() |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 140 | elif state == POWER_ON: |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 141 | self.setPowerOff(); |
| 142 | |
| 143 | # TODO: handle long press and reset |
| 144 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 145 | ## Signal handlers |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 146 | def power_good_signal_handler(self): |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 147 | if (self.power_sequence==1): |
Norman James | 471ab59 | 2015-08-30 22:29:40 -0500 | [diff] [blame] | 148 | self.dbus_objects['HostControl1'].boot() |
Norman James | 2a3d20b | 2015-08-20 07:09:33 -0500 | [diff] [blame] | 149 | self.power_sequence = 2 |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 150 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 151 | def host_status_signal_handler(self,value): |
| 152 | if (value == BOOTED and self.power_sequence==2): |
| 153 | self.power_sequence=0 |
| 154 | print "Host booted" |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 155 | |
Norman James | 9e6acf9 | 2015-09-08 07:00:04 -0500 | [diff] [blame^] | 156 | def power_lost_signal_handler(self): |
| 157 | ## Reboot if power is lost but reboot requested |
| 158 | if (self.reboot == 1): |
| 159 | self.setPowerOn() |
| 160 | |
| 161 | def host_watchdog_signal_handler(self): |
| 162 | print "Watchdog Error, Rebooting" |
| 163 | self.reboot = 1 |
| 164 | self.setPowerOff() |
| 165 | |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 166 | |
| 167 | if __name__ == '__main__': |
| 168 | dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
| 169 | |
| 170 | bus = dbus.SessionBus() |
Norman James | 3f97c5d | 2015-08-26 17:44:14 -0500 | [diff] [blame] | 171 | name = dbus.service.BusName(DBUS_NAME, bus) |
| 172 | obj = ChassisControlObject(bus, OBJ_NAME) |
Norman James | 5d78b4d | 2015-09-05 13:34:34 -0500 | [diff] [blame] | 173 | mainloop = GObject.MainLoop() |
Norman James | 81dbd35 | 2015-08-19 22:44:53 -0500 | [diff] [blame] | 174 | |
Norman James | e276510 | 2015-08-19 22:00:55 -0500 | [diff] [blame] | 175 | print "Running ChassisControlService" |
| 176 | mainloop.run() |
| 177 | |