# Übergabe — Session 2026-08-23 (bis in den 24. hinein) > **Einstieg:** diese Datei, dann [`teilprojekte.md`](teilprojekte.md). > **Zustand am Netz: stabil und aufgeräumt.** Nichts steht halb offen, keine Config-Transaktion > gelaufen, `s9` ist vollständig zurückgebaut, alle Shellys erreichbar. ## Was diese Session war Begonnen mit TP17.3 (der Shelly-Regression), geendet bei einer Umstrukturierung der Router-Konten. Fünf Commits: `d245d10`, `e8f7f80`, `0a7f2e2`, `2f18319`, `e9a5b36`. | | | |---|---| | ✅ **TP17.3 gelöst** | Ursache **`eco_mode`** bewiesen, `s23` (Dimmer-Flackern) und `s26` (Doppeldruck) repariert. | | ✅ **`eco_mode` flottenweit aus** | 13 Geräte umgestellt, null Fehler. **22/22 erreichbare Shellys auf `false`.** | | ❌ **TP17.1 verworfen** | Der Zigbee-Weg wurde **vollständig bewiesen** — und damit auch, dass das Ziel mit ihm nicht erreichbar ist. | | ✅ **Passwort-Rotation Etappe 1** | Dedizierte Service-Accounts `ha` + `nautobot` auf allen vier MikroTik. | --- ## 🔴 Womit die nächste Session anfangen sollte > ⚠️ **ÜBERHOLT am 2026-08-24 (User-Entscheid):** die Rotation ist **nicht** der Sessionstart. > Sie ist zu **[TP30 — Credential-Rotation](teilprojekte.md)** geworden, einem Sammel-TP, der > **gegen Projektende gebündelt** abgearbeitet wird — Begründung: es kommen weitere Passwörter > hinzu, und der teure Teil sind die Konsumenten (HA-Re-Auth, Stack-Redeploy), den man nicht > mehrfach zahlen will. **Der Inhalt unten bleibt sachlich gültig** und steht jetzt in TP30. **Passwort-Rotation, Etappe 2.** Die Vorarbeit steht komplett, der Rest ist die einzige Sache mit echter Dringlichkeit — das `admin`-Passwort ist zweimal in ein Transkript geraten (22.08. und, durch meinen eigenen Enumerationsfehler, nochmal am 23.08.; **derselbe Wert**, da alle vier Geräte ihn teilen). **Was Etappe 2 verlangt, in dieser Reihenfolge:** 1. **Nautobot** auf den `nautobot`-User umstellen — `NAUTOBOT_ROUTEROS_USERNAME/PASSWORD` im Stack `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored), dann **Portainer-Redeploy** auf der DS923. ⚠️ Beim Redeploy die Healthcheck-/`mem_limit`-Zeilen nicht verlieren — siehe CLAUDE.md-Gotcha, der Stack hat am 17.08. zweimal die DS923 abgeräumt. **Abnahme:** ein GC-Backup-Lauf, der durchgeht. 2. **HA**: die vier `mikrotik`-Integrationen (`.99.1`, `.99.2`, `.99.11`, `.99.12`) auf `ha` bringen. 🔴 **`supports_reconfigure: false` — nicht skriptbar.** Entfernen-und-neu-Anlegen *wäre* skriptbar (`ha_set_integration domain="mikrotik"`), riskiert aber die **40 `device_tracker`-Entities**. Sie heißen nach MAC (`device_tracker.10_20_ba_fa_f5_40`), kämen also identisch zurück — **aber nur, wenn die alten Registry-Einträge vorher weg sind**, sonst hängt HA ein `_2` an. Dieselbe Falle wie beim Shelly-Rename. 3. **Erst danach `admin` rotieren.** Dann berührt es nur noch `~/.secrets/credentials.env` und `~/.claude.json` (+ MikroMCP-Neustart) — die Repo-Skripte ziehen automatisch nach. ### Was dafür schon fertig ist Auf **allen vier** Geräten angelegt und abgenommen (vorher existierte dort **nur** `admin`/`full`): | Gruppe | Policy | User | |---|---|---| | `grp-ha` | `read,api,rest-api,test` | `ha` | | `grp-nautobot` | `ssh,read,write,test,sensitive` | `nautobot` | Passwörter: `MIKROTIK_HA_PASS` / `MIKROTIK_NAUTOBOT_PASS` in `~/.secrets/credentials.env`. 🎯 **Der Export von `nautobot` ist byte-identisch zu dem von `admin`** (391/56/87/87 Zeilen) — **die GC-Compliance driftet beim Umstellen nicht.** Das war das Hauptrisiko und ist geprüft. `/user` wird von keiner ComplianceRule abgedeckt, die Konten erzeugen selbst keinen Drift. --- ## Danach, mit Vorsicht - **C2 — IoT-PSK rotieren.** Der Hebel ist `/interface wifi security multi-passphrase` (`group`/`passphrase`/`vlan-id`/`expires`), auf dem Core verifiziert vorhanden, Tabelle noch leer. 🔴 **Zuerst `multi-passphrase` gegen WPA3/SAE testen — auf einer Wegwerf-SSID, nie an `dirtyvader-iot`.** `sec-iot` fährt `wpa2-psk,wpa3-psk`; trägt multi-passphrase SAE nicht, sperrt man **26 IoT-Geräte auf einmal** aus, inklusive Nuki und NSPanel. Danach: 23 Shellys per Skript (der erprobte Anker-Pfad in `migrate.py._migrate_one`), **3 Geräte von Hand** — `.249` SONOFF NSPanel Pro (Touchscreen), `.244` Nuki Bridge (App), `.227` SwitchBot Floor Lamp (App). ⚠️ `s1`/`s2`/`s3` sind ausgesteckt und kommen im Dezember mit dem **alten** PSK zurück. ⚠️ CAPsMAN: eine Profiländerung wirkt erst nach `remote-cap provision` für **beide** APs. - **D — TP17.2 Shelly-Gerätepasswort**, an C2 gekoppelt (ein Reboot statt zwei). Werkzeug ist fertig (`migrate.py cmd_auth`, Digest-Fallback in `_rpc`). 🔴 **Der Aufwand ist HA, nicht `SetAuth`:** je Gerät ein Re-Auth-Flow, 23-mal. **Erst an EINEM Gerät messen** (Vorschlag `s15 technik_pve`, −36 dBm). - **TP25 Fund F** (5:05-Takt IoT) und die Entscheidung **5 GHz auf 20 MHz**. - **5-GHz-Umfeldscan** vor dem Einbau der zwei neuen APs. --- ## Die Entscheidung des Tages: warum TP17.1 gestorben ist Der Pilot hat den Zigbee-Weg **technisch vollständig bewiesen** — `s9` lief auf `PowerStripZB`, trat ZHA bei, ein Zigbee-Befehl schaltete das physische Relais, kein Broadcast-Sturm. Christophs Einwand hat ihn trotzdem gekippt: *„zigbee sollte die antwort auf die vielen radios auf -iot geben. nutzt aber wenig wenn man das wifi nicht abdrehen kann bzw. es nicht mehr aktivieren kann ohne reset."* Und die Messung stützt ihn: - **Das Gerät bleibt WLAN-Client** — Zigbee kommt *zusätzlich*, nicht *statt*. - **Der Funkgewinn ist klein:** die 12 Gen4 sind 12 von 26 IoT-Clients, bewegen aber je nur ~150–200 KB rx / 0,6–3 MB tx in sechs Stunden. - **Der Preis wäre dauerhaft:** die Zigbee-Firmware hat **keinen AP**, Shelly macht **kein Zigbee-OTA**, `Shelly.InstallAlt` braucht IP. WLAN aus = nie wieder Update, kein Rückweg, bei 10 Unterputz-Modulen. **Der Weg ist nicht gescheitert, das Ziel war mit ihm nicht erreichbar.** Das Runbook bleibt als Wissensspeicher; einziger Restposten ist der **Frühindikator** (`Shelly.CheckForUpdate` auf einen `…MT`/Thread-`alt`-Eintrag beobachten). --- ## Zwei Messungen, die vorherige Annahmen widerlegen **1. `eco_mode` aus hebt die Sendeleistung NICHT an.** Ich hatte das als Airtime-Risiko notiert, das TP25 berührt. Gemessen am Manager, vorher/nachher: **13 geänderte Geräte im Mittel −0,9 dB**, bei einer **Kontrollgruppe von 13 unveränderten mit +0,0 dB** und derselben Streuung (±2 dB). Rauschen. ⇒ Die TP17-Aussage, `eco_mode` senke „den CPU-Takt **und** die WLAN-Sendeleistung", stimmt nur zur Hälfte. Der Takt-Teil ist durch das Dimmer-Flackern bewiesen; der Rest ist nicht messbar. **2. `restart_required` auf 14 Shellys war ein Fehlalarm.** Der Reboot von `s26` mit Config-Vergleich davor/danach ergab **identische Configs**. Das Bit ist *sticky* und stand für keine abweichende Konfiguration. **Nicht erneut untersuchen** — drei Wege (169 RPC-Methoden, Config-Diff über die Gruppengrenze, Gerätelog) sind zu Ende gegangen, alle negativ. --- ## Zahlen und Fallen, die man nicht neu erheben muss - **`dirtyvader-iot`: 26–27 Clients, alle auf EINEM VAP** (`cap-wifi4-virtual1`, ap1). Davon 23 Shellys und **3 Fremde**: `.249` NSPanel Pro, `.244` Nuki Bridge, `.227` SwitchBot Floor Lamp. - **`s4 kueche_mikrowelle` ist wieder online** (war den ganzen Tag als offline geführt) — und ist **Gen3**, war also nie TP17.1-Kandidat. Bleibt der Härtefall bei −96 dBm (Geräte-Sicht). - 🔴 **HA- und Repo-Nummerierung der Shellys weichen ab** — HA: `s10 = schlafzi/teststecker`, Inventory: `s10 = bad_sonos`; ebenso `s17`. **Immer über MAC/IP zuordnen, nie über die s-Nummer.** - 🔴 **`migrate.py _resolve` fällt ohne Argument auf den alten VLAN1-Sweep `10.40.41.180-250` zurück.** Explizite Bereiche übergeben oder `SHELLY_SWEEP` setzen. - 🔵 **`inventory/bf.csv` führt `s12` noch auf `10.40.41.219`** (live `10.40.30.219`). - ⚠️ **Nach jedem Shelly-Firmwarewechsel den AP prüfen** — der Rückflash von `s9` zog einen **offenen** AP hoch (`ap.enable=true, is_open=true`). Abgeschaltet und mit dem IoT-PSK abgesichert. - 🔒 **`wifi-security` ist als ComplianceRule grün, aber NICHT deploybar** — die Passphrasen stehen als `<>` im Template. Ist-Stand immer per REST vom Gerät lesen (`GET http://10.40.99.1/rest/interface/wifi/security`), **nie** aus `wlan-psks.env`. ### Der Firmware-Mechanismus der Shelly Gen4 (falls er je wieder gebraucht wird) Zwei-Slot-Modell über drei **undokumentierte** RPCs, aus dem UI-JavaScript des Geräts extrahiert: `Shelly.InstallAlt {app, stage}` lädt in den inaktiven Slot und rebootet hinein · `Shelly.SetAlternative {name}` schaltet um (auf unseren Modellen **nicht vorhanden**) · `Shelly.ListAlternatives` (404 auf beiden Builds). Die Shelly-Support-Seite beschreibt einen **Modus-Umschalter mit 5-Sekunden-Knopf** — **das gilt für unsere Modelle nicht.** --- ## Neue und geänderte Dokumente - [`tp17.1-shelly-gen4-funkmigration-runbook.md`](tp17.1-shelly-gen4-funkmigration-runbook.md) — Kopf trägt jetzt „VERWORFEN"; enthält den kartierten Mechanismus, das 2,4-GHz-Bild und die ZHA-Sturmzähler mit Baseline - [`teilprojekte.md`](teilprojekte.md) — TP17.1 verworfen, TP17.2 aktiviert, TP17.3 erledigt, PSK-Follow-up um Radius-Befund und Etappe 1 ergänzt - `CLAUDE.md` — 🔴 empfahl bis gestern aktiv `sshpass -p` als Reboot-Weg, jetzt `sshpass -e` - `mcp/shelly/migrate.py` — neues `eco`-Kommando (mit Retry je Gerät und Fehlerliste)