Skip to content

Instantly share code, notes, and snippets.

@claabs
Created November 7, 2025 02:53
Show Gist options
  • Save claabs/7e2656cb427de256340c1df7ef235175 to your computer and use it in GitHub Desktop.
Save claabs/7e2656cb427de256340c1df7ef235175 to your computer and use it in GitHub Desktop.
Super basic HTTP service to get Batocera power status and shutdown control
#!/usr/bin/env python3
from http.server import BaseHTTPRequestHandler, HTTPServer
import subprocess
PORT = 8146
class RequestHandler(BaseHTTPRequestHandler):
def _send_json(self, data, code=200):
body = data.encode("utf-8")
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.send_header("Connection", "close")
self.end_headers()
self.wfile.write(body)
def do_GET(self):
if self.path == "/health":
self._send_json('{"status":"on"}')
else:
self._send_json('{"error":"not_found"}', code=404)
def do_POST(self):
if self.path == "/shutdown":
self._send_json('{"status":"shutting_down"}')
subprocess.Popen(["batocera-es-swissknife", "--shutdown"])
else:
self._send_json('{"error":"not_found"}', code=404)
# Silence default logging
def log_message(self, *args):
return
if __name__ == "__main__":
server = HTTPServer(("0.0.0.0", PORT), RequestHandler)
print(f"Serving on port {PORT}")
server.serve_forever()
#!/bin/bash
SERVICE_NAME=$(basename "$0" .${0##*.})
SCRIPT_PATH="/userdata/system/scripts/power.py"
PIDFILE="/userdata/system/cache/$SERVICE_NAME.pid"
LOGFILE="/userdata/system/logs/$SERVICE_NAME.log"
STARTUP_WAIT=1
STOP_TIMEOUT=3
start() {
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "$SERVICE_NAME already running (pid $(cat "$PIDFILE"))"
return 0
fi
mkdir -p "$(dirname "$LOGFILE")"
echo "Starting $SERVICE_NAME..."
# Start detached using setsid + nohup
setsid nohup "$SCRIPT_PATH" >> "$LOGFILE" 2>&1 &
pid=$!
echo "$pid" > "$PIDFILE"
# Short startup health check
echo "Waiting $STARTUP_WAIT seconds for process to initialize. .."
sleep $STARTUP_WAIT
if ! kill -0 "$pid" 2>/dev/null; then
echo "ERROR: $SERVICE_NAME failed to start"
rm -f "$PIDFILE"
return 1
fi
echo "$SERVICE_NAME started (pid $pid)"
}
stop() {
if [ -f "$PIDFILE" ]; then
pid=$(cat "$PIDFILE")
if kill -0 "$pid" 2>/dev/null; then
echo "Stopping $SERVICE_NAME (pid $pid) ..."
# Kill entire process group
kill -TERM -"$pid"
# Wait a short time
timeout=$STOP_TIMEOUT
while kill -0 "$pid" 2>/dev/null && [ $timeout -gt 0 ]; do
sleep 1
timeout=$((timeout-1))
done
# Force kill if still running
if kill -0 "$pid" 2>/dev/null; then
echo "Process group did not stop, sending SIGKILL"
kill -9 -"$pid"
fi
fi
rm -f "$PIDFILE"
else
echo "PID file not found, attempting fallback kill ..."
# Fallback: try to kill by matching the flatpak invocation
pkill -9 -f "$SCRIPT_PATH" || true
fi
}
status() {
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "running"
return 0
fi
echo "stopped"
return 1
}
start_on_boot() {
start
}
# Script entrypoint
if [ $# -eq 0 ]; then
echo "Usage: $SERVICE_NAME start|stop|status|start_on_boot"
exit 1
fi
if [[ $(type -t "$1") == function ]]; then
FUNCTION="$1"
shift
$FUNCTION "$@"
else
echo "ERROR: '$1' is not defined"
echo "Usage: $SERVICE_NAME start|stop|status|start_on_boot"
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment