diff --git a/docs/handoff-tp25-session-20260821.md b/docs/handoff-tp25-session-20260821.md new file mode 100644 index 0000000..6a87cf3 --- /dev/null +++ b/docs/handoff-tp25-session-20260821.md @@ -0,0 +1,162 @@ +# Übergabe: TP25-Session — vom Verdacht zur Raumkarte + +> **Stand bei Übergabe: 2026-08-21, alles live verifiziert und committet.** Diese Datei ist der +> Einstieg. Der Arbeitsplan steht in [`tp25-wlan-roaming-messung-20260820.md`](tp25-wlan-roaming-messung-20260820.md); +> hier steht, was du wissen musst, bevor du ihn aufschlägst. + +--- + +## 1. Dein Auftrag in zwei Sätzen + +**TP25 ist der kritische Pfad.** TP6 ist am 2026-08-20/21 gemessen und entschieden — formal Fall B, +aber im Videocall nicht wahrnehmbar; die Zahlen stehen in [`tp6-praemisse-messrunbook.md`](tp6-praemisse-messrunbook.md) §5 +und TP6 ist bewusst **nachrangig**. Was die Calls tatsächlich zerreißt, ist der Funk, und der ist jetzt +raumgenau vermessen. + +--- + +## 2. 🔴 Zuerst: es ist eine Transaktion offen + +``` +TEST-ether3-trunk-ap1-sideboard OFFEN crs326-core Scope bridge-vlan Frist 2026-09-04 +``` + +**Die Compliance ist absichtlich nicht 92/92.** `ether3` wurde zum Trunk gemacht, damit ap1 an seinem +neuen Platz (Sideboard) überhaupt läuft — die Änderung steht **am Gerät**, aber **nicht in der SoT**. +Das ist kein Versehen, sondern der Zustand „uncommitted". + +```bash +python3 nautobot/gc-transaktion.py status +``` + +**Geschlossen wird sie so:** + +- **Bleibt ap1 am Sideboard** → Template nachziehen (`ether3` in die sieben `tagged`-Listen, + **und aus der `untagged`-Liste von VLAN 40 raus**), dann `--refresh-compliance`, dann + `gc-transaktion.py commit --change-id TEST-ether3-trunk-ap1-sideboard`. Der Commit **verweigert + sich**, solange der Scope noch driftet — das ist die eingebaute Sicherung gegen einen Commit, der + nur behauptet, die SoT sei nachgezogen. +- **Geht ap1 zurück auf ether15** → `gc-transaktion.py rollback --change-id …` erzeugt aus dem + Snapshot einen Rückbau-**Vorschlag**; prüfen, per `gc-manual-plan.py` deployen, dann + `rollback --erledigt`. + +Hintergrund zum Mechanismus: [`docs/transaktionen/README.md`](transaktionen/README.md). + +--- + +## 3. Verifizierter Ist-Stand (nichts davon neu erheben) + +| | | +|---|---| +| **ap1** | **am Sideboard**, Uplink `crs326-core ether3` (trägt jetzt VLAN 10/20/30/40/50/90/99), erreichbar in 447 µs, **12 Clients** | +| **ap2** | unverändert **am Boden im Arbeitszimmer**, 16 Clients | +| SSIDs auf Sendung | **fünf**, nicht sechs: main, iot, media, untrusted, guest. `cfg-infra` existiert als Objekt, ist aber **in keiner Provisioning-Regel** → nie ein VAP. Kein Drift. | +| pro Radio | 5 GHz: 4 SSIDs · 2,4 GHz: 5 SSIDs (Beacon-Airtime, relevant in dichter Nachbarschaft) | +| 802.11k/v/FT | **aktiv** (`st-main`, `rrm=yes`, `wnm=yes`, `ft-over-ds=yes`) — `ref_ft_is_not_roaming` ist historisch | +| Kanäle | ap1 5180 (ch36) / 2412 · ap2 5220 (ch44) / 2462, 5 GHz auf **20/40 MHz** | +| Übergabekosten | bei gutem Signal **0–2,6 s**, meist unter 0,4 s — gemessen, nicht geschätzt | +| TP6 | Upload-Last +28…+47 ms; Call lief durch **ohne einen einzigen Problem-Klick** | +| Linerate | **9,6 Mbit up / 54,6 Mbit down** (stand vorher nirgends im Repo) | + +--- + +## 4. Messstand TP25 — zwei Raumkarten + +**Raumkarte 1**, ap1 am alten Platz (2026-08-20 abends) · **Raumkarte 2**, ap1 am Sideboard (2026-08-21). +Signal = Durchschnitt, wie der Manager den Client sieht. + +| Raum | Karte 1 | Karte 2 | | +|---|---|---|---| +| Technik UG | −43 (ap1/5) | — | | +| Diele UG | **−44** (ap1/5) | **−69** | schlechter | +| Kinderzimmer | **−53** (ap1/5) | **−75** | schlechter | +| Schlafzimmer | **−61** (ap1/5) | **−83** (ap2/**2,4**) | **deutlich schlechter** | +| Bad | — | **−83**, 31 % Verlust | schlecht | +| Küche | — | −61 (ap1/5) | gut | +| Wohnzimmer | — | −59 (ap1/5) | gut | +| Treppe | −51 | −62 | ok | +| Arbeitszimmer | −49 | −50 | gut | +| Technik OG | −56 | −44 | besser | +| Diele OG | — | **−50**, 0 % über 5,5 min | **sehr gut** | +| Terrasse | −72, 43 % Verlust, 20,4 s Lücke | −55 am Telefon-Platz | s. u. | + +**Zur Terrasse, korrigiert:** der Platz, an dem das Telefon normalerweise steht, ist mit **−46 bis +−66 dBm gut**. Schlecht ist der Teil **dahinter** (Karte 1, −72 dBm). Die 51 % Verlust in Karte 2 sind +**kein Funkloch**, sondern Ruhezustand — siehe §6. + +**Kurzfassung:** das Sideboard verbessert das OG und opfert die Schlafräume. + +--- + +## 5. Die Frage, die als Nächstes drankommt + +Christophs Maßangaben (2026-08-21) drehen den Befund um: + +> Schlafzimmer und Kinderzimmer liegen **2 bzw. 4 m Luftlinie von ap1**. ap2 ist 4–6 m entfernt, mit +> **zwei zusätzlichen Mauern** dazwischen. Kinderzimmer liegt **< 1 m** an der Trennmauer zum Schlafzimmer. + +Gemessen wurde aber: beide Räume hängen an **ap2 auf 2,4 GHz bei ⌀ −83 dBm**. + +🔴 **Ein Client, der bei 2 m Luftlinie zum besseren AP am schlechteren klebt, hat kein +Abdeckungsproblem, sondern ein Steering-Problem.** Damit ist das die erste Stelle in diesem Haus, an +der **Fund E (`signal-range`-Boden) wirklich hilft** — hier gibt es eine bessere Alternative; auf der +Terrasse gab es keine, dort hätte derselbe Boden nur rausgeworfen. + +**Test, bevor irgendetwas gesetzt wird:** + +```bash +bash docs/tp25-walk-messung.sh +``` + +Derselbe Gang, aber in **jedem Schlafraum stehen bleiben** und **alle 10–20 s die Konsole antippen** +(hält das Telefon wach — sonst sind die Verlustzahlen wertlos, s. §6). Protokollieren, **ob und wann** +der Client von ap2 auf ap1 wechselt. Auswertung: +`python3 docs/tp25-gehweg-auswertung.py --dir `. + +--- + +## 6. Fallen, die in dieser Session je einen Fehlbefund gekostet haben + +| Falle | Symptom | Merkregel | +|---|---|---| +| **Ruhezustand ≠ Funkloch** | 58 s Ping-Lücke bei −53 dBm und 275 Mbps PHY | iOS beantwortet ICMP mit gesperrtem Display nicht. Bleibt Signal **und** Rate hoch, war das Gerät erreichbar. Die Auswertung markiert das jetzt. | +| **Teilzustand nach `Failed`** | 6 von 7 VLANs gesetzt | `ether3` war in VLAN 40 **untagged** — ein Port kann nicht zugleich tagged und untagged sein. Nach jedem Fehlschlag am Gerät nachzählen. | +| **CF-403 ohne User-Agent** | saubere Ping-Reihe über tote Flows | `speed.cloudflare.com/__down` antwortet `curl` mit 403 + 1 Byte. Aufgefallen nur am Core-Sampler (164 kbit statt 50 Mbit). | +| **Treiber-Heartbeat** | 5,5 min Call ohne Messung | Start-Klick ohne laufenden Treiber schreibt nur einen Marker. Die Konsole warnt jetzt sichtbar. | +| **RouterOS + SSH-Mehrzeiler** | `expected closing brace` | Die Console parst zeilenweise; als Einzeiler braucht jeder `do={}`-Block ein abschließendes `;`. | +| **`tr` puffert blockweise** | CSV scheinbar leer | In Pipes 4-KB-Puffer. `\r` im Shell-Loop entfernen, nicht per `tr`. | +| **Marker URL-kodiert** | `RAUM%3DDIELE%20OG` | Erst `unquote`, dann **nicht** hochschreiben. | +| **`NAUTOBOT_TOKEN`** | Abbruch nach dem Dry-Run | `gc-manual-plan.py` braucht die Variable im Environment (steht in `docs/nas-vlan20/stacks/210-nautobot.yml`, gitignored). | + +--- + +## 7. Werkzeug, das diese Session hinterlässt + +| Datei | Zweck | +|---|---| +| [`tp6-monitor-core.sh`](tp6-monitor-core.sh) | Core-Sampler: CPU, WAN-Rate, Client-Funkwerte im Sekundentakt, mit Reconnect | +| [`tp25-walk-messung.sh`](tp25-walk-messung.sh) | Gehweg-Messung: Ping **vom Core** aufs Telefon + Sampler | +| [`tp6-marker/server.py`](tp6-marker/server.py) | Klick-Konsole fürs Telefon: Phasen, Anweisungen, Not-Aus, **Raum-Buttons** | +| [`tp25-gehweg-auswertung.py`](tp25-gehweg-auswertung.py) | Tabelle je Raum: Signal, Verlust, längste Lücke, AP | +| [`tp6-auswertung.py`](tp6-auswertung.py) | Phasenauswertung der Sampler-CSV | +| [`../nautobot/gc-transaktion.py`](../nautobot/gc-transaktion.py) | `begin`/`status`/`commit`/`rollback` für Teständerungen | + +Rohdaten aller Läufe: `docs/messdaten/`. + +--- + +## 8. Spielregeln (unverändert, plus eine neue) + +1. **Config-Änderungen ausschließlich über Nautobot Golden Config.** Kein Direkt-Write per MikroMCP. +2. **NEU: Teständerungen bekommen eine Transaktion.** `gc-transaktion.py begin` vor dem Deploy — + mit Scope und Frist. Ein Drift ohne Akte ist ab jetzt ein Fehler, kein Versuch. +3. **Abnahme misst Wirkung, nicht Anzeige.** `--assert` liest am Gerät; bei Funkänderungen `monitor`, + nie das Profil. +4. **Bei Statuswechseln den Header mitziehen.** Der wiederkehrende Fehler dieses Repos. +5. **Eine Session zur Zeit an diesem Repo.** `git pull` vor dem ersten Edit. + +## 9. Nicht dein Auftrag + +TP6 neu aufrollen (gemessen und entschieden), Fasttrack-Reihenfolge (entschieden), CF-Writes. +Und: **kein neuer AP**, solange die User-Randbedingung gilt — erst muss aus den vorhandenen alles +herausgeholt sein, und mit dem Steering-Test aus §5 ist genau das noch offen. diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 685a2e7..ca7736f 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -64,7 +64,13 @@ ab jetzt bei jeder Änderung mitgezogen, nicht nur die TP-Abschnitte.)* -**Nächster Schritt (Stand 2026-08-21): TP25 — die WLAN-Übergaben, nicht CAKE.** +**Nächster Schritt (Stand 2026-08-21 abends): TP25 — Steering-Test in den Schlafräumen.** +> 📋 **Einstieg: [`handoff-tp25-session-20260821.md`](handoff-tp25-session-20260821.md)** — dort steht +> der verifizierte Ist-Stand, die Messfallen und der nächste Test. +> ⚠️ **Auf `crs326-core` ist eine Config-Transaktion OFFEN** (`TEST-ether3-trunk-ap1-sideboard`, +> Frist 2026-09-04): ap1 hängt testweise am Sideboard, `ether3` wurde dafür zum Trunk. Die Compliance +> ist deshalb **absichtlich** nicht 92/92 — `python3 nautobot/gc-transaktion.py status`. +> 🆕 **TP29** (Anwesenheitserkennung fürs Energiesparen) ist als Idee angelegt, nicht auf dem Pfad. > 📌 **Die TP6-Prämisse ist am 2026-08-20/21 gemessen** (Runbook §5): formal Fall B (+28…+47 ms unter > Dauer-Upload), aber im Videocall **nicht wahrnehmbar** — kein einziger Problem-Klick über sechs > Lastphasen. Laut war stattdessen der Funk: **Sticky Client + Band-Ping-Pong, zwölf Wechsel in neun @@ -1244,6 +1250,18 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung". > grenzt an Terrasse, Arbeitszimmer und Treppe, kostet **keinen neuen AP** und erfüllt damit die > User-Randbedingung; zu klären ist die Verkabelung (ap2 hängt an `crs326-branch ether24`). > **(3)** dritter AP erst, wenn beides nicht reicht. +> **(F) 2026-08-21 abends, Raumkarte 2 — ap1 versetzt ans Sideboard (`core ether3`).** Das OG gewinnt +> (Diele OG −50 ⌀ über 5,5 min mit 0 % Verlust, Technik OG −44), die **Schlafräume verlieren**: +> Schlafzimmer von −61 (ap1/5 GHz) auf **−83 (ap2/2,4 GHz)**, Kinderzimmer von −53 auf −75, Bad −83 mit +> 31 % Verlust. 🔴 **Und genau das ist vermutlich KEIN Abdeckungsproblem:** laut User liegen Schlaf- und +> Kinderzimmer **2 bzw. 4 m Luftlinie von ap1**, während ap2 4–6 m entfernt ist und zwei zusätzliche +> Mauern dazwischen hat. Ein Client, der so am ferneren AP klebt, ist ein **Steering**-Fall — und damit +> die erste Stelle im Haus, an der **Fund E (`signal-range`-Boden) wirklich hilft**, weil es hier eine +> bessere Alternative gibt. **Test steht aus** (Handover §5). Korrektur zur Terrasse: der Platz, an dem +> das Telefon normalerweise steht, ist mit **−46…−66 dBm gut**; schlecht ist der Teil dahinter. +> 📋 **Übergabe: [`handoff-tp25-session-20260821.md`](handoff-tp25-session-20260821.md).** +> ⚠️ **Auf `crs326-core` ist eine Config-Transaktion OFFEN** (`TEST-ether3-trunk-ap1-sideboard`, Scope +> `bridge-vlan`, Frist 2026-09-04) — die Compliance ist deshalb **absichtlich** nicht 92/92. > **Und das passiert TROTZ aktivem 802.11k/v und FT** — live geprüft: `st-main` mit `rrm=yes`/`wnm=yes`, > `ft-over-ds=yes`. Die Merkregel `ref_ft_is_not_roaming` („11k/v fehlen") ist damit **historisch**. > **Reihenfolge der Maßnahmen** (Doku §6, respektiert die User-Randbedingung „kein neuer AP, solange @@ -1837,3 +1855,30 @@ TP22 · TP-R · **TP3.2** (08-17) · **TP5** (08-18) · **TP7.1** (08-18) · **T 7. **Foundation (2026-07-14):** **TP15** (MikroTik-Switching / Omada-WLAN, 2× CRS326 bestellt) ∥ **TP20 (Platform-Postgres, single-site replication-ready)** → **TP21 (Nautobot Golden Config)** ∥ **TP20.1 (Vaultwarden→PG + 2-Site-HA)**. TP20 hängt an **TP18 ①** (Garage-Bucket für pgBackRest). + +--- + +### TP29 — Anwesenheitserkennung fürs Energiesparen ▸ 💡 **IDEE, noch nicht auf dem kritischen Pfad** (angelegt 2026-08-21) +> **User-Formulierung (2026-08-21):** „Personen im Haus orten mit BT (Shellys), WiFi und Radar. So +> kommen wir dem Ziel der Energieersparnis ohne Komfortverlust groß näher." + +- **Ziel:** raumgenaue Anwesenheit als Eingangssignal für Heizung und Licht — sparen, **ohne** den + typischen Komfortverlust („erst kalt, dann warm, wenn jemand da ist"). +- 🔎 **Der Entwurfsgedanke sind die komplementären Schwächen der drei Quellen** — keine trägt allein: + | Quelle | erkennt | erkennt **nicht** | + |---|---|---| + | **BLE über die Shellys** | grobe Zonen, billig, überall vorhanden | Menschen ohne getragenes Gerät; Raumgrenzen unscharf | + | **WLAN** (Registration-Table am Manager: Gerät, AP, Signal) | wer mit Telefon da ist, inkl. AP-Zuordnung | Menschen ohne Telefon; Raum nur so genau wie die AP-Abdeckung | + | **mmWave-Radar** | auch die **stillsitzende Person ohne Gerät** | braucht einen Sensor **je Raum** | +- ✅ **Was schon steht:** Shellys vollständig auf VLAN30 (TP17 ✅), HA produktiv — und mit + [`docs/tp6-monitor-core.sh`](tp6-monitor-core.sh) existiert seit TP25 bereits ein Sammler, der die + WLAN-Präsenzdaten am Manager mitschreibt (Gerät → AP → Signal, im Sekundentakt). +- ❓ **Offene Fragen für die erste Session:** Datenpfad ins HA (MQTT oder REST?) · Firewall-Regeln für + neue Sensorik (**TP5 ist deny-by-default**, jeder neue Dienst über eine VLAN-Grenze braucht eine + Regel) · Aufbewahrung und Privatsphäre der Ortsdaten · ob Radar-Sensoren auf `dirtyvader-iot` laufen + oder eigene Segmentierung brauchen. +- **Abgrenzung:** TP25 **misst** den Funk, TP29 **nutzt** ihn als Sensor — dieselbe Datenquelle, + anderes Ziel. Die Raumkarten aus TP25 sind für TP29 direkt verwertbar: sie sagen, wie genau die + WLAN-Quelle einen Raum überhaupt auflösen kann. +- **Abh.:** keine harten. Profitiert von TP25 (Abdeckung/AP-Zuordnung) und TP11 (Monitoring), wenn es + dahin kommt. **Kein Blocker für irgendetwas.** diff --git a/docs/tp25-wlan-roaming-messung-20260820.md b/docs/tp25-wlan-roaming-messung-20260820.md index 46e28dc..d834e9e 100644 --- a/docs/tp25-wlan-roaming-messung-20260820.md +++ b/docs/tp25-wlan-roaming-messung-20260820.md @@ -216,7 +216,50 @@ sinnvoll, aber **nur für Innenräume mit Alternative**, und er löst das gemess --- -## 7. Handlungsoptionen — in der Reihenfolge, in der sie Sinn ergeben +## 7. Raumkarte 2 (2026-08-21 abends) — ap1 am Sideboard, und ein Steering-Verdacht + +ap1 wurde physisch versetzt (Uplink jetzt `crs326-core ether3`, s. offene Transaktion +`TEST-ether3-trunk-ap1-sideboard`). Derselbe Gang, dieselben Werkzeuge. Signal = Durchschnitt. + +| Raum | Karte 1 (ap1 alt) | Karte 2 (ap1 Sideboard) | | +|---|---|---|---| +| Diele UG | −44 (ap1/5) | −69 | schlechter | +| Kinderzimmer | −53 (ap1/5) | −75 | schlechter | +| **Schlafzimmer** | **−61** (ap1/5) | **−83** (ap2/**2,4**) | **−22 dB** | +| Bad | — | −83, 31 % Verlust | schlecht | +| Küche / Wohnzimmer | — | −61 / −59 (ap1/5) | gut | +| Arbeitszimmer / Technik OG | −49 / −56 | −50 / −44 | gut bis besser | +| **Diele OG** | — | **−50**, 0 % über 5,5 min | **sehr gut** | + +**Das Sideboard verbessert das OG und opfert die Schlafräume.** + +### 7.1 Warum das vermutlich kein Abdeckungsproblem ist + +Maßangaben des Users (2026-08-21): Schlaf- und Kinderzimmer liegen **2 bzw. 4 m Luftlinie von ap1**; +**ap2** ist 4–6 m entfernt und hat **zwei zusätzliche Mauern** dazwischen. Gemessen wurde trotzdem +`ap2 / 2,4 GHz / −83 dBm`. + +🔴 **Ein Client, der bei 2 m Luftlinie zum besseren AP am schlechteren klebt, hat ein +Steering-Problem, kein Abdeckungsproblem.** Und damit ist das die erste Stelle in diesem Haus, an der +**Fund E (`signal-range`-Boden) tatsächlich das richtige Werkzeug ist** — hier existiert eine bessere +Alternative, auf der Terrasse (§6) existiert keine. + +**Test vor jeder Maßnahme:** derselbe Gang, aber in jedem Schlafraum stehen bleiben und alle 10–20 s +die Konsole antippen; protokollieren, ob und wann der Client auf ap1 wechselt. + +### 7.2 Zwei Korrekturen aus diesem Lauf + +1. **Die Terrasse ist differenzierter als in §6 geschrieben.** Der Platz, an dem das Telefon + normalerweise steht, liegt bei **−46 bis −66 dBm** — der Dead Spot ist der Teil **dahinter**. +2. **Die 51 % Verlust dieses Laufs auf der Terrasse sind KEIN Funkloch**, sondern Ruhezustand: während + der 58-Sekunden-Lücke stand der Client bei **−53 dBm, 275–309 Mbps PHY-Rate** und hatte weiter + 3 kbit/s Hintergrundverkehr. Die Auswertung markiert solche Lücken seitdem selbst. **Lange + unmarkierte Abschnitte ohne Interaktion sind für Verlustzahlen wertlos** — die Signalwerte bleiben + gültig. + +--- + +## 8. Handlungsoptionen — in der Reihenfolge, in der sie Sinn ergeben > **Randbedingung des Users (2026-08-17, gilt weiter):** *„ich weigere mich einen anderen access point zu > kaufen solange ich nicht das gefühl habe, wir haben alles aus dem ap rausgeholt."* Deshalb steht neue @@ -239,7 +282,7 @@ sinnvoll, aber **nur für Innenräume mit Alternative**, und er löst das gemess --- -## 8. Was das für die Call-Qualität bedeutet +## 9. Was das für die Call-Qualität bedeutet `call-quality-diagnosis.md` stuft Roaming als **Nebenfaktor** ein — begründet mit Kontrollexperiment 1: Christophs **nationale** Videocalls waren auf derselben WLAN-Infrastruktur gut. Diese Logik hält, und