From 8d8c83ee8eaaadfdbd3747ddd5b39d1bfac620b6 Mon Sep 17 00:00:00 2001 From: Ralf-Peter Wolff Date: Wed, 20 May 2026 13:02:25 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20Architektur=20korrigiert=20=E2=80=93=20?= =?UTF-8?q?Router=20kabelgebunden,=20WLAN=20via=20CAPsMAN-AP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 231 ++++++++++++++++++++++++------------------------------ 1 file changed, 104 insertions(+), 127 deletions(-) diff --git a/README.md b/README.md index 2f2e6f5..cf57661 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,79 @@ # 🏠 HomeMatic Anwesenheitserkennung via MikroTik Automatische Anwesenheitserkennung fΓΌr 2 iPhones im Heimnetz **Ebesch** (192.168.252.0/24). -Ein Python-Script lΓ€uft minΓΌtlich auf `ebesch-docker` und fragt den MikroTik-Router per REST-API ab β€” sind die iPhones im WLAN eingebucht, werden die HomeMatic-Systemvariablen auf *β€žzu Hause"* gesetzt. +Ein Python-Script lΓ€uft minΓΌtlich auf `ebesch-docker` und fragt den MikroTik-Router per REST-API +nach verbundenen WLAN-Clients β€” werden die iPhones erkannt, setzt es die HomeMatic-Systemvariablen +auf *β€žzu Hause"*. --- ## πŸ—οΈ Architektur ``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” REST API β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ ebesch-docker β”‚ ────────────────► β”‚ MikroTik RB5009 β”‚ -β”‚ 192.168.252.10 β”‚ /caps-man/ β”‚ 192.168.252.254 β”‚ -β”‚ (Cronjob 1min) β”‚ registration- β”‚ CAPsMAN β†’ AP .253 β”‚ -β”‚ β”‚ table β”‚ SSID: Aironet β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β–² - β”‚ statechange.cgi β”‚ WiFi - β–Ό β”‚ -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ HomeMatic CCU2 β”‚ β”‚ πŸ“± RP iPhone β”‚ -β”‚ 192.168.252.12 β”‚ β”‚ πŸ“± Kerstins iPhone β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -β”‚ Systemvariablenβ”‚ -β”‚ β€’ Zone RPiPhone (1828) -β”‚ β€’ Zone Kerstins iPhone (4730) -β”‚ β€’ Anwesenheit (950) -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ MikroTik RB5009UPr+S+ β”‚ + β”‚ 192.168.252.254 β”‚ + β”‚ Kabelrouter + CAPsMAN-Controller β”‚ + β”‚ (kein eigenes WLAN) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ CAPsMAN (kabelgebunden) + β”‚ Registration Table hier + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ MikroTik RBcAPGi-5acD2nD β”‚ + β”‚ 192.168.252.253 β”‚ + β”‚ WLAN-Accesspoint β”‚ + β”‚ SSID: Aironet (2,4+5 GHz) β”‚ + β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ + β”‚ WiFi β”‚ WiFi + β–Ό β–Ό + πŸ“± RP iPhone πŸ“± Kerstins iPhone + + +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” REST API /interface/wifi/ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ ebesch-docker β”‚ ──────────registration-table──►│ Router .254 β”‚ +β”‚ 192.168.252.10 β”‚ ◄─────────────────────────────│ (CAPsMAN ctrl.) β”‚ +β”‚ Cronjob 1 min β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ statechange.cgi (XML-API) + β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ HomeMatic CCU2 β”‚ +β”‚ 192.168.252.12 β”‚ +β”‚ β”‚ +β”‚ Zone RPiPhone (1828)β”‚ +β”‚ Zone K. iPhone (4730)β”‚ +β”‚ Anwesenheit (950)β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +> **Hinweis:** Der Router selbst hat kein WLAN. Die WLAN-Clients verbinden sich mit dem +> separaten AP (.253). Der Router agiert als **CAPsMAN-Controller** und kennt ΓΌber die +> Registration Table alle am AP eingebuchten GerΓ€te. + +--- + +## βš™οΈ Erkennungslogik + +### 1. WiFi Registration Table (primΓ€r) +`GET /rest/interface/wifi/registration-table` β€” ROS 7.x (neues WiFi-System) +Zeigt alle **aktuell aktiv verbundenen** WLAN-Clients des CAPsMAN-APs. + +### 2. CAPsMAN Registration Table (Fallback API) +`GET /rest/caps-man/registration-table` β€” ROS 6 / frΓΌhe ROS-7-Versionen +Automatischer Fallback falls der neue Pfad keine Daten liefert. + +### 3. ARP-Tabelle (letzter Fallback) +`GET /rest/ip/arp` β€” enthΓ€lt zuletzt gesehene MAC/IP-Zuordnungen. +Hilft wenn das iPhone kurz vom WLAN getrennt ist (Display aus / Sleepmode). + +### iOS MAC-Randomisierung (iOS 14+) +iPhones nutzen **pro SSID eine stabile private MAC-Adresse**. +Diese bleibt fΓΌr dieselbe SSID konstant β€” wir tragen genau diese ein. + +**MAC-Adresse ablesen:** +``` +iPhone β†’ Einstellungen β†’ WLAN β†’ β“˜ neben "Aironet" β†’ WLAN-Adresse ``` --- @@ -35,35 +83,11 @@ Ein Python-Script lΓ€uft minΓΌtlich auf `ebesch-docker` und fragt den MikroTik-R | Komponente | GerΓ€t | IP | |---|---|---| | Script-Host | ebesch-docker | 192.168.252.10 | -| Router | MikroTik RB5009UPr+S+ | 192.168.252.254 | -| WLAN-AP | MikroTik RBcAPGi-5acD2nD (CAPsMAN) | 192.168.252.253 | +| Router (CAPsMAN-Ctrl.) | MikroTik RB5009UPr+S+ | 192.168.252.254 | +| WLAN-AP | MikroTik RBcAPGi-5acD2nD | 192.168.252.253 | | HomeMatic | CCU2 | 192.168.252.12 | -**Software auf ebesch-docker:** -- Python 3.8+ -- `requests` Bibliothek (via pip/venv) - ---- - -## βš™οΈ Erkennung - -### PrimΓ€r: CAPsMAN Registration Table -Zeigt alle **aktuell aktiv verbundenen** WLAN-Clients des APs. -β†’ ZuverlΓ€ssigste Methode, da in Echtzeit. - -### Fallback: ARP-Tabelle -EnthΓ€lt zuletzt gesehene MAC/IP-Zuordnungen. -β†’ Greift wenn das iPhone kurz vom WLAN getrennt ist (Sleepmode). - -### iOS MAC-Randomisierung (iOS 14+) -iPhones nutzen **pro SSID eine stabile private MAC-Adresse** (nicht die echte Hardware-MAC). -Diese bleibt fΓΌr dieselbe SSID konstant, ist aber netzwerkspezifisch. - -**MAC-Adresse herausfinden:** -``` -iPhone β†’ Einstellungen β†’ WLAN β†’ β“˜ neben "Aironet" β†’ WLAN-Adresse -``` -Diese Adresse in `config.ini` eintragen. +**Software auf ebesch-docker:** Python 3.8+, `requests` (via pip/venv) --- @@ -78,12 +102,12 @@ git clone https://git.rwolff.homelinux.net/rpwolff/homematic-anwesenheit.git cd homematic-anwesenheit ``` -### 2. MAC-Adressen eintragen +### 2. config.ini anlegen und MACs eintragen ```bash +cp config.ini.example config.ini nano config.ini -# [device.rp_iphone] β†’ mac = XX:XX:XX:XX:XX:XX -# [device.kerstin_iphone] β†’ mac = XX:XX:XX:XX:XX:XX +# mac = XX:XX:XX:XX:XX:XX ← private WLAN-MAC je iPhone eintragen ``` ### 3. Installation ausfΓΌhren @@ -92,17 +116,13 @@ nano config.ini bash install.sh ``` -Das Script: -- Legt `/opt/homematic-presence/` an -- Erstellt ein Python-venv mit `requests` -- Installiert einen Cronjob (`/etc/cron.d/homematic-presence`) -- Konfiguriert Log-Rotation +Richtet Python-venv, Cronjob und Log-Rotation ein. ### 4. Testen ```bash -/opt/homematic-presence/venv/bin/python3 /opt/homematic-presence/presence_check.py \ - --dry-run --verbose +/opt/homematic-presence/venv/bin/python3 \ + /opt/homematic-presence/presence_check.py --dry-run --verbose ``` ### 5. Log beobachten @@ -115,66 +135,13 @@ tail -f /var/log/homematic-presence.log ## πŸ“Š HomeMatic Systemvariablen -| Variable | ISE-ID | Typ | `false` | `true` | -|---|---|---|---|---| -| Zone RPiPhone | 1828 | LOGIC | außer Haus | zu Hause | -| Zone Kerstins iPhone | 4730 | LOGIC | außer Haus | zu Hause | -| Anwesenheit | 950 | LOGIC | nicht anwesend | anwesend | +| Variable | ISE-ID | `false` | `true` | +|---|---|---|---| +| Zone RPiPhone | **1828** | außer Haus | zu Hause | +| Zone Kerstins iPhone | **4730** | außer Haus | zu Hause | +| Anwesenheit | **950** | nicht anwesend | anwesend | -Die Variable **Anwesenheit** wird auf `true` gesetzt wenn mindestens eine Person zuhause ist. - ---- - -## πŸ”§ Konfiguration (`config.ini`) - -```ini -[mikrotik] -host = 192.168.252.254 -user = admin -password = - -[homematic] -host = 192.168.252.12 -combined_ise_id = 950 # Kombinierte Anwesenheit - -[device.rp_iphone] -mac = XX:XX:XX:XX:XX:XX # Private WLAN-MAC fΓΌr SSID "Aironet" -ise_id = 1828 -label = RP iPhone - -[device.kerstin_iphone] -mac = XX:XX:XX:XX:XX:XX # Private WLAN-MAC fΓΌr SSID "Aironet" -ise_id = 4730 -label = Kerstins iPhone -``` - ---- - -## πŸ” Troubleshooting - -**CAPsMAN zeigt 0 Clients obwohl GerΓ€t verbunden:** -```bash -# Router-Seite prΓΌfen: -curl -u admin: http://192.168.252.254/rest/caps-man/registration-table -``` - -**HomeMatic-Variable Γ€ndert sich nicht:** -```bash -# XML-API direkt testen: -curl "http://192.168.252.12/config/xmlapi/statechange.cgi?ise_id=1828&new_val=true" -``` - -**Script manuell ausfΓΌhren:** -```bash -/opt/homematic-presence/venv/bin/python3 \ - /opt/homematic-presence/presence_check.py --verbose -``` - -**Cronjob-Status:** -```bash -systemctl status cron -grep homematic /var/log/syslog | tail -20 -``` +`Anwesenheit` wird `true` wenn mindestens eine Person zuhause ist. --- @@ -182,27 +149,37 @@ grep homematic /var/log/syslog | tail -20 | Datei | Beschreibung | |---|---| -| `presence_check.py` | Hauptscript: Router abfragen β†’ HomeMatic setzen | -| `config.ini` | Konfiguration (MACs, IPs, Credentials) | +| `presence_check.py` | Hauptscript | +| `config.ini.example` | Konfigurationsvorlage (ohne PasswΓΆrter, im Repo) | +| `config.ini` | Aktive Konfiguration (in `.gitignore`, nicht im Repo) | | `install.sh` | Einmalige Installation auf ebesch-docker | -| `README.md` | Diese Dokumentation | --- -## πŸ”’ Sicherheitshinweise +## πŸ” Troubleshooting -- `config.ini` enthΓ€lt PasswΓΆrter β†’ **nicht ΓΆffentlich committen** -- Das Repo ist ΓΆffentlich β€” `config.ini` ist in `.gitignore` -- PasswΓΆrter liegen in Bitwarden / Obsidian Firma +```bash +# WiFi-Clients direkt abfragen: +curl -u admin: http://192.168.252.254/rest/interface/wifi/registration-table + +# HomeMatic-Variable manuell setzen: +curl "http://192.168.252.12/config/xmlapi/statechange.cgi?ise_id=1828&new_val=true" + +# Cronjob-Log: +tail -50 /var/log/homematic-presence.log + +# Systemd / Cron status: +systemctl status cron +``` --- -## πŸ“… Wartung +## πŸ”’ Sicherheit -- RouterOS-Updates kΓΆnnen CAPsMAN-API-Pfade Γ€ndern β†’ Script ggf. anpassen -- iOS-Updates kΓΆnnen MAC-Randomisierung beeinflussen β†’ MACs ggf. neu auslesen -- HomeMatic-Firmware-Updates: ISE-IDs bleiben stabil +- `config.ini` enthΓ€lt PasswΓΆrter β†’ in `.gitignore`, **nicht committen** +- Credentials liegen in Bitwarden / Obsidian Firma --- -*Netz: Ebesch Β· 192.168.252.0/24 Β· SSID: Aironet Β· Repo: [git.rwolff.homelinux.net/rpwolff/homematic-anwesenheit](https://git.rwolff.homelinux.net/rpwolff/homematic-anwesenheit)* +*Netz: Ebesch Β· 192.168.252.0/24 Β· SSID: Aironet Β· RouterOS: 7.20.6* +*Repo: [git.rwolff.homelinux.net/rpwolff/homematic-anwesenheit](https://git.rwolff.homelinux.net/rpwolff/homematic-anwesenheit)*