#!/usr/bin/env python3 """ Babycam Network State Machine Verwaltet die drei Betriebsmodi: A – Heimnetz (wlan0 verbunden, AP aus) B – Kein WLAN (AP auf wlan1 automatisch) C – Setup-Modus (AP läuft, User konfiguriert WLAN) Override-Datei: /tmp/babycam-ap-override "on" → AP immer an (manuell) "off" → AP immer aus (manuell) fehlt → Automatik """ import subprocess import time import logging import sys import os logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", handlers=[logging.StreamHandler(sys.stdout)], ) log = logging.getLogger(__name__) AP_INTERFACE = "wlan1" CLIENT_INTERFACE = "wlan0" AP_IP = "192.168.50.1" CHECK_INTERVAL = 30 # Sekunden OVERRIDE_FILE = "/var/lib/babycam/ap-override" def run(cmd, check=False): result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if check and result.returncode != 0: log.error(f"Fehler bei: {cmd}\n{result.stderr}") return result def get_override(): """Liest die manuelle Override-Einstellung. Gibt 'on', 'off' oder None zurück.""" try: with open(OVERRIDE_FILE) as f: val = f.read().strip().lower() if val in ("on", "off"): return val except FileNotFoundError: pass return None def is_wlan0_connected(): result = run(f"nmcli -t -f GENERAL.STATE device show {CLIENT_INTERFACE}") return "100 (connected)" in result.stdout def is_ap_running(): result = run("systemctl is-active hostapd") return result.stdout.strip() == "active" def start_ap(): log.info("Starte Access Point (BabyCam)...") run("ip addr add 192.168.50.1/24 dev wlan1 2>/dev/null || true") run("ip link set wlan1 up") run("systemctl start hostapd", check=True) run("systemctl start dnsmasq", check=True) log.info("Access Point gestartet.") def stop_ap(): log.info("Stoppe Access Point...") run("systemctl stop hostapd") run("systemctl stop dnsmasq") run("ip addr flush dev wlan1 2>/dev/null || true") log.info("Access Point gestoppt.") def main(): log.info("Babycam Network State Machine gestartet.") current_mode = None while True: override = get_override() connected = is_wlan0_connected() ap_running = is_ap_running() if override == "on": # Manuell: AP immer an if current_mode != "MANUAL_ON": log.info("Modus: Manuell – Access Point erzwungen AN.") if not ap_running: start_ap() current_mode = "MANUAL_ON" elif override == "off": # Manuell: AP immer aus if current_mode != "MANUAL_OFF": log.info("Modus: Manuell – Access Point erzwungen AUS.") if ap_running: stop_ap() current_mode = "MANUAL_OFF" else: # Automatik if connected: if current_mode != "A": log.info("Modus A: Heimnetz aktiv – AP aus.") if ap_running: stop_ap() current_mode = "A" else: if current_mode != "B": log.info("Modus B: Kein WLAN – starte Access Point.") if not ap_running: start_ap() current_mode = "B" time.sleep(CHECK_INTERVAL) if __name__ == "__main__": main()