indi-allsky Watchdog: Automatischer Neustart bei Kamera-Problemen mit systemd und Bash

Zickige USB-Kameras wie die ZWO ASI678MC, billig gemachte Kabel, Temperaturschwankungen: All-Sky-Kameras auf Raspberry-Pi-Basis sind technisch anspruchsvoll. Auch stabile Setups mit indi-allsky können in einen Zustand geraten, in dem keine neuen Bilder mehr erzeugt werden – ohne dass der Prozess selbst abstürzt.

Dieser Beitrag zeigt eine robuste, praxiserprobte Watchdog-Lösung, die unabhängig von indi-allsky-Interna arbeitet:
Ein externer Watchdog überwacht die tatsächliche Bildproduktion (JPGs) und startet indi-allsky automatisch neu, sobald der Datenfluss stockt. Optional inklusive E-Mail-Benachrichtigung.

Warum ein externer Watchdog für indi-allsky sinnvoll ist

indi-allsky selbst erkennt Kamera-Hänger meist nur indirekt. In vielen Fällen läuft der Prozess weiter, während einzelne Threads blockieren. Klassische Mechanismen wie systemd-Restart oder interne Statusmeldungen greifen dann nicht zuverlässig.

Ein externer Watchdog hat entscheidende Vorteile:

  • er bewertet reales Output-Verhalten (existierende JPGs)
  • er ist unabhängig von INDI-States, USB-Events oder Threads
  • er funktioniert auch bei „halb toten“ Prozessen
  • er ist transparent und leicht anpassbar

Grundidee des Watchdogs

Das Prinzip ist bewusst einfach:

  • Suche das zeitlich neueste JPG
  • Prüfe, wie alt es ist
  • Wenn seit X Minuten kein neues Bild erzeugt wurde:
  • sende eine Mail
  • starte indi-allsky neu
  • verhindere Doppeltrigger und Mail-Spam

Voraussetzungen

indi-allsky läuft als systemd-User-Service

  • Bilder werden als JPG gespeichert
  • Mailversand per mail funktioniert bereits
  • Raspberry Pi OS / Linux mit systemd

Watchdog-Skript erstellen

Das Skript übernimmt die komplette Logik.

 nano ~/indi-allsky-watchdog.sh

Inhalt – mail@domain.tdl bitte gegen die korrekte Mailadresse austauschen.

#!/bin/bash

# ==================================================
# Konfiguration
# ==================================================
IMAGE_DIR="/var/www/html/allsky/images"
MAX_AGE_MINUTES=5
MAIL_TO="mail@domain.tld"

LOCK_FILE="/tmp/indi-allsky-watchdog.lock"
STATE_FILE="/tmp/indi-allsky-watchdog.last"

# ==================================================
# Lock gegen parallele Ausführung
# ==================================================
exec 9>"$LOCK_FILE" || exit 1
flock -n 9 || exit 0

# ==================================================
# Zeitpunkt des letzten JPGs ermitteln
# ==================================================
LAST_IMAGE_TIME=$(find "$IMAGE_DIR" \
    -type f \
    -name "*.jpg" \
    -printf '%T@\n' 2>/dev/null \
    | sort -n \
    | tail -1)

# Falls keine Bilder gefunden werden
[ -z "$LAST_IMAGE_TIME" ] && exit 0

# ==================================================
# Alter des letzten Bildes berechnen
# ==================================================
NOW=$(date +%s)
LAST=${LAST_IMAGE_TIME%.*}
AGE_MIN=$(( (NOW - LAST) / 60 ))

# ==================================================
# Prüfen: Grenze überschritten?
# ==================================================
if [ "$AGE_MIN" -lt "$MAX_AGE_MINUTES" ]; then
    exit 0
fi

# ==================================================
# Rate-Limit: nur eine Mail pro Ereignis
# ==================================================
if [ -f "$STATE_FILE" ]; then
    LAST_STATE=$(cat "$STATE_FILE")
    if [ "$LAST_STATE" = "$LAST" ]; then
        exit 0
    fi
fi

echo "$LAST" > "$STATE_FILE"

# ==================================================
# Benachrichtigung + Neustart
# ==================================================
echo -e "indi-allsky Watchdog ausgelöst\n
Seit ${AGE_MIN} Minuten kein neues JPG.\n
Host: $(hostname)\n
Zeit: $(date)\n
Dienst wird neu gestartet." \
| mail -s "indi-allsky Watchdog: Neustart auf $(hostname)" "$MAIL_TO"

systemctl --user restart indi-allsky

Skript ausführbar machen

 chmod +x ~/indi-allsky-watchdog.sh

