Arranque y parada automática del servidor Docker según la presencia de la pantalla
Una de las cosas que hemos observado durante las pruebas con nuestra pantalla Elecrow ESP32-P4 es que el servidor crow-ha, encargado de gestionar la comunicación entre el panel y Home Assistant, sigue funcionando aunque apaguemos la pantalla. Y eso significa mantener en ejecución Chromium, sus procesos auxiliares y el resto de servicios asociados sin que haya nadie al otro lado que los necesite.
Como ya que estamos intentando optimizar los recursos de nuestra Raspberry Pi, ¿por qué no detener automáticamente el contenedor cuando la pantalla esté apagada y volver a arrancarlo de froma automática cuando la encendamos?
La solución ha resultado bastante sencilla y, además, no necesita ninguna integración adicional de Home Assistant.
Identificando la pantalla en nuestra red
Lo primero fue localizar la dirección IP de la Elecrow. Para ello revisamos los registros del contenedor crow-ha, donde encontramos la conexión WebSocket de nuestro panel:
1 | [WS] client 2 connected: esp32-e8f60ae9c6f6 1024x600 from ::ffff:192.168.1.65 |
Así identificamos la dirección IP 192.168.1.65 y, consultando la tabla ARP de la Raspberry Pi, pudimos asociarla a su dirección MAC:
1 | 192.168.1.65 dev wlan0 lladdr 14:c1:9f:f5:4c:fc REACHABLE |
Para evitar que la dirección cambie en el futuro, en nuestro router FRITZ!Box reservamos la IP 192.168.1.65 para la pantalla.
Después comprobamos que el panel respondía a las peticiones ICMP cuando estaba encendido y que dejaba de hacerlo al apagarlo. Ya teníamos, por tanto, un mecanismo bastante fiable para conocer su estado sin necesidad de comunicarnos con el propio servidor crow-ha.
Creando un vigilante con systemd
En lugar de recurrir a una automatización de Home Assistant, hemos preferido utilizar un pequeño script ejecutado directamente en la Raspberry Pi. De esta manera, el sistema puede arrancar o detener Docker incluso cuando el propio contenedor está parado.
El script /usr/local/sbin/crow-ha-watchdog.sh realiza las siguientes operaciones:
- Comprueba si la pantalla responde a un ping.
- Si está disponible, arranca
crow-hacuando el contenedor está detenido. - Si no responde, incrementa un contador de fallos.
- Tras cuatro comprobaciones consecutivas sin respuesta, detiene el contenedor.
- Si vuelve a detectar la pantalla, reinicia el contador y arranca el servidor cuando sea necesario.
El contenido del script es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #!/bin/bash PANEL_IP="192.168.1.65" CONTAINER="crow-ha" COUNT_FILE="/run/crow-ha-watchdog.misses" MAX_MISSES=4 DOCKER="$(command -v docker)" PING="$(command -v ping)" if [ -z "$DOCKER" ] || [ -z "$PING" ]; then logger -t crow-ha-watchdog "No encuentro docker o ping" exit 1 fi if ! "$DOCKER" inspect "$CONTAINER" >/dev/null 2>&1; then logger -t crow-ha-watchdog "No puedo consultar el contenedor $CONTAINER" exit 1 fi RUNNING=$("$DOCKER" inspect -f '{{.State.Running}}' "$CONTAINER") if "$PING" -c 1 -W 2 "$PANEL_IP" >/dev/null 2>&1; then rm -f "$COUNT_FILE" if [ "$RUNNING" != "true" ]; then "$DOCKER" start "$CONTAINER" logger -t crow-ha-watchdog "Pantalla detectada: arrancando $CONTAINER" fi else COUNT=$(cat "$COUNT_FILE" 2>/dev/null || echo 0) COUNT=$((COUNT + 1)) echo "$COUNT" > "$COUNT_FILE" if [ "$COUNT" -ge "$MAX_MISSES" ] && [ "$RUNNING" = "true" ]; then "$DOCKER" stop "$CONTAINER" logger -t crow-ha-watchdog "Pantalla desconectada: deteniendo $CONTAINER" rm -f "$COUNT_FILE" fi fi |
Una vez guardado, le damos permisos de ejecución:
1 | sudo chmod 755 /usr/local/sbin/crow-ha-watchdog.sh |
Programando las comprobaciones
Para ejecutar el script periódicamente hemos creado dos unidades de systemd.
La primera, /etc/systemd/system/crow-ha-watchdog.service, define el servicio que ejecuta nuestro script:
1 2 3 4 5 6 | [Unit] Description=Vigilante de presencia de la pantalla Elecrow [Service] Type=oneshot ExecStart=/usr/local/sbin/crow-ha-watchdog.sh |
La segunda, /etc/systemd/system/crow-ha-watchdog.timer, establece la periodicidad:
1 2 3 4 5 6 7 8 9 10 | [Unit] Description=Comprobar periodicamente si la pantalla Elecrow está conectada [Timer] OnBootSec=30s OnUnitActiveSec=30s AccuracySec=5s [Install] WantedBy=timers.target |
Con ello, systemd ejecutará el vigilante cada 30 segundos, comenzando 30 segundos después del arranque de la Raspberry Pi.
Finalmente, activamos el temporizador:
1 2 | sudo systemctl daemon-reload sudo systemctl enable --now crow-ha-watchdog.timer |
Podemos comprobar que está funcionando mediante:
1 | systemctl status crow-ha-watchdog.timer |
Y consultar las operaciones realizadas por el vigilante con:
1 | journalctl -t crow-ha-watchdog -n 20 --no-pager |
Comprobando que funciona el servicio de aogado / encendido
Lo mejor de todo es que no nos hemos limitado a confiar en que el invento funcione. Hemos realizado pruebas reales apagando y encendiendo la pantalla.
Esta es la secuencia que hemos obtenido en nuestros registros:
1 2 | 16:32:10 Pantalla desconectada: deteniendo crow-ha 16:33:42 Pantalla detectada: arrancando crow-ha |
También hemos comprobado con docker ps -a que el contenedor pasa correctamente de estado Up a Exited (0) y vuelve a arrancar cuando la pantalla reaparece en la red.
En resumen, el comportamiento queda así:
| Estado de la pantalla | Acción del vigilante |
|---|---|
| Encendida y conectada | Arranca crow-ha si está detenido. |
| Apagada o desconectada | Acumula cuatro fallos consecutivos. |
| Sin respuesta durante cuatro comprobaciones | Detiene crow-ha. |
| Vuelve a conectarse | Arranca automáticamente crow-ha. |
La solución tiene otra ventaja: no depende de Home Assistant, por lo que seguirá funcionando aunque este último tenga problemas o esté reiniciándose. Tampoco hemos tenido que modificar el código de crow-ha ni su configuración Docker Compose.
Y así conseguimos algo bastante razonable: que nuestra Raspberry Pi no tenga que trabajar para una pantalla de ELECROW que está apagada. Que bastante tiene ya con todo lo demás.
72
Como era de esperar, después de dejar nuestro kit de impresión 3D «olvidado» en la buhardilla durante bastante tiempo, hemos descubierto que nos falta alguna pieza y que, por mucho que lo hemos intentado, no conseguimos montar la carcasa que teníamos prevista.
Así que, para salir del paso, hemos tenido que buscar una solución alternativa que permita «descansar» cómodamente a nuestra pantalla ELECROW. De momento, no hemos encontrado nada mejor que un sencillo atril que teníamos por ahí, y que está cumpliendo dignamente su cometido. No es la solución más elegante ni la definitiva, pero al menos nuestra pantalla ya tiene dónde apoyarse mientras seguimos buscando las piezas perdidas… ¡o una alternativa mejor!