blob: 376e0e9090cab925380d9c11ce08be0aa46f6fdd [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 -05005import gobject
Norman Jamese2765102015-08-19 22:00:55 -05006import dbus
7import dbus.service
8import dbus.mainloop.glib
Brad Bishop84e73b52016-05-12 15:57:52 -04009from obmc.dbuslib.bindings import get_dbus, DbusProperties, DbusObjectManager
Norman Jamese2765102015-08-19 22:00:55 -050010
Norman James3f97c5d2015-08-26 17:44:14 -050011DBUS_NAME = 'org.openbmc.control.Chassis'
Norman James8fee6f22015-10-28 12:48:43 -050012OBJ_NAME = '/org/openbmc/control/chassis0'
Norman Jamesa3e47c42015-10-18 14:43:10 -050013CONTROL_INTF = 'org.openbmc.Control'
Norman James3f97c5d2015-08-26 17:44:14 -050014
Norman Jamesad8c3d32016-02-11 15:19:01 -060015MACHINE_ID = '/etc/machine-id'
16
Norman James2a3d20b2015-08-20 07:09:33 -050017POWER_OFF = 0
18POWER_ON = 1
19
Norman James9e6acf92015-09-08 07:00:04 -050020BOOTED = 100
21
Brad Bishop84e73b52016-05-12 15:57:52 -040022class ChassisControlObject(DbusProperties,DbusObjectManager):
Norman Jamesad8c3d32016-02-11 15:19:01 -060023 def getUuid(self):
24 uuid = "";
25 try:
26 with open(MACHINE_ID) as f:
27 data = f.readline().rstrip('\n')
28 if (len(data) == 32):
29 uuid = data
30 else:
31 print "ERROR: UUID is not formatted correctly: "+data
32 except:
33 print "ERROR: Unable to open uuid file: "+MACHINE_ID
34
35 return uuid
36
Norman Jamese2765102015-08-19 22:00:55 -050037 def __init__(self,bus,name):
Norman James471ab592015-08-30 22:29:40 -050038 self.dbus_objects = { }
Brad Bishop84e73b52016-05-12 15:57:52 -040039 DbusProperties.__init__(self)
40 DbusObjectManager.__init__(self)
Norman James9e6acf92015-09-08 07:00:04 -050041 dbus.service.Object.__init__(self,bus,name)
Norman James90baede2015-09-02 20:32:49 -050042 ## load utilized objects
Norman James362a80f2015-09-14 14:04:39 -050043 self.dbus_objects = {
44 'power_control' : {
45 'bus_name' : 'org.openbmc.control.Power',
Norman Jamesa3e47c42015-10-18 14:43:10 -050046 'object_name' : '/org/openbmc/control/power0',
Norman James362a80f2015-09-14 14:04:39 -050047 'interface_name' : 'org.openbmc.control.Power'
48 },
49 'identify_led' : {
Norman Jamesa3e47c42015-10-18 14:43:10 -050050 'bus_name' : 'org.openbmc.control.led',
Adriana Kobylak9c751042016-02-09 13:44:32 -060051 'object_name' : '/org/openbmc/control/led/identify',
Norman James362a80f2015-09-14 14:04:39 -050052 'interface_name' : 'org.openbmc.Led'
Norman Jamesc07c4732015-10-26 07:12:58 -050053 },
54 'watchdog' : {
55 'bus_name' : 'org.openbmc.watchdog.Host',
Norman James8fee6f22015-10-28 12:48:43 -050056 'object_name' : '/org/openbmc/watchdog/host0',
Norman Jamesc07c4732015-10-26 07:12:58 -050057 'interface_name' : 'org.openbmc.Watchdog'
Norman James98e1f7b2015-11-24 22:17:56 -060058 },
59 'host_services' : {
60 'bus_name' : 'org.openbmc.HostServices',
61 'object_name' : '/org/openbmc/HostServices',
62 'interface_name' : 'org.openbmc.HostServices'
63 },
Norman Jamesf5edb9e2016-01-31 13:32:24 -060064 'settings' : {
65 'bus_name' : 'org.openbmc.settings.Host',
66 'object_name' : '/org/openbmc/settings/host0',
67 'interface_name' : 'org.freedesktop.DBus.Properties'
68 },
Norman James471ab592015-08-30 22:29:40 -050069 }
Norman James90baede2015-09-02 20:32:49 -050070
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050071 #uuid
Norman Jamesad8c3d32016-02-11 15:19:01 -060072 self.Set(DBUS_NAME,"uuid",self.getUuid())
Norman James2656f332015-10-26 06:42:41 -050073 self.Set(DBUS_NAME,"reboot",0)
Adriana Kobylak08d3bdb2015-10-20 16:59:14 -050074
Norman James471ab592015-08-30 22:29:40 -050075 bus.add_signal_receiver(self.power_button_signal_handler,
Norman Jamescfc2b442015-10-31 17:31:46 -050076 dbus_interface = "org.openbmc.Button", signal_name = "Released",
Norman James8fee6f22015-10-28 12:48:43 -050077 path="/org/openbmc/buttons/power0" )
Norman Jamescfc2b442015-10-31 17:31:46 -050078 bus.add_signal_receiver(self.reset_button_signal_handler,
Norman James807ed1f2015-11-09 10:53:03 -060079 dbus_interface = "org.openbmc.Button", signal_name = "PressedLong",
Norman Jamescfc2b442015-10-31 17:31:46 -050080 path="/org/openbmc/buttons/power0" )
Kenc95eccd2015-12-19 07:02:34 +080081 bus.add_signal_receiver(self.softreset_button_signal_handler,
82 dbus_interface = "org.openbmc.Button", signal_name = "Released",
83 path="/org/openbmc/buttons/reset0" )
Norman Jamescfc2b442015-10-31 17:31:46 -050084
Norman James9e6acf92015-09-08 07:00:04 -050085 bus.add_signal_receiver(self.host_watchdog_signal_handler,
86 dbus_interface = "org.openbmc.Watchdog", signal_name = "WatchdogError")
Norman James72567ba2016-01-13 16:57:48 -060087
88 bus.add_signal_receiver(self.emergency_shutdown_signal_handler,
89 dbus_interface = "org.openbmc.SensorThresholds", signal_name = "Emergency")
90
Norman James362a80f2015-09-14 14:04:39 -050091 bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
Norman James323ed972015-12-09 09:06:37 -060092 self.InterfacesAdded(name,self.properties)
Norman James471ab592015-08-30 22:29:40 -050093
Norman James9e6acf92015-09-08 07:00:04 -050094
Norman James362a80f2015-09-14 14:04:39 -050095 def getInterface(self,name):
96 o = self.dbus_objects[name]
Norman James85f050b2015-12-18 14:58:20 -060097 obj = bus.get_object(o['bus_name'],o['object_name'],introspect=False)
Norman James362a80f2015-09-14 14:04:39 -050098 return dbus.Interface(obj,o['interface_name'])
Norman Jamese2765102015-08-19 22:00:55 -050099
Norman Jamese2765102015-08-19 22:00:55 -0500100
Norman James3f97c5d2015-08-26 17:44:14 -0500101 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500102 in_signature='', out_signature='')
103 def setIdentify(self):
104 print "Turn on identify"
Norman James362a80f2015-09-14 14:04:39 -0500105 intf = self.getInterface('identify_led')
106 intf.setOn()
Norman Jamese2765102015-08-19 22:00:55 -0500107 return None
108
Norman James3f97c5d2015-08-26 17:44:14 -0500109 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500110 in_signature='', out_signature='')
111 def clearIdentify(self):
Norman James362a80f2015-09-14 14:04:39 -0500112 print "Turn on identify"
113 intf = self.getInterface('identify_led')
114 intf.setOff()
Norman Jamese2765102015-08-19 22:00:55 -0500115 return None
116
Norman James3f97c5d2015-08-26 17:44:14 -0500117 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500118 in_signature='', out_signature='')
Norman James362a80f2015-09-14 14:04:39 -0500119 def powerOn(self):
Norman Jamese2765102015-08-19 22:00:55 -0500120 print "Turn on power and boot"
Norman James2656f332015-10-26 06:42:41 -0500121 self.Set(DBUS_NAME,"reboot",0)
Norman Jamese2765102015-08-19 22:00:55 -0500122 if (self.getPowerState()==0):
Norman James362a80f2015-09-14 14:04:39 -0500123 intf = self.getInterface('power_control')
124 intf.setPowerState(POWER_ON)
Norman Jamesc07c4732015-10-26 07:12:58 -0500125 intfwatchdog = self.getInterface('watchdog')
Adriana Kobylak025d13f2015-10-22 12:45:24 -0500126 #Start watchdog with 30s timeout per the OpenPower Host IPMI Spec
127 #Once the host starts booting, it'll reset and refresh the timer
128 intfwatchdog.set(30000)
129 intfwatchdog.start()
Norman Jamese2765102015-08-19 22:00:55 -0500130 return None
131
Norman James3f97c5d2015-08-26 17:44:14 -0500132 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500133 in_signature='', out_signature='')
Norman James362a80f2015-09-14 14:04:39 -0500134 def powerOff(self):
Norman Jamese2765102015-08-19 22:00:55 -0500135 print "Turn off power"
Adriana Kobylak5f7fe662016-02-04 12:39:06 -0600136 intfwatchdog = self.getInterface('watchdog')
137 intfwatchdog.stop()
Norman James362a80f2015-09-14 14:04:39 -0500138 intf = self.getInterface('power_control')
139 intf.setPowerState(POWER_OFF)
140 return None
141
142 @dbus.service.method(DBUS_NAME,
143 in_signature='', out_signature='')
144 def softPowerOff(self):
145 print "Soft off power"
Norman James98e1f7b2015-11-24 22:17:56 -0600146 intf = self.getInterface('host_services')
147 ## host services will call power off when ready
148 intf.SoftPowerOff()
Norman James362a80f2015-09-14 14:04:39 -0500149 return None
150
151 @dbus.service.method(DBUS_NAME,
152 in_signature='', out_signature='')
153 def reboot(self):
154 print "Rebooting"
Norman James8d2e3ef2015-11-17 19:34:25 -0600155 if self.getPowerState() == POWER_OFF:
Norman Jamescfc2b442015-10-31 17:31:46 -0500156 self.powerOn();
157 else:
158 self.Set(DBUS_NAME,"reboot",1)
Norman Jamesb4ef3182015-12-03 17:54:35 -0600159 self.powerOff()
160 return None
161
Norman Jamesb4bd9e22015-12-18 15:47:50 -0600162 @dbus.service.method(DBUS_NAME,
163 in_signature='', out_signature='')
Norman Jamesb4ef3182015-12-03 17:54:35 -0600164 def softReboot(self):
165 print "Soft Rebooting"
166 if self.getPowerState() == POWER_OFF:
167 self.powerOn();
168 else:
169 self.Set(DBUS_NAME,"reboot",1)
Norman James8d2e3ef2015-11-17 19:34:25 -0600170 self.softPowerOff()
Norman Jamese2765102015-08-19 22:00:55 -0500171 return None
172
Norman James3f97c5d2015-08-26 17:44:14 -0500173 @dbus.service.method(DBUS_NAME,
Norman Jamese2765102015-08-19 22:00:55 -0500174 in_signature='', out_signature='i')
175 def getPowerState(self):
Norman James362a80f2015-09-14 14:04:39 -0500176 intf = self.getInterface('power_control')
177 return intf.getPowerState()
Norman Jamese2765102015-08-19 22:00:55 -0500178
Norman Jamese2765102015-08-19 22:00:55 -0500179 ## Signal handler
Norman James362a80f2015-09-14 14:04:39 -0500180
181 def SystemStateHandler(self,state_name):
Norman Jamesf5edb9e2016-01-31 13:32:24 -0600182 if (state_name == "HOST_POWERED_OFF" or state_name == "HOST_POWERED_ON"):
183 intf = self.getInterface('settings')
184 intf.Set("org.openbmc.settings.Host","system_state",state_name)
185
Norman James2656f332015-10-26 06:42:41 -0500186 if (state_name == "HOST_POWERED_OFF" and self.Get(DBUS_NAME,"reboot")==1):
Norman James362a80f2015-09-14 14:04:39 -0500187 self.powerOn()
Norman James362a80f2015-09-14 14:04:39 -0500188
Norman Jamese2765102015-08-19 22:00:55 -0500189 def power_button_signal_handler(self):
Norman James9e6acf92015-09-08 07:00:04 -0500190 # toggle power
Norman Jamese2765102015-08-19 22:00:55 -0500191 state = self.getPowerState()
Norman James2a3d20b2015-08-20 07:09:33 -0500192 if state == POWER_OFF:
Norman James362a80f2015-09-14 14:04:39 -0500193 self.powerOn()
Norman James2a3d20b2015-08-20 07:09:33 -0500194 elif state == POWER_ON:
Norman James362a80f2015-09-14 14:04:39 -0500195 self.powerOff();
Norman Jamese2765102015-08-19 22:00:55 -0500196
Norman Jamescfc2b442015-10-31 17:31:46 -0500197 def reset_button_signal_handler(self):
198 self.reboot();
Kenc95eccd2015-12-19 07:02:34 +0800199
200 def softreset_button_signal_handler(self):
201 self.softReboot();
Norman Jamescfc2b442015-10-31 17:31:46 -0500202
Norman James9e6acf92015-09-08 07:00:04 -0500203 def host_watchdog_signal_handler(self):
Norman James362a80f2015-09-14 14:04:39 -0500204 print "Watchdog Error, Hard Rebooting"
Adriana Kobylakdbc81052016-02-08 15:48:21 -0600205 self.Set(DBUS_NAME,"reboot",1)
206 self.powerOff()
Norman James72567ba2016-01-13 16:57:48 -0600207
208 def emergency_shutdown_signal_handler(self):
209 print "Emergency Shutdown!"
210 self.powerOff()
211
Norman James9e6acf92015-09-08 07:00:04 -0500212
Norman Jamese2765102015-08-19 22:00:55 -0500213
214if __name__ == '__main__':
215 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
216
Brad Bishop84e73b52016-05-12 15:57:52 -0400217 bus = get_dbus()
Norman James3f97c5d2015-08-26 17:44:14 -0500218 name = dbus.service.BusName(DBUS_NAME, bus)
219 obj = ChassisControlObject(bus, OBJ_NAME)
Norman James6f8d0422015-09-14 18:48:00 -0500220 mainloop = gobject.MainLoop()
Norman James81dbd352015-08-19 22:44:53 -0500221
Norman Jamese2765102015-08-19 22:00:55 -0500222 print "Running ChassisControlService"
223 mainloop.run()
224