Manueller Funktionstest

 ~/indi-allsky-watchdog.sh

Erwartetes Verhalten:

  • bei laufender Bildproduktion: keine Aktion
  • bei gestoppter Bildproduktion: Mail + Restart

systemd-Service für den Watchdog anlegen

 nano ~/.config/systemd/user/indi-allsky-watchdog.service
[Unit] Description=Watchdog prüft JPG-Aktivität von indi-allsky 
[Service] Type=oneshot ExecStart=/home/dante/indi-allsky-watchdog.sh

systemd-Timer anlegen

 nano ~/.config/systemd/user/indi-allsky-watchdog.timer
[Unit] Description=Timer für indi-allsky Watchdog 
[Timer] OnBootSec=2min OnUnitActiveSec=2min AccuracySec=30s 
[Install] WantedBy=default.target

Watchdog aktivieren

 systemctl --user daemon-reload systemctl --user enable --now indi-allsky-watchdog.timer

Prüfen:

 systemctl --user list-timers | grep indi-allsky

Was dieser Watchdog zuverlässig leistet

  • erkennt echte Stillstände der Bildproduktion
  • startet indi-allsky automatisch neu
  • versendet maximal eine Mail pro Ereignis
  • funktioniert unabhängig von USB-Status oder Threads
  • ist vollständig transparent und wartbar

Appendix: Ergänzung bei bewusst abgezogener Kamera (USB) – 25.12.2025

Nach der Veröffentlichung des ursprünglichen Watchdog-Setups hat sich in der Praxis ein Sonderfall gezeigt,
der berücksichtigt werden sollte: Die Kamera kann bewusst abgezogen werden – etwa für Tests,
Wartungsarbeiten oder Hardware-Experimente.

In diesen Situationen kann indi-allsky weiterhin laufen, obwohl keine Bilder mehr erzeugt werden.
Die Basislogik des Watchdogs erkennt korrekt, dass keine neuen JPG-Dateien geschrieben werden – sie kann jedoch
nicht unterscheiden, ob ein echter Fehler vorliegt oder ein manueller Eingriff erfolgt ist.

Warum Prozess-Checks oder /dev/video0 nicht ausreichen

In modernen indi-allsky-Setups (libcamera, ZWO-Kameras, gemischte USB/CSI-Umgebungen) gilt:

  • indi-allsky kann weiterlaufen, auch wenn die Kamera physisch nicht mehr angeschlossen ist
  • ein reiner Dienst- oder Prozess-Check ist daher nicht zuverlässig
  • /dev/video0 ist häufig nicht vorhanden oder nicht stabil nutzbar

Entscheidend ist daher nicht allein der Software-Zustand, sondern die physische Präsenz der Kamera.

Lösung: USB-Erkennung über Vendor-/Product-ID (optional)

USB-Kameras verfügen über eine eindeutige Kennung, die sich direkt auslesen lässt:

lsusb

Beispiel aus einem produktiven Setup:

Bus 003 Device 002: ID 03c3:678b ZWO ASI678MC

Diese Vendor-/Product-ID kann im Watchdog-Skript gezielt geprüft werden.
Ist die Kamera am USB-Bus nicht vorhanden, geht der Watchdog von einem bewussten manuellen Eingriff aus und
unterdrückt einen automatischen Neustart.

Wo diese Ergänzung im Skript eingefügt wird

Die USB-Prüfung wird im bestehenden Watchdog-Skript direkt nach dem Lock-Block eingefügt,
also vor der Prüfung des letzten JPG-Zeitstempels:

# ==================================================
# Lock gegen parallele Ausführung
# ==================================================
exec 9>"$LOCK_FILE" || exit 1
flock -n 9 || exit 0

# USB-Erkennung hier einfügen

Beispiel für die USB-Erkennung

CAMERA_USB_ID="03c3:678b"

if ! lsusb | grep -qi "$CAMERA_USB_ID"; then
    # Kamera physisch nicht vorhanden – kein Neustart
    exit 0
fi

Wirkung der Ergänzung

Mit dieser optionalen Erweiterung unterscheidet der Watchdog sauber zwischen:

  • einem echten Fehlerzustand (Kamera vorhanden, aber keine neuen Bilder)
  • einem bewussten manuellen Eingriff (Kamera physisch abgezogen)

Unnötige Neustarts werden vermieden, während die ursprüngliche Watchdog-Logik unverändert bleibt.

Hat dir dieser Beitrag gefallen?

Du kannst allsky-rodgau.de mit einem kleinen Kaffee auf BuyMeACoffee unterstützen.

Jetzt Kaffee spendieren!