veilleur-systemd.py
Un LED en latido más un control de servicios cada segundo: el script se vuelve un demonio systemd con Restart=always, arrancado en el arranque. El patrón de robustez para una placa embebida sin pantalla ni teclado.
Hardware
Un ODROID-M1 (Rockchip RK3568B2, 4 Cortex-A55, 4-8 Go) con Armbian o Ubuntu de Hardkernel, con M.2 NVMe, SATA y Ethernet gigabit. Opcional: LED en uno de los LED controlables por el kernel (leds sysfs) o LED GPIO con gpiozero.
Cableado
Sin cableado obligatorio; los LED del sistema están en /sys/class/leds y parpadean con una escritura simple.
Funcionamiento
El bucle corre a 1 Hz: alterna el brillo sysfs y relanza cualquier servicio declarado inactivo. La unidad systemd (simple, Restart=always) lo relanza y lo arranca en el boot.
Ejecución
En Armbian: apt install gpiod python3-gpiod; los dos chips GPIO del RK3568 (gpiochip0/gpiochip3) aparecen en gpiodetect, mapea el pin con gpioinfo.
Variantes
Añadir un watchdog hardware (systemd WatchdogSec + sd_notify), o subir el estado a un broker MQTT (pip install paho-mqtt).
veilleur-systemd.py
#!/usr/bin/env python3
# Veilleur : fait clignoter une LED "battement de coeur" et relance
# les services declares dans VEILLE. A installer en service systemd.
import subprocess
import time
from pathlib import Path
# --- config ---
LED_GLOB = "/sys/class/leds/*"
VEILLE = ["ssh", "cron"] # services a maintenir en vie
def trouver_led():
for led in sorted(Path(LED_GLOB).glob("*")):
if (led / "brightness").exists():
return led / "brightness"
return None
def maintenir():
for service in VEILLE:
r = subprocess.run(["systemctl", "is-active", "--quiet", service])
if r.returncode != 0:
print(f"{service} inactif -> redemarrage")
subprocess.run(["systemctl", "restart", service])
led = trouver_led()
print("Veilleur demarre (LED:", led, ")")
while True:
if led:
led.write_text("1" if (int(time.time()) % 2) else "0")
maintenir()
time.sleep(1)
# Installation (en root) :
# cp veilleur-systemd.py /usr/local/bin/veilleur.py && chmod +x ...
# puis unite systemd de type simple avec Restart=always (voir doc).