Improve set_server_power implementation
[libremanage.git] / libremanage
index 283d57506f9390026efa87701cd86bf7ec35bdeb..4f4312f9b3ac2089f7b0a874f42215922b8a90f1 100755 (executable)
@@ -46,6 +46,7 @@ import sys
 import json
 import functools
 import subprocess
+import time
 import os.path
 
 def open_ssh(server, command, force_tty=False):
@@ -69,25 +70,54 @@ def get_server_handle(name):
 
     return server
 
+def gpio_export(server, pin, mode):
+    if mode:
+        open_ssh(server, "echo " + str(pin) + " > /sys/class/gpio/export")
+        open_ssh(server, "echo out > /sys/class/gpio/gpio" + str(pin) + "/direction")
+    else:
+        open_ssh(server, "echo " + str(pin) + " > /sys/class/gpio/unexport")
+
+def gpio_write(server, pin, value):
+    open_ssh(server, "echo " + str(value) + " > /sys/class/gpio/gpio" + str(pin) + "/value")
+
+def power_button(server, pin, state):
+    # Hold down the power to force off (via the EC),
+    # or just flick on to turn on
+
+    gpio_write(server, pin, 1)
+    time.sleep(2 if state == POWER_OFF else 0.5)
+    gpio_write(server, pin, 0)
+
+POWER_OFF    = 0
+POWER_ON     = 1
+POWER_REBOOT = 2
+
 def set_server_power(state, server):
     conf = server["power"]
 
-    # Set invert to write LOW for power on and HIGH for off
-    if conf["invert"]:
-        state = 1 - state
-
+    # TODO: Invert
     # Export pin, configure, write value, unexport
-    open_ssh(server, "echo " + str(conf["pin"]) + " > /sys/class/gpio/export")
-    open_ssh(server, "echo out > /sys/class/gpio/gpio" + str(conf["pin"]) + "/direction")
-    open_ssh(server, "echo " + str(state) + " > /sys/class/gpio/gpio" + str(conf["pin"]) + "/value")
-    open_ssh(server, "echo " + str(conf["pin"]) + " > /sys/class/gpio/unexport")
+    pin = conf["pin"]
+
+    gpio_export(server, pin, True)
+
+    # Act like a power button
+
+    if state == POWER_OFF or state == POWER_ON:
+        power_button(server, pin, state)
+    elif state == POWER_REBOOT:
+        # Requires that we already be online.
+        power_button(server, pin, POWER_OFF)
+        power_button(server, pin, POWER_ON)
+
+    gpio_export(server, pin, False)
 
 COMMANDS = {
         # Power managemment
 
-        "shutdown": functools.partial(set_server_power, 0),
-        "poweron": functools.partial(set_server_power, 1),
-        "reboot": lambda s: (set_server_power(0, s), set_server_power(1, s)),
+        "shutdown": functools.partial(set_server_power, POWER_OFF),
+        "poweron": functools.partial(set_server_power, POWER_ON),
+        "reboot": functools.partial(set_server_power, POWER_REBOOT),
 
         # TTY access (or keyboard if wired as such)