# TP17.1 — Shelly Gen4 raus aus dem WLAN (Thread oder Zigbee) · Runbook > **Status 2026-08-23:** 🔜 **entscheidungsreif, nicht startbereit.** Schritt 0 ist eine Abwägung, > kein Flash. Steuerung/Scope: [`teilprojekte.md`](teilprojekte.md) → **TP17.1**. > **Kein Netz-Eingriff bisher**, alle Zahlen hier sind read-only erhoben. > > 📌 **Wohnort dieses Arbeitspakets: das Netz-Projekt** (User-Entscheid 2026-08-23). Eine erste > Fassung lag kurzzeitig im HA-Projekt (`ha-xstate`) — sie ist dort **entfernt**, damit es keine > zweite Wahrheit gibt. HA ist Betroffener, nicht Eigentümer: die Entities brechen, aber die > Entscheidung ist eine Funk- und Netzentscheidung. ## Das Ziel (Christophs Begründung, dreiteilig) 1. **Die PSK-Rotation wird billiger.** Jedes Gerät, das den Funk wechselt, fällt aus der Rechnung. 2. **Mesh-Stabilität** — netzgespeiste Geräte sind immer Router-Knoten, nie Sleepy End Devices. 3. **Ruhe im WLAN.** 26 der 27 WLAN-Clients des ganzen Netzes hängen auf `dirtyvader-iot`. ⚠️ **Punkt 1 trägt nur teilweise.** Kandidaten sind **10 Geräte**; danach blieben grob **16** auf dem IoT-SSID. Die Rotation wird **kleiner, nicht überflüssig** — und Gen3 kann nie folgen, dort fehlt 802.15.4. *(Seit 2026-08-23 ist das ohnehin entschärft: Rotation und Funkmigration laufen **parallel**, s.u.)* --- ## Bestand (live 2026-08-23, `mcp/shelly/discover.py`, read-only) **22 von 26 Shellys erreichbar** auf VLAN30, **alle auf Firmware 2.0.0**: | Gen | Anzahl | Modelle | |---|---|---| | **Gen4** | **12** | 9× `S4SW-002P16EU` (2PM) · 1× `S4SW-001P16EU` (1PM) · 2× `S4PL-00416EU` (Power Strip) | | Gen3 | 8 | `S3PL-00112EU`, `S3PL-30116EU` | | Gen2 | 2 | `SPDM-002PE01EU`, `SNDC-0D4P10WW` | **Die 12 Gen4:** s25 bad_lichtschalter `.205` · s20 kueche_steckdosen2 `.206` · s21 kueche_steckdosen4 `.207` · s12 dieleug_steckdosen `.219` · s16 wohnzimmer_steckdosen `.223` · s17 bad_steckdosen `.224` · s18 kueche_steckdosen1 `.225` · s19 kueche_steckdosen3 `.226` · s26 bad_luefter `.233` *(alle 2PM)* · s22 kueche_steckdose3-2 `.202` *(1PM)* · **s9 wohnzimmer_sideboard `.216`** und **s13 arbeitszimmer_technik `.220`** *(Power Strip)*. **Nicht erreichbar (4):** `s1`/`s2`/`s3` (weihnachten_*, saisonal ausgesteckt — die HA-Entities sind **deaktiviert, nicht gelöscht**, deshalb tauchen sie in keiner Zustandssuche auf; Christoph 2026-08-23) und **`s4 kueche_mikrowelle`** — der einzige, den auch HA als `unavailable` führt. Hängt hinter Metall bei **RSSI −93 dBm**, Generation unbekannt. **Falls Gen4: bester Pilot überhaupt**, denn 802.15.4 kommt dorthin, wo 2,4-GHz-WLAN scheitert. --- ## 🔴 Die Firmware-Lage — der Kern der Entscheidung **Direkt an den Geräten erhoben** (`Shelly.CheckForUpdate`, read-only, 2026-08-23): | | Befund | |---|---| | Stable | **2.0.0 überall — für kein Gerät ein stabiles Update** | | Beta | `2.0.1-beta1`, Build 2026-08-19, für alle inkl. Gen3 | | **Alt-Varianten (nur Gen4)** | `S2PMG4ZB` · `S1PMG4ZB` · `PowerStripZB` — jeweils **„with Zigbee"** | | Gen3 | **kein `alt`-Eintrag** → Alternativfunk ist Gen4-only | **Thread gibt es von Shelly heute nicht.** Die offizielle Linie ist **„wird evaluiert"** (Stand Juli 2026, genannter Engpass: **Flash-Platz**), kein Release-Datum. Was im Mai 2026 als „Thread für Gen4" durch die Presse ging, war die **Dritt**-Firmware. 🎯 **Der wichtigste Nebenbefund:** Shelly liefert alternative **Funk**-Firmware über den **normalen Update-Kanal**, nicht über einen Bastelpfad. Eine Thread-Variante erschiene mit hoher Wahrscheinlichkeit **genau dort** als weiterer `alt`-Eintrag. ⇒ **Frühindikator statt Warten auf Pressemeldungen:** `Shelly.CheckForUpdate` auf einem Gen4 pollen und auf einen `…MT`/Thread-Eintrag warten. ### Die drei Wege im Vergleich | Weg | Deckt ab | Preis | Reife | |---|---|---|---| | **(A) Zigbee, offiziell — heute verfügbar** | **10 der 12** (2PM, 1PM, Power Strip) | Entity-Bruch (Shelly-Integration → Z2M); 2,4-GHz-Kanalplanung nötig | Hersteller-Firmware, offizieller Kanal, **keine** Garantie-/Cloud-Frage | | **(B) Thread, offiziell — warten** | offen | nur Wartezeit | existiert nicht; „wird evaluiert", Flash-Platz als Engpass | | **(C) Thread, Dritt-Firmware — heute möglich** | 10 der 12 via [hencou](https://github.com/hencou/shelly_gen4_matter_module) *(die [automatous-io](https://github.com/automatous-io/shelly-1-gen4-matter-thread)-Variante deckt hier **0** ab)* | **Garantie + Cloud + offizielle OTA weg**; Rückweg nur mit **UART-Vollbackup je Gerät**; PM-Kalibrierung Platzhalter; Test-VID | nur *Shelly 1 Gen4* auf echter Hardware verifiziert, andere Profile **ungetestet** | **Die zwei `S4PL-00416EU` (s9, s13) deckt keiner der Wege ab** — sie bleiben im WLAN. 💡 **Empfehlung, falls gefragt: (A) prüfen, bevor (C) erwogen wird.** Zigbee erfüllt **alle drei Ziele oben** — heute, mit Hersteller-Firmware, ohne Garantieverlust, ohne UART-Backup. Zigbee2MQTT läuft bereits als **LXC 112 (`10.40.20.106`, `z2m25`)**. Was vorher zu klären ist: - **(a) Rückrollbarkeit:** Ist der Wechsel des Funkstacks so zurückrollbar wie ein normales Update? Das ist ein anderer Vorgang als ein Versionssprung — vor dem ersten Gerät klären. - **(b) Kanalplanung: ✅ erledigt, s. eigenes Kapitel unten.** Kurzfassung: Thread 15, ZHA 20, Z2M 25, WLAN 1 + 11. Sauber bis auf **ZHA ch20, das auf der Unterkante von WLAN ch11 sitzt**. - **(c) Entity-Bruch: ✅ entschärft (User-Entscheid 2026-08-23) — „wir werden so umbauen, dass die Entitäten ihren Namen behalten."** Der Umbau benennt die neuen Entities auf die alten `entity_id`s zurück, damit Automationen, Dashboards und die FSM-Configs unverändert bleiben. ⚠️ **Zwei Fallen dabei:** (1) die alte `entity_id` ist erst frei, wenn die alte Integration das Gerät **losgelassen** hat — sonst hängt HA ein `_2` an; also erst entfernen, dann neu anlernen, dann umbenennen. (2) **Der Name überlebt, die History nicht** zwangsläufig — der Recorder keyt auf `entity_id`, das passt, aber `unique_id` und Device-Zuordnung sind neu. Energie-Dashboard-Statistiken brauchen ggf. einen Fix-Lauf. ⇒ Damit fällt der teuerste Posten der ganzen Abwägung weg. **Er gilt für Weg (A) und (C) gleich.** --- ## 📻 Das 2,4-GHz-Bild — alle vier Netze, live erhoben 2026-08-23 **Das ist der Rechenschritt, der bei „einfach auf Zigbee umstellen" gern übersprungen wird.** Es gibt hier **drei** 802.15.4-Netze neben dem WLAN, nicht eines: | Netz | Kanal | Mitte | belegt ca. | Geräte | Quelle | |---|---|---|---|---|---| | **WLAN ap1** | 1 | 2412 | **2401–2423** | — | CAPsMAN | | **Thread (OTBR)** | **15** | 2425 | 2424–2426 | ~30 Matter-Knoten | `ha_manage_radio thread` | | **ZHA** | **20** | 2450 | 2449–2451 | **52 Geräte** | ZHA-Diagnostics, EZSP/bellows | | **WLAN ap2** | 11 | 2462 | **2451–2473** | **26 Clients** | CAPsMAN | | **Z2M (`z2m25`)** | **25** | 2475 | 2474–2476 | — | `configuration.yaml`, zstack | - **ZHA-Koordinator:** SONOFF **Dongle-M**, angebunden **über Netz** (`socket://10.40.30.137:6638`), PAN 23386, `tx_power=8`. Zwei weitere ZHA-Einträge (Dongle Plus V2, Dongle-M_10E8) stehen auf *ignore* — das ist Absicht, sonst griffe ZHA nach dem Z2M-Stick. - **Z2M-Koordinator:** ITead **Sonoff Zigbee 3.0 USB Dongle Plus**, `adapter: zstack`. 🎯 **Befund: das Band ist gut geplant — mit genau einer Ausnahme.** - **Thread ch15 (2425)** liegt **2 MHz über** der Oberkante von WLAN ch1. Knapp, aber sauber. - **Z2M ch25 (2475)** liegt **2 MHz über** der Oberkante von WLAN ch11. Ebenso sauber — das ist die klassisch richtige Wahl. - 🟠 **ZHA ch20 (2450) liegt direkt auf der Unterkante von WLAN ch11 (2451)** — die einzige Nachbarschaft im Haus, und sie trifft das Netz mit **52 Geräten** gegen den AP mit **26 Clients**. ⚠️ **Aber: gemessen beißt sie nicht.** `PHY_CCA_FAIL_COUNT` des Koordinators steht bei **4** über die gesamte Zählperiode → keine nennenswerte Kanalbelegung. **Kein Handlungsbedarf**, Begründung im Kapitel „Kanalwahl für ZHA" unten. *(Meine erste Einschätzung „🔴 der eine Konflikt" war aus der Frequenztabelle abgeleitet, nicht gemessen.)* - 💡 **Die Lücke zwischen WLAN ch1 und ch11 (2423–2451) ist unbenutzt.** Dort liegen **ZB 16/17/18** (2430/2435/2440) — mitten im Freiraum, nichts sendet da. ⚠️ **Trotzdem nicht blind umziehen:** einen Kanalwechsel müssen 52 Geräte mitmachen; schlafende und ältere Router folgen dem `nwk_update_id`-Broadcast nicht zuverlässig und bleiben zurück. Das ist **dieselbe Fehlerklasse wie der Vorfall von 2024** (s.u.). Erst **Energy-Scan** in ZHA fahren, dann entscheiden — nicht umgekehrt. ### Wohin kämen die Shelly-Zigbee-Geräte? Sie wären **netzgespeiste Router**, keine End Devices — sie verändern also die Routing-Topologie des Netzes, dem sie beitreten. Drei Optionen, und die Wahl ist eine **Blast-Radius**-Frage: | | Wirkung | |---|---| | **In ZHA** (52 Geräte, ch20) | dichteres Mesh dort, wo die Fernbedienungen hängen — **aber** das ist das Netz, das die Automationen trägt, und es sitzt auf dem einzigen kontendierten Kanal | | **In Z2M** (ch25, sauberer Kanal) | technisch der bessere Kanal — **aber** genau das Netz, mit dem 2024 die Installation zusammenbrach (s.u.) | | **Getrennt halten** | 10 Router in **ein** Netz, das andere unangetastet lassen ⇒ wenn es schiefgeht, läuft die andere Hälfte des Hauses weiter | 🔑 **Empfehlung: die Trennung als Sicherheitsnetz nutzen, die es faktisch schon gibt.** Zwei unabhängige Zigbee-Netze sind ein Vorteil, kein Zufall — die Shellys gehören **komplett in eines**. ✅ **Welches, ist seit dem Inventar vom 2026-08-23 entschieden: ZHA.** Begründung im Kapitel „Welche Geräte sind für fehlerhaftes Routing anfällig?" unten — kurz: ZHA hat schon 24 Router (einer mehr fällt kaum ins Gewicht), Z2M hätte mit zehn Shellys **mehr als doppelt so viele wie heute**, und in Z2M hängt die **Wandbeleuchtung an ZLL-Altgeräten** — dort *ist* eine Routing-Störung die Lichterdisko. --- ## ⚠️ Christophs Z2M-Vorbehalt — ernst zu nehmen, und benennbar > **Erfahrung (2024):** „mir hats vor 2 jahren die ganze installation gekillt. nichts mehr steuerbar, > musste alles resetten und neu aufbauen. **Lichterdisko** war das damals." **Das ist kein diffuses Unbehagen, sondern eine bekannte Fehlerklasse.** „Alles unsteuerbar + Lichter feuern von selbst" ist das Bild eines **Zigbee-Broadcast-/Routing-Sturms**: das Netz sättigt sich mit Broadcasts, Routing-Tabellen thrashen, Kommandos kommen mehrfach oder gar nicht an. Typische Auslöser sind **Gruppen-/Binding-Schleifen**, ein einzelnes fehlerhaftes Router-Gerät (billige Bulbs sind berüchtigt), oder schlicht zu viele Broadcasts auf einem überlasteten Kanal. **Nicht** ursächlich ist üblicherweise „Z2M als Software" — dieselbe Klasse trifft ZHA genauso. ⚠️ **Der Root Cause von damals ist heute nicht mehr rekonstruierbar** (Netz wurde neu aufgebaut, keine Logs). Deshalb ist die ehrliche Aussage: *wir wissen nicht, ob es wiederkommt* — aber wir können die Bedingungen ungünstig machen: 1. **Blast Radius trennen** (s.o.) — die wirksamste Maßnahme, weil sie ohne Ursachenkenntnis wirkt. 2. **Nicht im Batch beitreten lassen.** 10 neue Router auf einmal ändern die Topologie schlagartig. Einzeln, mit ein paar Tagen Abstand — und dazwischen schauen, ob Kommandos noch prompt ankommen. 3. **Vorher einen Rückweg festhalten:** Z2M/ZHA-Backup (`coordinator_backup.json` bzw. ZHA-Backup) **vor** dem ersten Join. Genau das hat 2024 gefehlt — der Wiederaufbau war nötig, weil es kein Netz-Backup gab, nicht weil die Geräte kaputt waren. 4. **Keine Gruppen-Bindings für die Shellys** anlegen, solange sie neu sind. Direktes Binding ist der Pfad, auf dem Schleifen entstehen; über HA gesteuert passiert das nicht. 5. **Ein Abbruchkriterium vorher festlegen:** wenn nach einem Join die Latenz eines bekannten Geräts spürbar steigt, das Gerät wieder entfernen — **nicht** „wird sich schon einpendeln". 📌 **Und die nüchterne Gegenrechnung:** 10 zusätzliche *Router* machen ein Zigbee-Mesh normalerweise **stabiler**, nicht instabiler — das ist der Regelfall. Der Vorfall von 2024 ist ein Grund für Vorsicht und Backups, kein Grund, den Weg auszuschließen. --- ## 🌩️ Broadcast-/Routing-Sturm erkennen — Zähler, Baseline, Abbruchkriterium **Der Vorfall von 2024 war unsichtbar, weil niemand hingesehen hat, bevor es zu spät war.** Das ist lösbar: der EZSP-Koordinator führt Zähler mit, die einen Sturm **beschreiben**, bevor er als „Lichterdisko" auffällt. Hier die **Baseline vom 2026-08-23** (ZHA, read-only aus den Diagnostics) — gegen die wird nach jedem Join verglichen. ### Die Zähler, auf die es ankommt | Zähler | Baseline (kumuliert) | Bedeutung, wenn er steigt | |---|---|---| | 🔴 **`BROADCAST_TABLE_FULL`** | **0** | **Der eine Zähler, der einen Sturm beweist.** Broadcasts kommen schneller, als der Stack sie nachhalten kann. Alles > 0 ist ein Alarm. | | 🔴 **`ALLOCATE_PACKET_BUFFER_FAILURE`** | **0** | Koordinator hat keine Puffer mehr → **genau der Zustand „nichts mehr steuerbar"**. | | 🔴 **`PHY_TO_MAC_QUEUE_LIMIT_REACHED`** | **0** | Das Radio kommt mit dem Senden nicht nach. | | 🔴 **`TYPE_NWK_RETRY_OVERFLOW`** | **0** | Netzwerk-Retries laufen über. | | 🟠 `ROUTE_DISCOVERY_INITIATED` | 65 | Routen-Thrash. Ein paar pro Tag sind normal, ein Sprung um Dutzende in Minuten nicht. | | 🟠 `NEIGHBOR_STALE` / `NEIGHBOR_REMOVED` | 372 / **0** | Topologie-Unruhe. `REMOVED > 0` heißt: Router verschwinden aus der Nachbarschaftstabelle. | | 🟠 `MAC_TX_UNICAST_RETRY` / `…_FAILED` | 1.086 / 341 | **Retry-Quote ≈ 15 %, Fehlerquote ≈ 5 %** bei 6.222 Erfolgen. Das ist die Normallage dieses Netzes — Verdopplung = Warnsignal. | | 🟠 `PHY_CCA_FAIL_COUNT` | **4** | Kanal war belegt, als gesendet werden sollte = **Funkstörung** (WLAN oder Zigbee). | | 🟠 `NWK_FRAME_COUNTER_FAILURE` | 25 | Replay/Rejoin-Schleifen — ein Gerät, das immer wieder neu beitritt. | | ℹ️ `MAC_RX_BROADCAST` vs `MAC_RX_UNICAST` | 124.282 vs 18.620 | **Verhältnis 6,7 : 1.** Das ist die Normallage (Link-Status alle 15 s je Router). **Das Verhältnis ist die Kennzahl, nicht der Absolutwert** — wandert es Richtung 20:1, läuft ein Sturm an. | 📌 **Ablesen:** ZHA-Config-Entry → Diagnostics → `data.application_state.counters.ezsp_counters`. `_last_reset_value` = Langzeitsumme, `_raw_value` = seit dem letzten Reset. **Für Z2M** (hier 2.6.2) ist das Gegenstück `zigbee2mqtt/bridge/health` — es liefert je Gerät `leave_count`, `network_address_changes` und Fehlerzähler; `network_address_changes > 0` ist dort das Äquivalent zu „Topologie unruhig". ### Was man als Mensch sieht, bevor die Zähler gelesen werden - Kommandos brauchen **Sekunden** statt sofort — oder kommen **doppelt** an (Licht geht an und gleich wieder aus). - Geräte fallen **in Wellen** auf `unavailable`, nicht einzeln. - Lichter schalten **von selbst** — ein Broadcast, der im Netz kreist und mehrfach zugestellt wird. **Das ist die „Lichterdisko".** - Im HA-Log häufen sich `Failed to send request … device did not respond`. 🔑 **Merkregel: der Unterschied zwischen „ein Gerät zickt" und „das Netz kippt" ist die Gleichzeitigkeit.** Ein einzelnes stummes Gerät ist ein Gerät. Drei Geräte gleichzeitig, die vorher liefen, sind das Netz. ### Abbruchkriterium für den Test — vorher festlegen, nicht im Moment entscheiden **Rückbau des Testgeräts, sobald EINES davon eintritt:** 1. `BROADCAST_TABLE_FULL`, `ALLOCATE_PACKET_BUFFER_FAILURE`, `PHY_TO_MAC_QUEUE_LIMIT_REACHED` oder `TYPE_NWK_RETRY_OVERFLOW` **verlässt die Null**. 2. Retry-Quote **verdoppelt** sich gegenüber der Baseline (≈15 % → >30 %). 3. Ein Referenzgerät, das vorher prompt reagierte, braucht **wiederholt >2 s**. 4. Zwei oder mehr Geräte gehen **gleichzeitig** auf `unavailable`. **Nicht** „das pendelt sich schon ein" — genau diese Hoffnung hat 2024 den Neuaufbau gekostet. --- ## 🧭 Welche Geräte sind für fehlerhaftes Routing anfällig? (Inventar 2026-08-23) **Beide Netze vollständig durchgesehen.** Die Risiken sind konkret benennbar — und sie sind in **beiden** Netzen vorhanden, nur unterschiedlich. ### ZHA — 52 Geräte, davon **24 Router** | Klasse | Geräte | Einschätzung | |---|---|---| | Philips/Signify Hue | **14 Router** (LCT012 ×3, LST002 ×2, LCL006 ×2, 5060931P7 ×4, 4090331P9 ×2, 915005997801) | Als Router **gutmütig und stabil**. Aber: siehe Aqara-Zeile. | | IKEA | Signal Repeater ×2, STARKVIND, VINDSTYRKA, Driver 30W ×2, Floor lamp | unauffällig; die Repeater sind explizit als Router gedacht | | 🟠 **GLEDOPTO** | GL-SD-001, GL-C-006, GL-C-008 (**3 Router**) | **Dokumentierte Schwäche als Router** (ältere Firmware-Stände, Kind-Tabellen). Im Auge behalten. | | 🟠 Sunricher | HK-LN-DIM-A | meist unauffällig | | 🔴 **LUMI / Aqara** | `lumi.weather` ×3 (End Devices) | **Der klassische Instabilitätsherd.** Aqara-End-Devices halten sich nicht an die übliche Rejoin-Mechanik und **fallen weg, wenn sie an einem Nicht-Aqara-Router hängen** — Hue-Router sind der meistdokumentierte Fall, und davon stehen hier **14**. | ⇒ 🐤 **Die drei `lumi.weather` sind der Kanarienvogel.** Sie reagieren als Erste, wenn sich die Topologie ändert. **Vor und nach dem Shelly-Join gezielt auf ihr `last_seen` schauen** — nicht auf den Durchschnitt des Netzes. ### Z2M — 15 Geräte, davon **7 Router** | Klasse | Geräte | Einschätzung | |---|---|---| | 🔴 **Busch-Jaeger ZLL** | 6× „Zigbee Light Link power supply/relay/dimmer/wall-switch", **sw 1.2.0** | **Zigbee-Light-Link-Altbestand.** ZLL-Stacks sind älter als Zigbee 3.0, mit knappen Routing-/Kind-Tabellen — und **das ist die Wandbeleuchtung** (Küche, Wohnzimmer ×2, Kinderzimmer, Klo, Schlafzimmer). ⇒ **Genau die Geräte, aus denen eine „Lichterdisko" besteht.** | | 🔴 **Tuya-Familie** | Tongou Smart circuit breaker (Router) · Mini human breathe sensor · 24G mmWave · Soil sensor · **`_TZE284_7zazvlyn` „Automatically generated definition"** | Tuya ist die unberechenbarste Klasse; das letzte Gerät ist **nicht einmal sauber unterstützt** (Auto-Definition) — sein Verhalten ist unbekannt. | | 🟠 Aqara | Presence sensor FP300 | dieselbe Familie wie oben, End Device | | ℹ️ COOLO / IKEA | Soil moisture, TRADFRI on/off | unauffällig | 🎯 **Damit ist die Netzwahl für den Test entschieden — und zwar gegen die Intuition:** > **Das Testgerät gehört in ZHA, nicht in Z2M.** Drei Gründe: > 1. **Proportion.** ZHA hat **24 Router** — einer mehr ändert die Topologie kaum. Z2M hat **7**; zehn > Shellys würden den Router-Bestand dort **mehr als verdoppeln**. Genau solche abrupten > Topologiewechsel erzeugen die Route-Thrash-Phase, die man fürchtet. > 2. **Blast Radius.** In Z2M hängt die **Wandbeleuchtung** an ZLL-Altgeräten. Ein Routing-Problem dort > *ist* die Lichterdisko. In ZHA hängen Lampen, die sich zur Not einzeln schalten lassen. > 3. **Messbarkeit.** Für ZHA gibt es die Zählertabelle oben mit einer **echten Baseline**. Für Z2M > gibt es `bridge/health`, aber keine vergleichbar feinen Funkzähler. > > ⚠️ **Der Preis dieser Wahl:** die drei Aqara-`lumi.weather` sitzen in ZHA und könnten sich auf den > neuen, unerprobten Shelly-Router umhängen. Das ist beherrschbar (beobachten, notfalls den Shelly > wieder entfernen) — und es ist der Grund, warum der Test **ein** Gerät umfasst und nicht drei. --- ## 📡 Kanalwahl für ZHA — gemessen, nicht geschätzt 🔄 **Korrektur meines eigenen Befundes von vorhin.** Ich hatte ZHA ch20 als „🔴 der eine Konflikt im Haus" markiert, weil 2450 MHz auf der Unterkante von WLAN ch11 (2451) liegt. **Die Zähler des Koordinators widersprechen dem:** `PHY_CCA_FAIL_COUNT` steht bei **4** über die gesamte Zählperiode (gegen 6.222 erfolgreiche Sendungen). Wäre die WLAN-Nachbarschaft ein echtes Problem, stünde dort eine drei- bis vierstellige Zahl. **Die Adjazenz existiert auf dem Papier und beißt nicht.** **Empfehlung: ZHA bleibt vorerst auf Kanal 20.** - Ein Kanalwechsel müssten **52 Geräte** mitmachen. Schlafende und ältere Router folgen dem `nwk_update_id`-Broadcast **nicht zuverlässig** und bleiben auf dem alten Kanal zurück — sie sind dann verwaist und müssen einzeln neu angelernt werden. **Das ist exakt die Fehlerklasse von 2024**, ausgelöst durch die Maßnahme, die sie verhindern sollte. - Der Nutzen ist nach der CCA-Messung **nicht belegt**. Ein Risiko ohne belegten Nutzen ist kein Trade. **Falls doch einmal gewechselt wird — dann auf `18`:** | Kandidat | Mitte | Abstand zu Thread (2425) | Abstand zu WLAN ch11 (2451) | Urteil | |---|---|---|---|---| | 16 | 2430 | 3 MHz | 19 MHz | zu nah an Thread | | 17 | 2435 | 8 MHz | 14 MHz | brauchbar | | **18** | **2440** | **13 MHz** | **9 MHz** | ✅ **am besten zentriert** in der Lücke 2426–2451 | | 19 | 2445 | 18 MHz | 4 MHz | zu nah am WLAN | ✅ **Vorbedingung erfüllt: die Nachbar-WLANs sind am 2026-08-23 gemessen** (Kapitel unten). Ergebnis: das Fenster 2426–2448 ist nur **schwach** belegt (alles ≤ −81 dBm) — **ZB18 ist valide**. Der Handlungsdruck fehlt trotzdem (CCA = 4). 🔴 **Neue Randbedingung:** funken die **zwei neuen APs** ebenfalls auf 2,4 GHz, ist **ch6 belegt** und ZB18 fällt aus — dann sind 20 und 25 die einzig richtigen Plätze. Details und die Empfehlung dazu im Scan-Kapitel. --- ## 📡 WLAN-Umfeldscan 2,4 GHz — durchgeführt 2026-08-23 (beide APs) 🔴 **Gotcha zuerst, er kostet sonst eine halbe Stunde: `/interface wifi scan` geht am CAP NICHT.** Auf ap1 direkt (SSH, User in Gruppe `full`) antwortet das Gerät `failure: not allowed (/interface/wifi/scan)`. **Das ist weder device-mode noch eine Policy-Lücke** — der Gegentest beweist es: `/tool fetch` meldet auf demselben Gerät explizit *„not allowed **by device-mode**"*, und die Gruppe `full` hat `test` und `sniff`. Ursache ist der **CAPsMAN-Zustand**: ein CAP besitzt sein Radio nicht. **Der Scan läuft am Manager gegen die `cap-wifiN`-Schnittstelle** und funktioniert dort einwandfrei. Reiht sich ein in „unter CAPsMAN führt der Manager die Tabellen". *(Zuordnung am Messtag über `radio-mac` bestimmt, nicht angenommen: ap1 = `cap-wifi3` (5 GHz) / `cap-wifi4` (2,4 GHz), ap2 = `cap-wifi1` / `cap-wifi2`.)* ### Fremdnetze — die Nachbarschaft ist leise | WLAN-Kanal | Belegung ca. | Fremd-APs | stärkstes Fremdsignal | |---|---|---|---| | **1** (2412) | 2401–2423 | dahoam is dahoam −89, FRITZ!Box 6690 TM −87 | **−87** | | 3 / 4 (2417/2427) | 2406–2438 | meins.w −81/−93, Drei_H288A −81 | **−81** | | **6** (2437) | 2426–2448 | Liwest_9d44 −90, meins.liwest −88/−90, Liwest3422 −90 | **−88** | | 8 (2447) | 2436–2458 | meins.w −92, verstecktes Netz −84 | **−84** | | **11** (2462) | 2451–2473 | FRITZ!Box 7490 −81, LiwestBB93 −96, LiwestF0DA −90, LiwestEDBA −92, MIKENET2 −91 | **−81** | ⇒ **Kein einziges Fremdnetz über −81 dBm.** Die 2,4-GHz-Umgebung ist für eine Wohnlage bemerkenswert ruhig — die eigenen APs sind mit Abstand die lautesten Sender im Band. ### 🔴 Zwei laute Sender sind aber die eigenen — und keiner davon ist ein AP | Sender | Kanal | Signal | Was es ist | |---|---|---|---| | `AC:15:18:7B:62:21` SSID **`AC15187B6220`** | **11** (2462) | **−51** (von ap1) | **Shelly s23** (`dieleug-wohnzimmer_licht`, Pro Dimmer 2PM, `10.40.30.203`) sendet einen **eigenen Access Point** | | `54:F2:9F:12:51:F1` SSID **`DTUBI-92337823`** | **1** (2412) | **−59** (von ap2) | **Hoymiles-DTU** (Solar-Datenlogger, VLAN30) sendet ebenfalls einen eigenen AP | 🎯 **Der Shelly-Fund ist ein Rückstand aus TP17 und live bestätigt:** `WiFi.GetConfig` liefert `ap.enable = true`, SSID `AC15187B6220`, WPA2. Das ist ein **übrig gebliebener „Anker"** aus dem Migrationsverfahren von 2026-07-13 — dort wurde je Gerät vor dem STA-Write die geräteeigene AP-Funktion als Notanker aktiviert und **nach dem Verify wieder abgeschaltet**. Bei s23 ist das De-Anchoring **nicht angekommen**. Das Gerät funkt seither doppelt: als **Client auf ch1** (`dirtyvader-iot` an ap1, RSSI −56) **und als AP auf ch11**. - **Fix ist ein Einzeiler** über den vorhandenen Pfad: `WiFi.SetConfig {"config":{"ap":{"enable":false}}}` bzw. `mcp/shelly/migrate.py deanchor`. ⏸️ **Nicht ausgeführt — nicht beauftragt.** - 📌 **Und es ist ein Auftrag an die Abnahme, nicht nur ein Einzelfall:** die anderen 21 Anker sind **nie gegengeprüft** worden. Ein Sweep über alle Shellys (`WiFi.GetConfig` → `ap.enable`) gehört vor die nächste Funkaktion — read-only, eine Minute. - Die **DTU** ist derselbe Fall in anderer Farbe (Hersteller-Konfig-AP, der nie abgeschaltet wurde) — ob sie sich abschalten lässt, ist offen. ### Was das für die Zigbee-Kanalfrage heißt - Das Fenster **2426–2448** (WLAN ch4–8), in dem ZB **16/17/18** liegen, ist **belegt, aber nur schwach** — alles dort ≤ **−81 dBm**. **ZB18 (2440) bleibt damit eine valide Option**, die Messung widerlegt sie nicht. - **Handlungsdruck entsteht dadurch trotzdem nicht.** `PHY_CCA_FAIL_COUNT` = 4 gilt weiter; das ist die Aussage über den Ort, der zählt (der Koordinator), während der Scan die Orte der **APs** beschreibt. **ZHA bleibt auf 20.** ### 📻 Nachtrag: Homematic / HmIP — **868 MHz, damit außerhalb dieser Rechnung** **Christophs Ergänzung 2026-08-23.** Live nachgesehen: Integration `homematicip_local` an der CCU **`ccu.emsenhuber.net`** (RaspberryMatic, Technik UG, `10.40.20.232`) mit **37 Geräten** im Mischbetrieb — **Homematic classic** (BidCoS-RF, z.B. `HM-LC-Sw1-FM` „WC Lüfter", zentrale `HM-RCV-50`) **und HmIP** (u.a. `HmIP-HEATING` je Raum = die Heizungssteuerung). ✅ **Für die Kanalplanung ist das eine Entlastung:** beide Funkstandards liegen im **868-MHz-Band** (SRD860), nicht bei 2,4 GHz. **Homematic stört Zigbee, Thread und WLAN nicht — und wird von ihnen nicht gestört.** Es ändert an der Tabelle oben nichts. ⚠️ **Aber es ist ein fünftes Funkökosystem im Haus** (WLAN 2,4 · WLAN 5 · Zigbee ×2 · Thread · Homematic) — und es hat **seinen eigenen Ausfallmodus, der dem Broadcast-Sturm entspricht:** das 868-MHz-Band ist gesetzlich auf **1 % Duty Cycle** begrenzt. Wird das überschritten, stellt die Zentrale das Senden **minutenlang ein** — Symptom: „Befehle kommen nicht an, aber alles ist online". 🔎 **Merkregel: bei Homematic-Aussetzern zuerst den Duty Cycle der CCU ansehen, nicht die Funkabdeckung.** Ausgelöst wird er typischerweise durch zu häufige Sollwert-Schreibvorgänge — also durch Automationen, nicht durch Geräte. 📌 **Bezug zu TP29** (Anwesenheitserkennung fürs Energiesparen): die `HmIP-HEATING`-Geräte **sind** der Aktor, den TP29 ansteuern würde. Wer dort präsenzabhängig regelt, schreibt Sollwerte — und läuft damit genau in die Duty-Cycle-Grenze. **Das gehört in TP29s Entwurf, bevor die erste Automation scharf geht.** ### 🆕 Und was die zwei neuen APs damit zu tun haben **Sehr viel — das ist der Punkt, an dem die AP-Frage und die Zigbee-Frage dieselbe Frage werden.** 2,4 GHz hat **drei** überlappungsfreie Kanäle: 1, 6, 11. Heute belegt das Haus **zwei** davon (ap1 = 1, ap2 = 11) und lässt **ch6 frei** — genau das Fenster, in dem ZB 16/17/18 liegen. 🔴 **Kommen zwei APs dazu und funken alle vier auf 2,4 GHz, ist ch6 belegt.** Damit fällt ein ZHA-Umzug auf 18 aus, und **ZB20 (zwischen 6 und 11) sowie ZB25 (über 11) sind dann die einzigen richtigen Plätze** — also exakt die heutige Belegung. *Die aktuelle Konfiguration wäre dann nicht nur vertretbar, sondern die einzig sinnvolle.* 💡 **Empfehlung für den AP-Aufbau, die beides löst:** **2,4 GHz nicht auf allen vier APs betreiben.** Vier 2,4-GHz-Zellen auf drei Kanälen stören sich zwangsläufig selbst, und die Reichweite von 2,4 GHz ist so groß, dass zwei Zellen die Wohnung ohnehin abdecken — die IoT-Geräte hängen heute an **zwei** APs und kommen zurecht. Die beiden neuen APs also als **5-GHz-Schwerpunkt** betreiben (2,4 GHz aus oder stark reduziert). Das - hält **ch6 frei** und damit die Zigbee-Option offen, - vermeidet Selbststörung im vollsten Band, - und legt die neue Kapazität dorthin, wo sie tatsächlich fehlt: **5 GHz an den Rändern** (TP25: die Redundanz ist der Schwachpunkt, nicht die Abdeckung). ⚠️ **Vor dem Aufbau messen, nicht danach:** derselbe Scan auf 5 GHz (`cap-wifi1`/`cap-wifi3`) fehlt noch — 5 GHz ist das Band, in dem die neuen APs wirklich geplant werden müssen. --- ## 🔌 UART-Backup: was das praktisch heißt (nur für Weg C nötig) **Kurzantwort: ja, einmal physisch ans Gerät — aber es ist keine Taste, und es ist genau einmal.** **Der J6-Header** (7-polig, 1,27 mm Raster, auf der Rückseite der Platine): | Pin | Funktion | GPIO | |---|---|---| | 2 | **TXD** → RXD des Adapters | GPIO16 | | 3 | **RXD** ← TXD des Adapters | GPIO17 | | 4 | **3,3 V** — Versorgung vom Adapter | — | | 6 | **BOOT** — muss beim Einschalten **LOW** sein | GPIO0 | | 7 | **GND** | — | **Der Ablauf je Gerät:** Modul stromlos machen und **ausbauen** → Gehäuse öffnen → fünf Pins an einen USB-UART-Adapter (**3,3 V, kein 5 V!**) → **GPIO0 beim Anlegen der Versorgung auf LOW** ziehen → `esptool.py read_flash` über die vollen **8 MB** → das Image wegsichern → dann erst flashen. - ⚡ **Nicht am Netz.** Die Versorgung kommt beim Flashen vom Adapter, nicht von 230 V — das Gerät muss also aus der Wand. - 🔘 **Kein Reset-Knopf.** Der ESP32-C6 geht über die Strapping-Leitung in den Download-Modus. Viele Adapter schalten das per **DTR/RTS** automatisch; ob das an diesem J6 durchgeschleift ist, steht nicht in der Doku — **am ersten Gerät ausprobieren**, sonst GPIO0 von Hand nach GND brücken. - ✅ **Danach nie wieder UART.** Alle weiteren Updates laufen **OTA** (Matter-OTA, Dashboard-Upload). Der Aufwand fällt **einmal je Gerät** an, nicht bei jedem Update. - 🔁 **Recovery** = dasselbe Prozedere rückwärts, mit dem gesicherten 8-MB-Image. Bricht dabei der Strom weg, während der Bootloader geschrieben wird, ist das Gerät **nur noch per UART** zu retten — ein zweites Mal öffnen, kein Weg über die Luft. - ⚠️ **Der Weg ohne UART existiert** (Paket über die Shelly-Web-UI hochladen), **kann aber kein Backup erzeugen** und ist damit praktisch einseitig. 🎯 **Konsequenz für die Wegwahl:** die Frage „wie viele Module sitzen Unterputz hinter einem Schalter" entscheidet über den Aufwand von Weg (C) mehr als alles andere. **Weg (A) Zigbee braucht davon nichts** — das ist ein normales Update über den Hersteller-Kanal. --- ## Vorbedingungen aus dem Netz (stehen bereits, nur für den Thread-Weg relevant) - ✅ **Thread-Border-Router läuft**, ~30 Matter-Knoten produktiv (OTBR auf demselben Host wie HA). - ✅ **Commissioning-Pfad erprobt:** temporäre SSID `dirtyvader-infra` (VLAN20) nach [`matter-pairing-infra-ssid-runbook.md`](matter-pairing-infra-ssid-runbook.md) — am 2026-08-22 mit dem TIMMERFLOTTE bewiesen. `cfg-infra`/`dp-infra`/`sec-infra` stehen dauerhaft am Manager. - 🔴 **Nötig ist der Umweg, weil TP12.1 offen ist:** zwischen VLAN10 (iPhone) und VLAN20 (Border Router) wird **kein IPv6 geroutet** → Commissioning-Etappe 2 bricht ab. Und `ble_proxy` ist wirkungslos, seit der ESP32-BT-Proxy ausgeschlossen wurde (User 2026-08-22). ⇒ **Jedes weitere Thread-Gerät zahlt diesen Umweg erneut** — das stärkste Argument für TP12.1. - ⚠️ **Firewall ist deny-by-default** — ein neuer Dienst über eine VLAN-Grenze braucht eine explizite Regel. Für den **Zigbee**-Weg heißt das: der Pfad Gerät → Z2M (`10.40.20.106`) läuft über den Zigbee-Koordinator, nicht über IP — es entsteht **kein** neuer VLAN-Übergang. Ein Punkt weniger. --- ## Ablauf **Schritt 0 — entscheiden, nicht flashen.** Weg (A), (B) oder (C). Grundlage ist die Tabelle oben. Das ist Christophs Abwägung; sie hängt an Garantie, Rückweg und daran, wie lange er auf (B) warten will. **Schritt 1 — Pilot mit genau EINEM Gerät.** Kandidat: **`s26 bad_luefter`** oder **`s12 dieleug_steckdosen`** — beide 2PM Gen4, funktional unkritisch, **keine** Verbrauchsmessung im Energie-Dashboard. **Nicht** mit einem Küchengerät anfangen (Kühl-/Tiefkühlschrank hängen dort). Bei Weg (C) vorher **UART-Vollbackup**, sonst gibt es keinen Rückweg. **Schritt 2 — HA-Seite bilanzieren, bevor das zweite Gerät drankommt.** Welche `entity_id`s sind neu, was zeigt noch auf die alten? `grep` über die HA-Automationen und die FSM-Configs im `ha-xstate`-Repo (`machines/*.json`). **Erst wenn der Pilot in HA vollständig verdrahtet ist**, war er erfolgreich. **Schritt 3 — Wellen zu 3–4 Geräten**, nach Raum gruppiert, gleiches Abnahmekriterium. **Schritt 4 — Zahl zurückmelden:** wie viele Geräte sind aus `dirtyvader-iot` verschwunden. Diese Zahl macht die PSK-Rotation planbar. ### Abnahmekriterium **Pro Gerät ein frischer Knoten im Zielnetz UND eine funktionierende HA-Entity** — nicht die Anzeige in einer Tabelle. Im Netz-Projekt hat genau diese Verwechslung einmal **14 Stunden** gekostet: die Registration-Table zeigte 25 zufriedene Clients, während keiner davon eine IP bekam. --- ## Verzahnung mit der PSK-Rotation (parallel, nicht nacheinander) **User-Entscheid 2026-08-23:** beides läuft **gleichzeitig**. Möglich macht das der **Passphrase-Override je MAC** in `/interface wifi access-list` (RouterOS 7): neuer PSK aufs Profil, noch nicht migrierte Geräte übergangsweise per MAC mit dem alten weiter, danach Liste leeren — **kein Flag-Day**. 🔑 **Die eine Regel, die die Parallelität kostenlos macht:** ein Gerät, das ohnehin den Funk wechselt, bekommt den **neuen PSK gar nicht** — nur einen Übergangseintrag, und verschwindet später ganz. ⚠️ **Nicht vergessen:** `s1`/`s2`/`s3` sind ausgesteckt und **in HA nicht eingebunden**. Sie kommen beim nächsten Einstecken mit dem **alten** PSK zurück — sie gehören auf die Override-Liste, sonst stehen sie im Dezember im AP-Mode. --- ## Offene Fragen für die erste Sitzung 1. Ist **`s4 kueche_mikrowelle`** ein Gen4? Falls ja → bester Pilot, größter Gewinn (−93 dBm heute). 2. Wie viele der 10 Kandidaten sind physisch zugänglich? Unterputz-Module hinter Schaltern zu öffnen ist bei Weg (C) Pflicht (UART), bei Weg (A) nicht. 3. Bei Weg (A): **welcher Zigbee-Kanal**, gemessen gegen ap1 ch1 / ap2 ch11 — und was sagt der bestehende Z2M-Koordinator dazu, der schon IKEA-Geräte trägt? 4. ✅ **Geklärt (Christoph 2026-08-23): es sind ZWEI Drucker.** Der **P750W ist der Etikettendrucker** und hängt korrekt auf **VLAN30** (`10.40.30.5`). Der **eigentliche Drucker ist ein Brother MFC auf VLAN10** — live bestätigt: `10.40.10.6`, MAC `30:05:5C:78:86:20` (OUI = Brother Industries), ARP-Status `delay` = aktiv, **keine DHCP-Reservierung** (statisch konfiguriert). Beide Angaben waren richtig, sie meinten verschiedene Geräte. 📌 **Für TP5 relevant:** die Merkregel „Drucker fällt mit **udp/161 SNMP** aus, nicht mit 631" (`ref_printer_snmp_before_ipp`) betrifft den **VLAN-übergreifenden** Fall. Der MFC steht im **selben VLAN** wie die Macs — dort greift die `forward`-Kette gar nicht. --- ## Verweise - Steuerung: [`teilprojekte.md`](teilprojekte.md) → **TP17.1**, **TP12.1** (IPv6/Matter), Follow-up **PSK-Rotation** - Migrationshistorie der Shellys (VLAN1 → VLAN30, 26 Geräte, 0 Fehler) inkl. Anker-Verfahren gegen den AP-Mode-Fallstrick: [`teilprojekte-archiv.md` → TP17](teilprojekte-archiv.md#tp17) - Werkzeug: `mcp/shelly/` — `discover.py` (read-only), `migrate.py` (Dry-Run default). ⚠️ **Kein Rotate-Kommando vorhanden**, es bräuchte eine Variante über denselben `set_sta`-Pfad. - HA-Seite: `~/dev/ha-xstate` (FSM-Configs `machines/*.json`)