Fix for Power Restore Policy

This fix is to make the Restore_last_state of Power Restore Policy
to working properly.

eg:- if the last state is Host_powered_on/off and system goes for pdu
     reboot then system should reach to the Host_Powred_On/Off state.

Fixes openbmc/openbmc#196

Change-Id: If4bdb65a21452d7aa041312fcdbb1daa1b1b0424
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/pystatemgr/discover_system_state.py b/pystatemgr/discover_system_state.py
index 7cdb4c1..f793314 100644
--- a/pystatemgr/discover_system_state.py
+++ b/pystatemgr/discover_system_state.py
@@ -34,6 +34,11 @@
         'object_name': '/org/openbmc/settings/host0',
         'interface_name': 'org.freedesktop.DBus.Properties'
     },
+    'system': {
+        'bus_name': 'org.openbmc.managers.System',
+        'object_name': '/org/openbmc/managers/System',
+        'interface_name': 'org.freedesktop.DBus.Properties'
+    },
 }
 
 
@@ -61,18 +66,19 @@
     intf = getInterface(bus, dbus_objects, 'occstatus1')
     intf.setValue("Enabled")
 else:
-    ## Power is off, so check power policy
+    # Power is off, so check power policy
     settings_intf = getInterface(bus, dbus_objects, 'settings')
-    system_state = settings_intf.Get(
-        "org.openbmc.settings.Host", "system_state")
-    power_policy = settings_intf.Get(
-        "org.openbmc.settings.Host", "power_policy")
-
-    print "Last System State: "+system_state+";  Power Policy: "+power_policy
+    system_intf = getInterface(bus, dbus_objects, 'system')
+    system_last_state = system_intf.Get("org.openbmc.managers.System",
+                                        "system_last_state")
+    power_policy = settings_intf.Get("org.openbmc.settings.Host",
+                                     "power_policy")
+    print "Last System State:"+system_last_state+"Power Policy:"+power_policy
     chassis_intf = getInterface(bus, dbus_objects, 'chassis')
+
     if (power_policy == "ALWAYS_POWER_ON" or
-            (power_policy == "RESTORE_LAST_STATE" and
-             system_state == "HOST_POWERED_ON")):
+       (power_policy == "RESTORE_LAST_STATE" and
+            system_last_state == "HOST_POWERED_ON")):
         chassis_intf.powerOn()
 
 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
diff --git a/pysystemmgr/system_manager.py b/pysystemmgr/system_manager.py
index 4f9b261..a26c325 100644
--- a/pysystemmgr/system_manager.py
+++ b/pysystemmgr/system_manager.py
@@ -18,6 +18,9 @@
 INTF_SENSOR = 'org.openbmc.SensorValue'
 INTF_ITEM = 'org.openbmc.InventoryItem'
 
+SYS_STATE_FILE = '/var/lib/obmc/last-system-state'
+POWER_OFF = "0"
+
 
 class SystemManager(DbusProperties, DbusObjectManager):
     def __init__(self, bus, obj_name):
@@ -32,9 +35,16 @@
         bus.add_signal_receiver(
             self.SystemStateHandler, signal_name="GotoSystemState")
 
-        self.Set(DBUS_NAME, "current_state", "")
+        bus.add_signal_receiver(
+            self.chassisPowerStateHandler,
+            dbus_interface="org.freedesktop.DBus.Properties",
+            signal_name="PropertiesChanged",
+            path="/org/openbmc/control/power0")
 
-        ## replace symbolic path in ID_LOOKUP
+        self.Set(DBUS_NAME, "current_state", "")
+        self.Set(DBUS_NAME, "system_last_state", POWER_OFF)
+        self.import_system_state_from_disk()
+        # replace symbolic path in ID_LOOKUP
         for category in System.ID_LOOKUP:
             for key in System.ID_LOOKUP[category]:
                 val = System.ID_LOOKUP[category][key]
@@ -46,6 +56,12 @@
 
         print "SystemManager Init Done"
 
+    def chassisPowerStateHandler(self, interface_name, changed_properties,
+                                 invalidated_properties):
+        value = changed_properties.get('state')
+        if value is not None:
+            self.write_to_disk_and_update(str(value))
+
     def SystemStateHandler(self, state_name):
         print "Running System State: "+state_name
 
@@ -71,6 +87,24 @@
             print "SystemManager Goto System State: "+new_state_name
             self.SystemStateHandler(new_state_name)
 
+    def import_system_state_from_disk(self):
+        state = str(POWER_OFF)
+        try:
+            with open(SYS_STATE_FILE, 'r+') as f:
+                state = f.readline().rstrip('\n')
+        except IOError:
+            pass
+        self.Set(DBUS_NAME, "system_last_state", state)
+        return state
+
+    def write_to_disk_and_update(self, state):
+        try:
+            with open(SYS_STATE_FILE, 'w+') as f:
+                f.write(str(state))
+                self.Set(DBUS_NAME, "system_last_state", state)
+        except IOError:
+            pass
+
     @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s')
     def getSystemState(self):
         return self.Get(DBUS_NAME, "current_state")