blob: 334fbbf659da9b1232bf579c16788b8a4553107c [file] [log] [blame]
Norman James42c1be82015-10-22 14:34:26 -05001#!/usr/bin/python -u
Norman Jamese2765102015-08-19 22:00:55 -05002
Norman James471ab592015-08-30 22:29:40 -05003import sys
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -05004import uuid
Norman James6f8d0422015-09-14 18:48:00 -05005#from gi.repository import GObject
6import gobject
Norman Jamese2765102015-08-19 22:00:55 -05007import dbus
8import dbus.service
9import dbus.mainloop.glib
Norman James5e792e32015-10-07 17:36:17 -050010import Openbmc
Norman Jamese2765102015-08-19 22:00:55 -050011
Norman James3f97c5d2015-08-26 17:44:14 -050012DBUS_NAME = 'org.openbmc.control.Chassis'
Norman James8fee6f22015-10-28 12:48:43 -050013OBJ_NAME = '/org/openbmc/control/chassis0'
Norman Jamesa3e47c42015-10-18 14:43:10 -050014CONTROL_INTF = 'org.openbmc.Control'
Norman James3f97c5d2015-08-26 17:44:14 -050015
Norman Jamesad8c3d32016-02-11 15:19:01 -060016MACHINE_ID = '/etc/machine-id'
17
Norman James2a3d20b2015-08-20 07:09:33 -050018POWER_OFF = 0
19POWER_ON = 1
20
Norman James9e6acf92015-09-08 07:00:04 -050021BOOTED = 100
22
Norman James323ed972015-12-09 09:06:37 -060023class ChassisControlObject(Openbmc.DbusProperties,Openbmc.DbusObjectManager):
Norman Jamesad8c3d32016-02-11 15:19:01 -060024 def getUuid(self):
25 uuid = "";
26 try:
27 with open(MACHINE_ID) as f:
28 data = f.readline().rstrip('\n')
29 if (len(data) == 32):
30 uuid = data
31 else:
32 print "ERROR: UUID is not formatted correctly: "+data
33 except:
34 print "ERROR: Unable to open uuid file: "+MACHINE_ID
35
36 return uuid
37
Norman Jamese2765102015-08-19 22:00:55 -050038 def __init__(self,bus,name):
Norman James471ab592015-08-30 22:29:40 -050039 self.dbus_objects = { }
Norman James2656f332015-10-26 06:42:41 -050040 Openbmc.DbusProperties.__init__(self)
Norman James323ed972015-12-09 09:06:37 -060041 Openbmc.DbusObjectManager.__init__(self)
Norman James9e6acf92015-09-08 07:00:04 -050042 dbus.service.Object.__init__(self,bus,name)
Norman James90baede2015-09-02 20:32:49 -050043 ## load utilized objects
Norman James362a80f2015-09-14 14:04:39 -050044 self.dbus_objects = {
45 'power_control' : {
46 'bus_name' : 'org.openbmc.control.Power',
Norman Jamesa3e47c42015-10-18 14:43:10 -050047 'object_name' : '/org/openbmc/control/power0',
Norman James362a80f2015-09-14 14:04:39 -050048 'interface_name' : 'org.openbmc.control.Power'
49 },
50 'identify_led' : {
Norman Jamesa3e47c42015-10-18 14:43:10 -050051 'bus_name' : 'org.openbmc.control.led',
Adriana Kobylak9c751042016-02-09 13:44:32 -060052 'object_name' : '/org/openbmc/control/led/identify',
Norman James362a80f2015-09-14 14:04:39 -050053 'interface_name' : 'org.openbmc.Led'
Norman Jamesc07c4732015-10-26 07:12:58 -050054 },
55 'watchdog' : {
56 'bus_name' : 'org.openbmc.watchdog.Host',
Norman James8fee6f22015-10-28 12:48:43 -050057 'object_name' : '/org/openbmc/watchdog/host0',
Norman Jamesc07c4732015-10-26 07:12:58 -050058 'interface_name' : 'org.openbmc.Watchdog'
Norman James98e1f7b2015-11-24 22:17:56 -060059 },
60 'host_services' : {
61 'bus_name' : 'org.openbmc.HostServices',
62 'object_name' : '/org/openbmc/HostServices',
63 'interface_name' : 'org.openbmc.HostServices'
64 },
Norman Jamesf5edb9e2016-01-31 13:32:24 -060065 'settings' : {
66 'bus_name' : 'org.openbmc.settings.Host',
67 'object_name' : '/org/openbmc/settings/host0',
68 'interface_name' : 'org.freedesktop.DBus.Properties'
69 },
Norman James471ab592015-08-30 22:29:40 -050070 }
Norman James90baede2015-09-02 20:32:49 -050071
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050072 #uuid
Norman Jamesad8c3d32016-02-11 15:19:01 -060073 self.Set(DBUS_NAME,"uuid",self.getUuid())
Norman James2656f332015-10-26 06:42:41 -050074 self.Set(DBUS_NAME,"reboot",0)
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050075
Norman James471ab592015-08-30 22:29:40 -050076 bus.add_signal_receiver(self.power_button_signal_handler,
Norman Jamescfc2b442015-10-31 17:31:46 -050077 dbus_interface = "org.openbmc.Button", signal_name = "Released",
Norman James8fee6f22015-10-28 12:48:43 -050078 path="/org/openbmc/buttons/power0" )
Norman Jamescfc2b442015-10-31 17:31:46 -050079 bus.add_signal_receiver(self.reset_button_signal_handler,
Norman James807ed1f2015-11-09 10:53:03 -060080 dbus_interface = "org.openbmc.Button", signal_name = "PressedLong",
Norman Jamescfc2b442015-10-31 17:31:46 -050081 path="/org/openbmc/buttons/power0" )
Kenc95eccd2015-12-19 07:02:34 +080082 bus.add_signal_receiver(self.softreset_button_signal_handler,
83 dbus_interface = "org.openbmc.Button", signal_name = "Released",
84 path="/org/openbmc/buttons/reset0" )
Norman Jamescfc2b442015-10-31 17:31:46 -050085
Norman James9e6acf92015-09-08 07:00:04 -050086 bus.add_signal_receiver(self.host_watchdog_signal_handler,
87 dbus_interface = "org.openbmc.Watchdog", signal_name = "WatchdogError")
Norman James72567ba2016-01-13 16:57:48 -060088
89 bus.add_signal_receiver(self.emergency_shutdown_signal_handler,
90 dbus_interface = "org.openbmc.SensorThresholds", signal_name = "Emergency")
91
Norman James362a80f2015-09-14 14:04:39 -050092 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
Norman James323ed972015-12-09 09:06:37 -060093 self.InterfacesAdded(name,self.properties)
Norman James471ab592015-08-30 22:29:40 -050094
Norman James9e6acf92015-09-08 07:00:04 -050095
Norman James362a80f2015-09-14 14:04:39 -050096 def getInterface(self,name):
97 o = self.dbus_objects[name]
Norman James85f050b2015-12-18 14:58:20 -060098 obj = bus.get_object(o['bus_name'],o['object_name'],introspect=False)
Norman James362a80f2015-09-14 14:04:39 -050099 return dbus.Interface(obj,o['interface_name'])
Norman Jamese2765102015-08-19 22:00:55 -0500100
Norman Jamese2765102015-08-19 22:00:55 -0500101
Norman James3f97c5d2015-08-26 17:44:14 -0500102 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500103 in_signature='', out_signature='')
104 def setIdentify(self):
105 print "Turn on identify"
Norman James362a80f2015-09-14 14:04:39 -0500106 intf = self.getInterface('identify_led')
107 intf.setOn()
Norman Jamese2765102015-08-19 22:00:55 -0500108 return None
109
Norman James3f97c5d2015-08-26 17:44:14 -0500110 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500111 in_signature='', out_signature='')
112 def clearIdentify(self):
Norman James362a80f2015-09-14 14:04:39 -0500113 print "Turn on identify"
114 intf = self.getInterface('identify_led')
115 intf.setOff()
Norman Jamese2765102015-08-19 22:00:55 -0500116 return None
117
Norman James3f97c5d2015-08-26 17:44:14 -0500118 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500119 in_signature='', out_signature='')
Norman James362a80f2015-09-14 14:04:39 -0500120 def powerOn(self):
Norman Jamese2765102015-08-19 22:00:55 -0500121 print "Turn on power and boot"
Norman James2656f332015-10-26 06:42:41 -0500122 self.Set(DBUS_NAME,"reboot",0)
Norman Jamese2765102015-08-19 22:00:55 -0500123 if (self.getPowerState()==0):
Norman James362a80f2015-09-14 14:04:39 -0500124 intf = self.getInterface('power_control')
125 intf.setPowerState(POWER_ON)
Norman Jamesc07c4732015-10-26 07:12:58 -0500126 intfwatchdog = self.getInterface('watchdog')
Adriana Kobylak025d13f2015-10-22 12:45:24 -0500127 #Start watchdog with 30s timeout per the OpenPower Host IPMI Spec
128 #Once the host starts booting, it'll reset and refresh the timer
129 intfwatchdog.set(30000)
130 intfwatchdog.start()
Norman Jamese2765102015-08-19 22:00:55 -0500131 return None
132
Norman James3f97c5d2015-08-26 17:44:14 -0500133 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500134 in_signature='', out_signature='')
Norman James362a80f2015-09-14 14:04:39 -0500135 def powerOff(self):
Norman Jamese2765102015-08-19 22:00:55 -0500136 print "Turn off power"
Adriana Kobylak5f7fe662016-02-04 12:39:06 -0600137 intfwatchdog = self.getInterface('watchdog')
138 intfwatchdog.stop()
Norman James362a80f2015-09-14 14:04:39 -0500139 intf = self.getInterface('power_control')
140 intf.setPowerState(POWER_OFF)
141 return None
142
143 @dbus.service.method(DBUS_NAME,
144 in_signature='', out_signature='')
145 def softPowerOff(self):
146 print "Soft off power"
Norman James98e1f7b2015-11-24 22:17:56 -0600147 intf = self.getInterface('host_services')
148 ## host services will call power off when ready
149 intf.SoftPowerOff()
Norman James362a80f2015-09-14 14:04:39 -0500150 return None
151
152 @dbus.service.method(DBUS_NAME,
153 in_signature='', out_signature='')
154 def reboot(self):
155 print "Rebooting"
Norman James8d2e3ef2015-11-17 19:34:25 -0600156 if self.getPowerState() == POWER_OFF:
Norman Jamescfc2b442015-10-31 17:31:46 -0500157 self.powerOn();
158 else:
159 self.Set(DBUS_NAME,"reboot",1)
Norman Jamesb4ef3182015-12-03 17:54:35 -0600160 self.powerOff()
161 return None
162
Norman Jamesb4bd9e22015-12-18 15:47:50 -0600163 @dbus.service.method(DBUS_NAME,
164 in_signature='', out_signature='')
Norman Jamesb4ef3182015-12-03 17:54:35 -0600165 def softReboot(self):
166 print "Soft Rebooting"
167 if self.getPowerState() == POWER_OFF:
168 self.powerOn();
169 else:
170 self.Set(DBUS_NAME,"reboot",1)
Norman James8d2e3ef2015-11-17 19:34:25 -0600171 self.softPowerOff()
Norman Jamese2765102015-08-19 22:00:55 -0500172 return None
173
Norman James3f97c5d2015-08-26 17:44:14 -0500174 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500175 in_signature='', out_signature='i')
176 def getPowerState(self):
Norman James362a80f2015-09-14 14:04:39 -0500177 intf = self.getInterface('power_control')
178 return intf.getPowerState()
Norman Jamese2765102015-08-19 22:00:55 -0500179
Norman Jamese2765102015-08-19 22:00:55 -0500180 ## Signal handler
Norman James362a80f2015-09-14 14:04:39 -0500181
182 def SystemStateHandler(self,state_name):
Norman Jamesf5edb9e2016-01-31 13:32:24 -0600183 if (state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"):
184 intf = self.getInterface('settings')
185 intf.Set("org.openbmc.settings.Host","system_state",state_name)
186
Norman James2656f332015-10-26 06:42:41 -0500187 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME,"reboot")==1):
Norman James362a80f2015-09-14 14:04:39 -0500188 self.powerOn()
Norman James362a80f2015-09-14 14:04:39 -0500189
Norman Jamese2765102015-08-19 22:00:55 -0500190 def power_button_signal_handler(self):
Norman James9e6acf92015-09-08 07:00:04 -0500191 # toggle power
Norman Jamese2765102015-08-19 22:00:55 -0500192 state = self.getPowerState()
Norman James2a3d20b2015-08-20 07:09:33 -0500193 if state == POWER_OFF:
Norman James362a80f2015-09-14 14:04:39 -0500194 self.powerOn()
Norman James2a3d20b2015-08-20 07:09:33 -0500195 elif state == POWER_ON:
Norman James362a80f2015-09-14 14:04:39 -0500196 self.powerOff();
Norman Jamese2765102015-08-19 22:00:55 -0500197
Norman Jamescfc2b442015-10-31 17:31:46 -0500198 def reset_button_signal_handler(self):
199 self.reboot();
Kenc95eccd2015-12-19 07:02:34 +0800200
201 def softreset_button_signal_handler(self):
202 self.softReboot();
Norman Jamescfc2b442015-10-31 17:31:46 -0500203
Norman James9e6acf92015-09-08 07:00:04 -0500204 def host_watchdog_signal_handler(self):
Norman James362a80f2015-09-14 14:04:39 -0500205 print "Watchdog Error, Hard Rebooting"
Adriana Kobylakdbc81052016-02-08 15:48:21 -0600206 self.Set(DBUS_NAME,"reboot",1)
207 self.powerOff()
Norman James72567ba2016-01-13 16:57:48 -0600208
209 def emergency_shutdown_signal_handler(self):
210 print "Emergency Shutdown!"
211 self.powerOff()
212
Norman James9e6acf92015-09-08 07:00:04 -0500213
Norman Jamese2765102015-08-19 22:00:55 -0500214
215if __name__ == '__main__':
216 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
217
Norman James5e792e32015-10-07 17:36:17 -0500218 bus = Openbmc.getDBus()
Norman James3f97c5d2015-08-26 17:44:14 -0500219 name = dbus.service.BusName(DBUS_NAME, bus)
220 obj = ChassisControlObject(bus, OBJ_NAME)
Norman James6f8d0422015-09-14 18:48:00 -0500221 mainloop = gobject.MainLoop()
Norman James81dbd352015-08-19 22:44:53 -0500222
Norman Jamese2765102015-08-19 22:00:55 -0500223 print "Running ChassisControlService"
224 mainloop.run()
225