85 Commits

Author SHA1 Message Date
b91bac1265 TP45 Schicht B2: VLAN30-Reservierungen ins Oktett-Schema
36 DHCP-Reservierungen wandern aus dem Pool-Fenster (.5, .8, .202-.244)
in die Schema-Baender .11-.14 / .151-.176 / .177-.196. Dazu die CCU-Leiche
.232 (status=waiting, last-seen=never; die CCU lebt in VLAN20) entfernt und
SONOFF-NSPanelPro von einer dynamischen Lease auf .249 zu einer statischen
Reservierung auf .12 gepinnt.

Neuer Job `tp45-v30-leases` in gc-configplan.py. Er laedt MOVES/REMOVE/ADDS
per importlib aus tp45-leases.py, statt sie zu kopieren -- die Tabelle dort
ist die SSoT des Umzugs, eine zweite Kopie liefe still auseinander.

Warum der Job zwei Selektor-Formen traegt: die erste Fassung schrieb
ueberall `[/ip dhcp-server lease [find where ...]]`. In `[:len ...]` ist das
Syntaxfehler (`expected command name (line 1 column 55)`, live gemessen) --
Golden Config meldete trotzdem Job SUCCESS und Plan Completed, das Geraet
blieb unveraendert. Aufgefallen ist es an der Zahl der Log-Zeilen: von 38
`:if`-Statements hat kein einziger Zweig geloggt. Richtig ist
`[/ip dhcp-server lease find where ...]` ohne Klammerpaar um `find`;
die Argument-Form `set [find where ...]` bleibt.

Abnahme am Geraet, nicht am Plan-Status: 39 Leases im Soll-Schema, .232 und
.249 geraeumt, NSPanelPro dynamic=false; Compliance 145/145, keine Drifts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 16:18:05 +02:00
b509a2325e TP45 Schicht B1 Fix: Befehlspraefix nicht doppelt rendern
Erster Lauf nach dem Einbau ergab 144/145 -- und die eine Drift war mein Fehler,
nicht der des Geraets: backup_lines() strippte mit l[1:] nur das fuehrende '/',
nicht den ganzen Befehl. Das gerenderte Soll enthielt dadurch
`/ip dhcp-server lease ip dhcp-server lease add ...`.

Gefunden hat das die Compliance-Zahl selbst. Genau deshalb ist der NENNER die
Abnahme und nicht der Zaehler: 140 -> 145 beweist, dass die neue Rule auf allen
fuenf Geraeten auswertet; 145/145 beweist, dass das Soll stimmt.

Ausserdem: seed --force fuer einen bewussten Neuschnitt (der Guard gegen
versehentliches Re-Baseline bleibt).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 14:59:14 +02:00
4d273117b6 TP45 Schicht B1: DHCP-Reservierungen ins GC-Soll (Renderer + ComplianceRule)
Die 54 statischen Reservierungen des Cores standen in KEINEM Soll: das Template
rendert kein einziges /ip dhcp-server lease, und die Sektion stand unter keiner
ComplianceRule. Ein GC-Recovery von null haette einen Core ohne Reservierungen
erzeugt, in dem jedes IoT-Geraet in den Pool faellt -- und weil Compliance nur
prueft, was gerendert wird, waere die Zahl dabei gruen geblieben. Dieselbe
Luecke wie die handgelaufene `nautobot`-Adressliste.

- mikrotik_routeros.j2 [5b]: rendert local_config_context_data.dhcp_leases,
  gleiches Idiom wie firewall_filter.
- tp45-leases.py: seed/move/check. Zeilen werden verbatim uebernommen und nur
  im address=-Token getauscht -- das erhaelt Quoting und die 14 client-id-Felder.
  Reihenfolge bleibt die Geraete-Reihenfolge (Einfuege-, nicht numerisch).
- ingest-dhcp-lease-rule.py: Feature+Rule `dhcp-lease` auf RouterOS,
  config_ordered=False.

Noch KEIN Geraetewrite -- der Ist-Stand wurde als Soll gesetzt (Re-Baseline).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 14:55:00 +02:00
92bd4aac85 TP45: pool-v20 auf .200-.249 verengt -- Schema-Baender .100-.199 freigegeben
Die 7 DHCP-Pools starteten alle bei .100 und ueberlappten damit die beiden
Oktett-Baender, die dieses TP gerade belegt: .100-.149 (Server-Hosts) und
.150-.199 (App-Services). In VLAN20 ist das eine echte Kollisionsflaeche --
nautobot .154-.158, gitea .157, pve-mcp .173 und shelly-mcp .180 tragen ihre
IP GERAETELOKAL und stehen in keinem Lease-Eintrag, der Core kann sie also
nicht schuetzen und einem DHCP-Client .154 anbieten.

Entscheid 2026-09-21: nur pool-v20 und pool-v30 werden verengt, v20 zuerst.
VLAN10/40/50/90/99 bleiben bei .100-.200 -- dort gibt es kein Schema-Band,
das etwas gewoenne, und VLAN40/VLAN10 haetten sonst 11 Sonos (.191-.201),
den iPhone (.196) und den Mac (.82) mitgezogen.

VLAN20 kostet die Verengung nichts: eine statische Reservierung (nas-bf
.20.10, in .10x) und 0 dynamische Leases.

pool-v30 bleibt bewusst unangetastet -- dort liegen 35 statische
Reservierungen IM Fenster .200-.249 (26 Shellys .202-.226/.233, SwitchBot
.227, Twinkly .228, Withings .230/.231, lichterketten .236/.237, Nuki
.241/.244, CCU .232). Erst Schicht B zieht die um, dann pool-v30.
Nebenbei faellt damit die .30.250-Kollision: der Sonoff Dongle-M sitzt dort
statisch, der Pool reicht heute bis .250.

Neuer Job `tp45-pool-v20` (gc-configplan.py) mit gezaehltem Selektor: ein
`find where`, das 0 trifft, sieht wie "nicht vorhanden" aus statt wie
"kaputt" -- ein blankes `set [find where name=...]` liefe ins Leere und der
Job meldete Erfolg.

🔴 Lehre aus dem ersten Fehlversuch: jedes config_set-Statement muss auf EINER
Zeile klammer-vollstaendig sein. Mit `:if (...) do={` am Zeilenende geht
RouterOS in den Fortsetzungs-Modus und zeigt einen anderen Prompt, der
netmiko-Treiber verliert sein Muster und der Deploy stirbt mit
`E1015: Pattern not detected: ...@crs326\-core\].*$|#.*$)` -- Plan auf
Failed, ohne etwas geschrieben zu haben.

Abnahme: Gerate-Read pool-v20 = 10.40.20.200-10.40.20.249 (total=50,
used=0); DHCPOFFER-Probe auf vmbr0.20 -> 10.40.20.200 mit
Domain Name Server 10.40.20.30, 10.40.20.31; Probe-Lease wieder entfernt;
Compliance 140/140 ohne Drift.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 14:39:40 +02:00
974ecbc855 TP45 Schicht A: DHCP-Soll liefert AGH .30/.31 statt .36/.37
Die vier Core-Forward-Regeln fuer den Resolver waren nachgezogen, die
DHCP-Antwort an die Clients noch nicht: /ip dhcp-server network trug
weiterhin dns-server=10.40.20.36,10.40.20.37. Ein Client haette nach dem
AGH-Umzug den Resolver unter der alten Adresse gesucht.

Template geaendert, nach bf-golden-config gepusht (Git-DataSource ist die
Wahrheit, nicht die lokale Datei), Git-Sync, am Core gesetzt (alle 7 Netze),
per DHCPOFFER-Probe auf vmbr0.20 bestaetigt (Domain Name Server:
10.40.20.30, 10.40.20.31), Compliance 140/140 ohne Drift.

Randbefund (nicht in diesem Commit): die 7 DHCP-Pools starten live bei .100
und ueberlappen die Schema-Baender .100-.199 — pool-v30 reicht sogar bis
.250, wo statisch der Sonoff Dongle-M sitzt. Entscheid 2026-09-21: nur
pool-v20 und pool-v30 werden auf .200-.249 verengt, v20 zuerst.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 14:34:49 +02:00
139d7c029d TP45 Schicht A: AGH-DNS-Freigaben .30/.31 im GC-Soll + am Core nachgezogen
- nautobot/tp45-agh-firewall.py (neu): pflegt die vier `TP5-E2: LAN->AGH dns*`-
  Regeln im `local_config_context_data.firewall_filter` (add/remove, Dry-Run
  default, Unified Diff). Bewusst NICHT `ingest-core-firewall.py` -- das ist ein
  RE-BASELINE-Werkzeug und wuerde die Aenderung mit sich selbst absegnen.
- gc-configplan.py: Jobs `tp45-agh-fw` (add + move vor die Log-Regel; `caddy`
  dahinter, damit der AGH-Block zusammenbleibt) und `tp45-agh-dhcp`.

Fix in `create_plans`: unter derselben `change_control_id` liegen nach einem
zweiten Lauf zwei Plaene. Die Auswahl folgte der REST-Reihenfolge und traf den
ALTEN -> der config_set-Guard brach ab, obwohl der neue Plan korrekt erzeugt
war. Jetzt gewinnt der juengste; die alten bleiben Historie.

Fund: `find where dst-address=<bare-IP>` matcht in RouterOS nie (nur `~` als
Regex). Die Zeile stand als "Verifikation" in
docs/transaktionen/TP23-agh-firewall.commands.rsc:7 und hat dort seit dem
2026-08-25 immer `0` gemeldet, ohne je etwas zu pruefen. Gleiche Klasse wie
`nc -z` (09-01): eine Pruefung, die 0 meldet, sieht wie "fehlt" aus, nicht wie
"kaputt".

Abnahme: Reihenfolge am Geraet (vier neue Regeln vor dem Drop), Compliance
140/140 / 0 Drifts mit `RouterOS - ip-firewall-filter` (ordered, frisch
bewertet, `actual` traegt die neuen Zeilen), `dig` vom VLAN10-Client gegen
.30/.31/.36/.37 alle beantwortet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 13:27:23 +02:00
b52d6aa49e TP45 Schicht A: Nautobot .30/.31/.32/.34 -> .154/.155/.156/.158
Oktett-Klasse .150-.199 (App-Services). Nautobot gibt damit .30/.31 an
AGH frei. .157 ist gitea, deshalb nimmt redis .158.

- Datenmigration ueber neues nautobot/tp45-ip-move.py: Nautobot verbietet
  das Aendern einer IP nach dem Anlegen -> anlegen/primary_ip4 umhaengen/
  Altobjekt loeschen, in dieser Reihenfolge
- Stack-Redeploy (PUT /api/stacks/203), Caddy-Backend, Core-Literal *24
  ueber GC deployt (Plan 51a90e25) mit Wirksamkeitspruefung am Geraet
- caddy/deploy.sh: push_verified() ersetzt den push||push-Fallback.
  `pct push` meldet Exit 0 AUCH wenn es die Quelle nicht lesen kann, der
  Fallback griff deshalb nie und `caddy validate` pruefte die ALTE Datei
  -> gruene Abnahme bei unveraendertem Zustand (Symptom: 502 bei
  gesundem Backend)
- 39 Referenzen in 28 Dateien mitgezogen; lebende Doku nachgezogen
  (CLAUDE.md, ip-plan.md, cf-tunnel-mapping §0-Kopf, TP16.3/TP31-Prosa)
- GC-Compliance 140/140, 0 Drifts

Neue Funde (TP45-Prosa + CLAUDE.md):
- Die Core-Adressliste `nautobot` wird von GC nirgends gerendert -> ein
  Recovery von null erzeugt einen Core, in den Nautobot nicht mehr per
  SSH kommt. Gleiche Klasse wie die fehlenden DHCP-Reservierungen.
- Regel *24 (Literal) und *28 (Liste) sind Dubletten; der Literal steht
  bei 0 Paketen. Zusammenlegung bleibt offen.
- gc-manual-plan.py: /api/extras/job-log-entries/ liefert 404 (Nautobot
  3.x) -> bei gescheitertem Deploy fehlt die Fehlermeldung.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 13:14:35 +02:00
8c6cb84dd1 TP45: TP32-Oktett-Tabelle korrigiert + TP45/TP46 angelegt
Bestandsaufnahme 2026-09-21 ergab: die FQDNs sind nicht in Caddy/CF
verschwunden, sondern (a) AGH wertet DNS-Rewrites im Filter-Pfad aus und
ueberspringt sie fuer unfiltrierte Clients -> Fallback auf den Core, der
nur 10 von 26 Namen haelt; (b) ds-bf ist der einzige Ingress-Eintrag, der
Caddy umgeht, und faellt damit unter TP5 deny-by-default.

- TP32-Oktett-Tabelle: .10-.19/.20-.29-Split, Server-Block .100-.149,
  Broker/Funk .9x, Platform .8x, Alt-IP-Reservierung dokumentiert
- TP32-Ordnungsgruppe 40 auf 102/112 reduziert (CCU gehoert zu haos)
- TP37-Status: P1+2 waren als "offen" notiert, live sind 28 VMs/26 Services
- TP45 (VLAN20/30 ins Schema + DNS/FQDN) + TP46 (CF-SSoT/Recovery) als
  Prosa-Abschnitt, Zeiger in der Pflichtlektuere

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-21 12:58:40 +02:00
e87619e89b TP38: bridge-port comment ungequotet + core place-before->move
RouterOS exportiert comment=TP38-OOB-MGMT ohne Quotes (kein Leerzeichen),
das Template hatte sie gesetzt -> bridge-port Drift. Fix: unquoten.

Der Deploy-`place-before=[find ...]` wurde von Netmiko ignoriert (Regel
landete hinter dem drop); im Job jetzt add + move.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 19:33:22 +02:00
177ba100eb TP38: OOB-MGMT-Port (ether23 untagged VLAN99) + Branch-Input-Firewall
Template mikrotik_routeros.j2: ether23 auf core+branch als OOB-Port
(pvid=99, admit-only-untagged-and-priority-tagged) + VLAN99 untagged=ether23.
Branch bekommt einen deny-by-default-Input-Filter (8 Regeln, src-Rahmen
spiegelt /ip service available-from), Core eine Regel "OOB->core mgmt".

Neue Skripte: ingest-tp38-oob.py (seedet firewall_filter in beiden
local_config_context_data) und der gc-configplan.py-Job tp38-oob (Deploy).
ConfigPlans angelegt+approved, Deploy steht noch aus.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 19:23:59 +02:00
bce40d182d TP25: Handoff Steering-Threshold + Terrasse-Verifikation
st-main-5g deployed (140/140), Terrasse am iPhone verifiziert (2.4G statt 5G/-80).
MacBook-Klebrigkeit dokumentiert, transition-time=immediate wird nicht umgesetzt.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 18:40:22 +02:00
1d86983f63 TP25: st-main-5g Parameter-Reihenfolge gefixt + Commands-File
RouterOS exportiert transition-threshold vor wnm; Template-Reihenfolge ans
Export-Format angepasst. Deploy über manuellen Plan (Plan cc8340a8) — 140/140.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 18:30:24 +02:00
27effe937e TP25: AP-Zuordnung definitiv + Doku-Drift geschlossen
ap1=Sideboard/core ether3, ap2=Technik UG/core ether21, ap3=Technik OG/branch
ether24 (live per IP+MAC+Switch-Port). ap2 ether1 = :39. Nautobot Location
gesetzt (vorher None). Kanäle ap1/ap2 mitkorrigiert.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 18:27:19 +02:00
2cf32bde14 TP25: Steering 5G bricht früher ab (st-main-5g, -72/5s)
Terrasse saß am Rundgang 09-15 auf der -80/5G-Kante. transition-threshold
-80→-72, transition-threshold-time 10s→5s — nur für 5G; 2,4G bleibt auf
st-main (unset -80) für Reichweite draußen.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 18:27:16 +02:00
1f19a3b4a9 TP25: AP-Zuordnung definitiv geklärt, ap1-Redundanz gemessen
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 18:06:15 +02:00
3e727f1b3b TP25: AP-Zuordnung per Kabel-Test geklärt, Messrunde Vorher, Tausch ap1↔ap3 begonnen
Handoff der Vor-Ort-Session: ap1=Sideboard, ap2=Technik OG, ap3=Technik UG (per
Kabel-Test eindeutig). Messwerte Vorher (Innenräume + Terrasse) festgehalten;
Terrasse wird ausschließlich marginal von ap2 bedient. Tausch ap1↔ap3 angefangen,
aber Netzzustand unklar (ap2 down, ap3 an ether8). Nächste Schritte dokumentiert.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-15 17:11:17 +02:00
037d2bd22c TP25: Deckungsfix Variante 3 terminiert -- Umsetzung 2026-09-15/16
Letzter offener TP25-Posten: Terrasse ein eindeutig dominantes Signal
geben (Ende von Band-Thrash und -89-Kollaps-Roams). Plan gemess Variante 3
(Deckenstrahler an den guten Platz, hAP in den Drei-Raeume-Schatten),
Vorher/Nachher-Terrassenmessung + Anruf-Abnahme, Kanalplan unberuehrt,
Config nur ueber GC-Weg. Issue #17, Kommentar #232.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-15 12:17:38 +02:00
0e6742f1d7 TP25: DTU-Verifikation DURCH -- 45000 ms eliminiert den 5:05-Zyklus, Fund F abgeschlossen
- 09-15 12:11: DTU online seit 06:41:49, uptime 5h29m, 0 Disconnects
  (Vergleich 09-14 mit 30,5 s: fuenf Zyklen in 18 min). DTU sitzt heute
  auf ap3-2,4 statt ap2/ch11.
- Fund F damit abgeschlossen: Ursache = DTU-Cloud-Recovery, getriggert
  durch hmsmqtt-Polling-Kollision. Messplan #225 gegenstandslos.
- Issue #17, Kommentar #230.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-15 12:12:30 +02:00
b7d82fe300 TP25: Fund-F-5:05-Zyklus geklaert -- Cloud-Recovery der DTU bei Polling-Kollision
- Wireshark-Analyse (hms-mqtt-publisher PR #110, HMS-800W-2T): Poll <30 s
  resettet den Countdown, Cloud-Updates fallen aus; nach 4-5 min startet
  die DTU eine neue TCP-Session -- und dabei (Log-Beweis 09-14) eine
  vollstaendige WiFi-Disassoziation inkl. DHCP-Churn. Zyklus-Abstaende
  decken sich aufs Minutenkomma. Fund F damit neu interpretiert.
- Ursache: hmsmqtt 30500 ms (Grenzzone). Hebel = Poll-Rate, nicht
  DNS-Hoheit: Christoph hat 45000 ms gesetzt (09-14 abends).
- Verifikation ab 09-15 frueh (Log-Lauf ohne 4-5-min-Zyklen = Fund-F-
  Abschlussbeweis); Fallback: DTU-Firmware klaeren (ha-hoymiles-wifi#134).
- Issue #17, Kommentar #228.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 22:18:35 +02:00
13a996c6d9 TP25: DTU-Hebel korrigiert -- OpenDTU/AhoyDTU entfaellt fuer HMS-800W-2T
Recherche 09-14 abends: HMS-XXXXW-2T (W = eingebaute DTU, protobuf-
Protokoll) wird von AhoyDTU/OpenDTU nicht unterstuetzt (lumapu/ahoy#1189
seit 09-2023 offen; Christophs eigene AhoyDTU inkompatibel). Lokale Tools
(hmsmqtt, dtuGateway, ha-hoymiles-wifi) nehmen die DTU nicht von der Luft.
Einziger Airtime-Heibel bleibt DNS-Hoheit ueber die Cloud -- von Christoph
bewusst zurueckgestellt (Cloud-Aufzeichnungen bis hmsmqtt + WLAN stabil).
Korrektur auch als Issue-17-Kommentar #227; Messplan #225 bleibt gueltig.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 21:13:27 +02:00
2a21afe74a TP25: Messplan Wechselrichter/DTU (Hoymiles HMS-800W-2T) angelegt; 20:37-Nachtrag
- DTU geht mit der Sonne an/ab (09-14: 07:09-19:35) -- nachts unbetelligt,
  20:37-Verlust passierte ohne sie. Tagsueber ~5:05-Zyklus auf ch11 bei -53.
- Messplan (Issue #17, Kommentar #225): Referenz-Client auf ch11 pinnen,
  30-60 min Ping, Korrelation gegen die 5:05-Taktmarken.
- Hebel falls messbar: OpenDTU/AhoyDTU-Dongle statt Cloud-DTU (5-Min-Takt
  ist S-Miles-Telemetrie per Design, kein Ethernet an der DTU-WLite,
  Pin auf anderen AP kontraindiziert).
- 20:37-Nachtrag zur Abnahme: Totalverlust eigener Klasse (-89-Roam +
  iOS-Aufgeben, identisch 19:01 mit ft=no) -- keine ft=yes-Regression.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 21:04:42 +02:00
9fdcab58ad TP25: ft=yes-Abnahme DURCH — Anruf uebersteht 5 Band-Wechsel in 60 s
Live-Beleg 2026-09-14 20:33-20:34, Terrasse: nur roamed-to-Events, keine
disconnected-Zeile mehr im Fenster (davor 20:29/20:31 noch zwei volle
Trennungen). Hebel (1) damit komplett abgenommen; offen bleibt nur noch
der Deckungsfix Variante 3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 20:37:37 +02:00
441e97ed84 TP25: ft=yes-Durchfuehrung dokumentiert (140/140, 0 Drifts, CAP-Abnahme sauber)
- CLAUDE.md: 09-04-Entscheid (ft=no) mit Ruecknahme 09-14 konsistent gemacht —
  Weg, Plan-ID, Compliance-Stand und CAP-Abnahme vermerkt, damit keine
  Folgesession einen ft=no-Zustand liest, der nicht mehr existiert.
- teilprojekte.md TP25: Hebel (1) auf DURCH gesetzt (Sequenz, Plan b1135f3e,
  Asserts, Polling-Timeout-Folgenlosigkeit), offene Abnahme = Terrassen-Anruf.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 20:34:47 +02:00
89eb9dc3ac TP25: sec-main-Begruendungskommentar im Template auf 09-14-Stand bringen
Kontextkommentar ueber der sec-main-Zeile dokumentierte noch den 09-04-Entscheid
(ft=no); nach der Ruecknahme am 09-14 konsistent gemacht (Entscheid-Historie bleibt
als Zeile erhalten).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 20:21:47 +02:00
4e80ffac28 TP25: sec-main zurueck auf ft=yes/ft-over-ds=yes (Ruecknahme 09-04, Hebel-A gescheitert)
- Go Christoph 2026-09-14 nach Terrasse-In-situ-Session: mit ft=no ist jeder
  Roam eine Voll-Reassoziation -- darin starben 2 Anrufe.
- Known-Good-Stand vor Hebel-2: Fund-E-Abschlussmessung 09-02 lief auf
  ft=yes/ft-over-ds=yes + 7.24.1 ruhig (4 reauth/8,6 h, 0 Ausfaelle).
- Template [6c]-Kommentar auf Stand 09-14 gebracht: signal-range-Boden
  geprueft und gescheitert (kein band-Property, cap-wifiN-Rejoin-Falle).
- Commands-File docs/transaktionen/TP25-ft-yes-secmain.commands.rsc fuer
  den GC-Deploy via gc-manual-plan.py (Dry-Run gelesen).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 20:21:13 +02:00
548d73d84a TP25: ap2-In-situ widerlegt (Terrasse), Hebel-A-Machbarkeitspruefung negativ; TP30 #9 GITEA_ACCESS_TOKEN
- Handoff 2026-09-14: iPhone-Flapping auf der Terrasse = 5-GHz-Zellkante
  (-76..-81) plus client-getriebene Band-Wechsel in der Uberlappungszone
  -70..-77; vor ap2 (1-2 m) -49..-51 dBm, >2 min stabil => HW-Verdacht
  (23:02-Befund 2 m/-80) in situ widerlegt, kein Tausch begruendet.
- Hebel "Access-List-Band-Boden < -76 auf 5G" nicht sauber ausdrueckbar:
  kein band-Property, Interface-Scoping bricht am cap-wifiN-Rejoin,
  SSID-/MAC-Scope trae fen 2,4 GHz mit (Lockout-Risiko). Nicht umgesetzt.
- TP30: Posten #9 vorgemerkt -- GITEA_ACCESS_TOKEN am 09-14 ueber einen
  Fehlerpfad (URL-Konstruktion -> ValueError-Traceback) ins Transkript
  geraten; sechster Vorfall der Leak-Familie, neue Unterklasse.
- Gitea: TP25-Issue #17 Kommentar 217, TP30-Issue #20 Kommentar 218.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-14 20:16:20 +02:00
3eb03ae7b4 Plaintext-Secrets entfernt: Portainer-State-Dump gelöscht, n8n-Bearer + AdGuard-Token redaktieren
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-14 15:14:57 +02:00
3a97bbc41c opencode.jsonc entfernt (durch opencode.json ersetzt, Migration abgeschlossen)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-14 15:09:50 +02:00
7d237577e1 MCP: 7 globale Server auf Projektebene (env-Referenzen, keine Tokens im Repo)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-14 11:58:09 +02:00
777c4e0984 opencode.json: Projekt-MCP-Konfig mit {env:}-Platzhaltern
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-14 11:57:28 +02:00
425070ce11 Handoff: CF_API_TOKEN gerollt + Verify-Endpoint-Gotcha (Gitea #69 closed)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-13 15:13:23 +02:00
ae87e9f511 TP23 Stufe 5 Redesign: pro-Person Self-Service (agh-exception.py + Bau-Spec)
Stufe 5 reopened — DAU-Requirements (pro Person, "zuletzt geblockt -> 1 Klick",
temp+dauerhaft umschaltbar, scoped HA-Dashboard) nicht erfuellt → Stufe 6 gated.
agh-exception.py: $client-scoped allow/unallow, list-exceptions, recent-blocked
(selftest OK, reine Logik netzunabhaengig getestet). HA-Bau-Spec + Personen-
Client-Modell dokumentiert. Bau/Abnahme on-network offen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 14:32:13 +02:00
f941731ac4 TP35 ✅ abgeschlossen: Header ⏳→✅ (Gitea #25 closed/status:done)
5/6 Schichten durch; Schicht-3-pro-Projekt-Rollout laut Abgrenzung eigene
Sessions; On-Network-mikromcp-Smoketest als Merkposten → TP30 #20.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 12:52:52 +02:00
3877c23505 GC-Backup: täglicher Scheduler angelegt (vorher gab es keinen)
Diagnose: die GC-Backups standen seit 2026-09-04, weil NIE ein Scheduler
existierte — Backup/Intended/Compliance liefen nur manuell aus Sessions. Die
"2×/Tag per SSH"-Annahme (CLAUDE.md Bot-Master-Zeile + gc-snapshot.py-Docstring)
war nie real; beide korrigiert.

Fix: Nautobot-Job "Execute All Golden Configuration Jobs - Multiple Device"
enabled + ScheduledJob "GC Backup+Compliance – taeglich" (platform=RouterOS,
täglich 03:30 UTC, Backup→Intended→Compliance). Sofort-Lauf SUCCESS, alle 5
Geräte backup/compliance auf 2026-09-12 10:35, frischer bf-golden-config-Commit.
Announcement-Eintrag ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 12:36:48 +02:00
123a0fefdf TP35 Schicht 2 ✅ angewandt: claude.json-Secrets auf {env:} geflippt
Flip via ~/dev/.bin/schicht2-claude-json-migrate.py --apply-claude bei beendeter
App (Backup .bak-20260912-*), App neu gestartet, MCP-Server laden sauber. Alle 7
Secrets (mikromcp 5× PASS, hostinger Token, n8n Bearer) jetzt {env:}, verifiziert.
Restcheck: authentifizierter mikromcp-Read on-network (09-12 nur Connect-Timeout
VLAN99:80 = Erreichbarkeit, kein Auth-Fehler).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 12:28:23 +02:00
aebf3776ac TP35 Schicht 2 vorbereitet: exports.zsh komplett, claude.json-Flip ausstehend
exports.zsh um die 3 von opencode bereits referenzierten, aber fehlenden
MCP_MIKROMCP_{ROUTER_AP3,CRS326_CORE,CRS326_BRANCH}_PASS ergänzt (25 Vars,
gui-env-sync 25/25 in launchd-Env). claude.json hält noch 7 Klartext-Secrets;
DRY-RUN bestätigt alle Ziel-Vars MATCH. Flip läuft bei BEENDETER App über
~/dev/.bin/schicht2-claude-json-migrate.py --apply-claude (nicht aus laufender
Session — Claude Code schreibt State in die Datei). Announcement-Eintrag ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 12:19:00 +02:00
b6f2129b41 TP35 Schicht 4+5 ✅: /news-Announcements + Backup-Guard abgenommen
Schicht 4 (Announcement): docs/announcements.md angelegt (Format
## YYYY-MM-DD — Titel + Betrifft/Aktion, neueste oben) + globaler Skill /news
(liegt in ~/.claude/skills/news/ UND ~/.config/opencode/skills/news/, cp kein
Symlink). /news zeigt Einträge seit dem letzten Lauf (Seen-State ~/.news-seen/).
Erste Einträge: SSoT-Cutover + TP36-Live.

Schicht 5 (Backup-Guard): abgenommen — Guard + pre-commit-Hook live verdrahtet,
hat beim TP36-Live-Commit real gegriffen. Grenze dokumentiert (check prüft nur
Existenz der Guard-Datei, nicht deren Alter).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 12:14:10 +02:00
82cd8098ef TP36-Live ✅: gc-snapshot.py live — 5 CustomFields auf dcim.Device
Legt die fünf TP36-Live-CustomFields (grouping TP36-Live) auf dcim.device an
und befüllt sie für alle 5 RouterOS-Geräte (ap1/2/3, crs326-branch/core)
ausschließlich aus Nautobot/Golden-Config — kein Geräte-Kontakt:
  ros_version 7.24.1 (flotte), compliance_pct 100, dhcp_server_count
  (core 7, Rest 0), dns_upstream_mode (core doh, Rest plain), mgmt_ip.

Idempotent (get-or-create CF, PATCH Device), Dry-Run default, --commit schreibt.
Token aus gitignored 210-nautobot.yml, Backup-Text nur intern geparst (nie ausgegeben).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-12 12:11:29 +02:00
614025eafb TP43 ✅ umgesetzt: dw-FritzBox-DNS auf FB-Upstream .36/.37 + Rebind-Ausnahme
Christoph on-site: Upstream 10.40.20.36 + .37, DNS-Rebind-Schutz-Ausnahme
bf.emsenhuber.net, Fallback-Haken "öffentliche NS bei Unreachbarkeit der
primären" gesetzt (existiert auf diesem FRITZ!OS-Stand) → Ideal-Variante,
.37-Redundanz bleibt, BF-down fällt auf public. Gitea #32 closed (status:done).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 14:59:30 +02:00
677dade184 TP43: DHCP-Multi verworfen (FB-DHCP nur 1 DNS-IP) → FB-Upstream .36/.37 + Rebind-Ausnahme
dw-FritzBox kann per DHCP nur eine DNS-IP ausliefern → "mehrere NS an die
Clients" scheidet aus. Neue Richtung: Clients → 10.95.10.1 (FB), die FB
forwardet an Upstream 10.40.20.36 + .37 (beide BF, Voll-Resolver).

- Zwingend: DNS-Rebind-Schutz-Ausnahme bf.emsenhuber.net (sonst filtert die FB
  die Privat-IP-Antworten 10.40.x als Rebind weg).
- BF-down-Fallback: FRITZ!OS-"öffentliche NS bei Unreachbarkeit"-Setting, sonst
  public im Alternativ-Slot (kostet .37, dann strikt-primär verifizieren).
- Sauberer als DHCP-Multi: FB ist einziger Client-Resolver, .36 löst
  intern+public → public nie "zuerst" gefragt, kein NXDOMAIN-Leak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 14:25:53 +02:00
b20edd6b62 TP43 reopened: interne BF-Namen über WG am dw — Entscheidung DHCP-Multi [.36/.37/public]
Auslöser: portainer.bf.emsenhuber.net vom dw-Standort (WG-Tunnel up) nicht
auflösbar — dw-FritzBox kennt die interne Zone bf.emsenhuber.net nicht.

- Gitea #32 reopened (status:todo, thema:firewall-dns), Prosa aus dem Archiv
  zurück nach teilprojekte.md (Archiv = ♻️-Zeiger).
- fm-Einwand live entkräftet (dig @.36): bf-Namen → 10.40.0.0/16 (über WG
  erreichbar), fm-Namen → Cloudflare-Anycast, nie 10.101.x.
- Entscheidung: FritzBox verteilt per DHCP die DNS-Liste .36/.37/9.9.9.9;
  .37-Redundanz bleibt, FB entlastet. NXDOMAIN-Failover-Haken + zwei
  On-site-Verifikationen dokumentiert. Umsetzung = eigene On-site-Session.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 13:53:41 +02:00
a38ed0fe1d TP41 (✅) + TP43 (❌) + TP42 (✅) ins Archiv; TP41-Titel entschärft
- TP41 abgeschlossen: Gelis WARP via Android eingerichtet (letzter Blocker weg)
- TP43 verworfen: 420 = public CF-Worker, kein BF-Split-Horizon nötig; keine Altlasten
- TP42-Prosa nachgezogen (war closed in Gitea, Prosa stand noch in teilprojekte.md)
- Status-SSoT-Änderungen in Gitea gesetzt (#30 done, #32 dropped, #31 title-Fix)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 12:19:51 +02:00
5a29c482bd TP44 abgeschlossen: Prosa ins Archiv verschoben
Volltext TP44 (✅ DURCH) nach teilprojekte-archiv.md (Anker #tp44 + TOC-Zeile),
aus teilprojekte.md entfernt, Control-Plane-Themenzeile + gebrochenen intra-file
Link auf teilprojekte-archiv.md#tp44 gefixt. Gitea #33 war bereits closed/status:done.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 11:03:45 +02:00
4eba3673b7 TP44: Überholt-Zeiger auf falsche CF_API_TOKEN-Gotcha (Handoff 09-02)
Die Zeile "Repo-CF_API_TOKEN darf kein Workers-VPC" war falsch (live: liest
14/14). Handoff als Snapshot belassen, aber Korrektur-Hinweis ergänzt. Damit
ist die letzte Wiederholung der stale Gotcha markiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-11 10:58:18 +02:00
2b856d3d42 TP44 Teil B durch: Prosa auf ✅ + Handoff (Sync live, täglicher Job)
- teilprojekte.md: TP44-Status ✅ DURCH; Teil-B-Ergebnis (Live-Sync als
  täglicher Nautobot-Job, 4/14, 0 Drift); Drift-Korrektur der falschen
  "CF_API_TOKEN kann kein VPC"-Gotcha (live: liest 14/14).
- handoff-20260910: Root-Cause (Wurzel-__init__.py für walk_packages),
  register_jobs im __init__, has_sensitive_variables, VPC service_id-Fix,
  terpene-db service_id-Reconcile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 11:15:13 +02:00
f1d565bc88 TP44 Teil B: Meta.has_sensitive_variables=False — Job schedulebar machen
Nautobot verweigert das Scheduling von Jobs mit has_sensitive_variables
(Default True): "Job may have sensitive input variables". Der Job nimmt nur
ein Boolean (dryrun); das CF-Token stammt aus dem Nautobot-Secret, nicht aus
einer Job-Variable — daher unbedenklich abschaltbar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 11:12:56 +02:00
43c592e5d4 TP44 Teil B: CF-Sync-Job — VPC service_id-Feld + None-Match-Guard
Dry-Run-Befund: CloudService 'terpene-db' (VPC) wurde faelschlich als stale
markiert und fremde extra_config in 'App Launcher' gemischt. Ursache: VPC-
Directory-Services tragen ihren Identifier in "service_id", der Job las "id"
(=None). Ueber .get(mk)==None matchte der None-Wert das erste Objekt ohne den
Key. Fix: VPC nutzt v["service_id"]; _upsert ueberspringt mv=None generell.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 11:09:30 +02:00
33b18a08db TP44 Teil B: __init__.py in Repo-Wurzel — macht bf_infra für Nautobots Job-Loader sichtbar
Root-Cause des "No jobs were registered on loading the bf_infra.jobs submodule":
Nautobot 3.1.7 lädt Git-Repo-Jobs via import_modules_privately() ->
pkgutil.walk_packages([GIT_ROOT]). walk_packages entdeckt nur reguläre Pakete
(mit __init__.py), keine Namespace-Packages. Ohne Wurzel-__init__.py ist der
geklonte Ordner GIT_ROOT/bf_infra/ unsichtbar -> jobs/ wird nie importiert.
Live verifiziert: __init__.py da -> registry["jobs"] enthält CFEstateSync.
bf-infra ist das erste Git-Repo mit extras.job, daher nie zuvor aufgetreten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 11:06:28 +02:00
799b693ffa TP44 Teil B: register_jobs() ins Paket-__init__ (Git-Repo-Job registriert jetzt)
Nautobot importiert von einer Git-Datenquelle nur das Paket bf_infra.jobs und
erwartet register_jobs() im __init__ — der Call im Submodul blieb unsichtbar
(Sync-Log: "No jobs were registered on loading the bf_infra.jobs submodule").
register_jobs(CFEstateSync) daher ins __init__ verschoben, redundanten Call am
Ende von cf_estate_sync.py entfernt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 10:51:02 +02:00
4aeced30b5 CLAUDE.md: terpene-Zeile korrigiert — Terpenfinder = 420.teilzeitladen.xyz
terpene.* existiert nicht (0 DNS in allen Zonen, live 2026-09-10) und soll es
nicht; die öffentliche App ist der CF-Worker 420.teilzeitladen.xyz (blaueblüten).
Alte Zeile nannte terpene.teilzeitladen.xyz:8890 via Tunnel bf-mm — bf-mm ist
gelöscht. Einziger terpene-CF-Gegenstand: interner Tunnel terpene-db (f2d2fc8a).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-10 10:13:00 +02:00
89d94dbd45 TP44 Teil B: jobs/__init__.py — Job-Modul importieren, damit register_jobs greift
Nautobot laedt aus einer Git-Datenquelle nur das jobs-Paket; ohne __init__.py,
das cf_estate_sync importiert, wird kein Job registriert (Sync-Warnung
'No jobs were registered on loading the bf_infra.jobs submodule').

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 11:50:33 +02:00
6f60e03679 TP44 Teil B: CF-Estate-Sync als Nautobot-Job (ORM, aus Git-Datenquelle)
jobs/cf_estate_sync.py — kanonische Runtime des CF→Nautobot-Sync als
geplanter Nautobot-Job im vorhandenen nautobot-worker (kein neuer
Container, keine Nautobot-Exposure). Portierung der Reconcile-Logik aus
nautobot/tp44-cf-sync.py von REST auf ORM:
- ID-Matching (tunnel_id/app-id/script/service_id), extra_config-Merge
- Prefix-Assignments live aus teamnet/routes (subsumiert Seeder [7])
- Verwaisung = stale-Markierung statt Loeschen, Scope-sicher uebersprungen
- CF-Token aus Nautobot-Secret 'cf-api-token', dryrun-BooleanVar default True

Import im Worker verifiziert (IMPORT_OK), CF-Egress vom Worker bestaetigt.
Governance: periodische externe→Nautobot-Syncs = Jobs hier, kein per-Task-Container.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 11:47:55 +02:00
2f4866ca9a TP44 Teil B: CF-API→Nautobot-Sync (WIP, Dry-Run verifiziert)
nautobot/tp44-cf-sync.py — periodischer Live-Pull der CF-Estate nach
Nautobot (ersetzt den Inline-Snapshot des Seeders). Reuse: api() aus
caddy/cf-sync.py, Nautobot-Helper des Seeders.

- ID-Matching (tunnel_id/app-id/script/service_id) statt Name → rename-fest,
  keine Duplikate
- Merge statt Replace → kuratierte extra_config-Keys bleiben
- Verwaisung: extra_config.stale=true statt Hard-Delete; sicher
  uebersprungen, solange Token-Scope unvollstaendig
- 403-tolerant: deckt die 15 lesbaren Objekte driftfrei ab, zieht
  Hyperdrive/VPC automatisch mit, sobald Token-Scope da ist

Dry-Run: 11 Services unveraendert, 4 Networks Enrichment, 0 Duplikate.
Offen: Token-Scope (Hyperdrive+VPC) erweitern, dann Full-Sync + Cron-Host.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 20:43:35 +02:00
8e41268b4b TP44 Etappe 2 Teil A durch: IPAM-Prefixe live, Prosa nachgezogen
10.40.0.0/16 (container, Route bf-core-mesh) + 10.101.0.0/24 (network,
Route fm) in Nautobot IPAM angelegt; Seeder-Re-Run hat die zwei
cloud-network-prefix-assignments eingehängt (count=2, idempotent).
Gitea #33 kommentiert, bleibt WIP (Teil B CF-Sync offen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 19:50:58 +02:00
b915d02a82 TP44 Etappe 2 Teil A: Seeder für die zwei fehlenden IPAM-Prefixe
nautobot/tp44-ipam-prefixes.py — idempotenter get-or-create für
10.40.0.0/16 (container, Route bf-core-mesh) und 10.101.0.0/24
(network, Route fm.emsenhuber.net). Dry-Run default, --commit schreibt.
Nach dem Anlegen zieht tp44-cf-estate-seed.py Schritt [7] die zwei
cloud-network-prefix-assignments automatisch ein. Muster:
ingest-baseline.py / tp37-substrat-seed.py. Noch nicht gegen Nautobot
ausgeführt (nur Dry-Run verifiziert).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 19:48:26 +02:00
efb03979a0 TP34 verworfen: Prosa-Abschnitt ins Archiv verschoben
Caddyfile-via-GC-Ansatz zurückgezogen (Gitea #24 status:dropped, closed).
Caddyfile bleibt manuell in caddy/Caddyfile. Volltext-Abschnitt aus
teilprojekte.md ins Archiv gezogen (fortschreiben-nicht-überschreiben:
datierter Verworfen-Nachtrag oben, Konzepttext unverändert darunter),
plus TOC-Zeile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 16:31:22 +02:00
268fd859ab TP44: cf-tunnel-mapping §0 Live-Kopf + §10-16 als ARCHIV eingeklappt
Doku-Drift behoben: §10-15 beschrieben das 3-Tunnel-HA bf-mm/bf-nas/bf-pve,
das seit dem TP16.3-Cutover (2026-08-27) nicht mehr existiert und eine
Folgesession zu halluzinierten Tunneln/FQDNs verleitet hatte. Neuer §0 mit
dem live gegen die CF-API gemessenen Ist-Stand (bf-public/fm/terpene-db +
warp_connector bf-core-mesh, WARP-Routen); §10-16 in <details> ARCHIV
gekapselt (Inhalt unverändert), §17 (terpene-db, aktuell) bleibt sichtbar;
§14 Mesh-live-Notiz. Deckt sich mit dem Nautobot-Seed (TP44).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 15:50:31 +02:00
7a20a1db4f TP37 P2 vervollständigt: +6 live-verifizierte Smart-Home-ipam.Services
Fehlende exponierte Dienste ergänzt (RaspberryMatic 80/443/2001/2010,
iob-master 8081, z2m25 8080). Jeder Port per Socket-Probe belegt (nicht
aus Doku geraten); nc -z lieferte falsch-negativ und wurde verworfen.
iob-exposed/iob_slave bewusst ohne Service (kein Port gefunden).
Nautobot: 20 -> 26 ipam.Services, idempotent. Compliance 140/140.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 15:12:33 +02:00
bca8f6e27e TP34 zurückgezogen: Caddyfile via GC verworfen
Session lief auf veralteten Annahmen (Hostname terpene.* statt 420.*, zweiter
CF-Token erfunden) — entgegen dem User-Constraint "raten verboten". 420.teilzeitladen.xyz
ist ein Cloudflare-Worker (Projekt blaueblueten), nicht ein Caddy-Backend; :8890 gehoert
zu terpene.* via Tunnel bf-mm. Caddyfile war netto unveraendert, nur die beiden neuen
Skripte werden entfernt. Live LXC 130 ist bereits Baseline (e96fca5), Nautobot fuer TP34
unberuehrt (nur Dry-Run). Uebergabe: ~/.claude/plans/tp37-p2-seeden-dienste-silly-lerdorf.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 14:00:02 +02:00
d63dc7bb78 TP34: 420.teilzeitladen.xyz-Caddy-Block wieder entfernt
teilzeitladen.xyz liegt NICHT im emsenhuber.net-CF-Account (live geprueft: der
CF_DNS_API_TOKEN sieht nur die Zone emsenhuber.net, teilzeitladen.xyz count=0).
Damit kann Caddy auf LXC 130 kein DNS-01-Zert fuer den Namen holen -> Dauer-ACME-
Fehlerschleife. 420.teilzeitladen.xyz bleibt beim Cloudflare-Worker (cf-tunnel-mapping §17).

Ein Caddy-Backend fuer 420 braucht einen DNS-Token aus dem teilzeitladen.xyz-CF-Account
(blaueblueten-Projekt) — separat, nicht Teil von bf-infra. Seeder/Renderer bleiben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 13:36:33 +02:00
b200401c5a TP34: 420.teilzeitladen.xyz korrigiert (war terpene.*) + eigener DNS-Token
- caddy/Caddyfile: Hostname 420.teilzeitladen.xyz (nicht terpene.*); eigener
  per-site tls-Block mit CF_DNS_API_TOKEN_TEILZEITLADEN, damit der enge
  emsenhuber.net-ACME-Token unangetastet bleibt (Least-Privilege)
- nautobot/tp34-caddy-cf-seed.py: veraltete terpene.*-Referenz im Kommentar korrigiert

Deploy erst nach Hinterlegen des teilzeitladen.xyz-Tokens in /etc/caddy/caddy.env
(Zone:DNS:Edit nur teilzeitladen.xyz).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-08 13:30:30 +02:00
384f356290 TP34: terpene Quick-Win + Caddy-CF-Seeder + Renderer
- caddy/Caddyfile: terpene.teilzeitladen.xyz → 10.40.20.167:8890 (Quick-Win Schritt 0)
- nautobot/tp34-caddy-cf-seed.py: legt CustomFields caddy_fqdn/caddy_group auf
  ipam.Service an und setzt Werte fuer die 9 Routen mit vorhandenem Service-Objekt
- nautobot/tp34-caddy-render.py: rendert Caddyfile aus Nautobot, Diff gegen
  caddy/Caddyfile, optionaler Deploy via pct push + caddy reload

Deploy-Auflage fuer den terpene-Block:
  pct push 130 caddy/Caddyfile /etc/caddy/Caddyfile
  ssh root@10.40.20.40 "caddy reload --config /etc/caddy/Caddyfile"
(Plus CF-Tunnel-Route fuer terpene.teilzeitladen.xyz pruefen)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-08 11:48:18 +02:00
e96fca5a52 Merge branch 'main' of https://gitea.emsenhuber.net/admin/bf-infra 2026-09-07 17:20:38 +02:00
1625c30fd7 Merge tp37-dienste: TP37 P1+P2 durch
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-07 17:20:04 +02:00
83fd69ef8d TP37 P1+P2: VirtualMachines + ipam.Service seeden
P1 (tp37-substrat-seed.py): idempotenter Seeder fuer 3 ClusterTypes,
3 Clusters, 28 VirtualMachines mit eth0/IPAddress/primary_ip4.
Schon aus dem Worktree ausgefuehrt -- Skript damit in main nachgezogen.

P2 (tp37-dienste-seed.py): 20 ipam.Service-Eintraege angelegt:
Caddy :80/:443, Caddy-Backends (haos/vaultwarden/gitea/n8n),
Nautobot :8080, AdGuard :53 TCP+UDP (bf1+bf2), platform-pg :5432,
mariadb :3306, influxdb2 :8086, mqtt5 :1883, portainer :9443,
pve-mcp/shelly-mcp/n8n-mcp/gitea-mcp.
Compliance-Gegenprobe: 140/140 unveraendert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-07 17:19:59 +02:00
56746cb24d TP37 P1: Substrat-Seeder — Hosts/Container als native VMs in Nautobot
Idempotenter Seeder: 3 ClusterTypes (Proxmox VE/Synology Docker/Docker
Desktop), 3 Clusters (pve/nas-bf/macmini), 28 VirtualMachines mit
primary_ip4 (24 macvlan-IPs; macmini 4 host-geteilt). Native Modelle,
keine App (konsistent TP44). Live 2026-09-07, Compliance 140/140 / 0 Drift.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 14:02:35 +02:00
a0ba87d555 TP36 A4/A5/A6: Index/Status-SSoT-Cutover nach Gitea abgeschlossen
- teilprojekte.md: Quick-Index-Tabelle + "Ist-Stand (Kurz)"-Block entfernt (-493 Z.),
  Kopf zeigt aufs Gitea-Board (Labels status:*/thema:*); Governance/Genehmigte Ausnahmen
  unter eigenem Header behalten; TP36 reframed (Nautobot->Gitea, Scope = Index/Status,
  Nautobot nur noch Live-Geraetedaten). Alle 33 ### TPnn-Prosa-Abschnitte intakt.
- gitea-tp-sync.py: an das neue SSoT-Modell angepasst - aktive TPs sind SSoT direkt in
  Gitea, das Tool gleicht nur noch das Archiv ab und fasst offene Issues nie an. Dry-Run 0/0.
- CLAUDE.md: Pflichtlektuere #1 = Gitea-Board (Status) + Prosa-Datei (Detail); neue Sektion
  "SSoT & Branch-Konvention"; TP-Management-Sektion nachgezogen.

/projektstatus-Skill (beide globalen Kopien ~/.claude + ~/.config/opencode) auf die
Gitea-API umgestellt (Modus A Board / Modus B Markdown-Fallback) - liegt ausserhalb des Repos.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 13:30:24 +02:00
674e5fff0d TP36 (reframed): Gitea-TP-Sync — Index/Status als SSoT nach Gitea
- bin/gitea-tp-sync.py: idempotenter Sync teilprojekte.md-Quick-Index +
  Archiv-Header -> Gitea Issues (admin/bf-infra), Labels status:* + thema:*
- Erstlauf: 68 Issues (25 open / 43 closed) + 15 Labels angelegt
- Token aus ~/.hermes/.env (nie ausgegeben); Dry-Run default, --commit schreibt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-07 11:29:34 +02:00
c024f85579 TP44 nachgezogen + TP37/34/36-Plan (native Modelle, erst planen)
- Seeder tp36-cf-estate-seed.py -> tp44-cf-estate-seed.py (+ Referenzen, Docstring)
- teilprojekte.md: TP44 Quick-Index + Abschnitt (Anker), Ist-Stand 09-06,
  TP34/36/37 auf korrigierten Stand (TP37 P3 via TP44 erledigt; P1+2 offen)
- Plan-Runbook handoff-20260906-tp37-34-36-plan.md (native Modelle, Compliance-Gegenprobe)
- 09-02-Handoff + cf-tunnel-mapping: Referenzen/TODOs nachgezogen
- TP23-Quick-Index-Zeile (fremde, korrekte Aenderung) auf User-Okay mit uebernommen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-06 22:32:20 +02:00
9caf145341 TP23: Stufe-6-Runbook (DNS-Bypass-Sperre) mit hartem Vor-Ort-Gate
- docs/tp23-stufe6-bypass-sperre-runbook.md: separate Vor-Ort-Session; AGH-SPOF-Warnung
  (nicht aus der Ferne / nicht waehrend Abwesenheit), log-only-Vorstufe -> Drop mit Auto-Revert,
  Exempt/JIT-Bau, DoH-443-Grenze, Rollback + Abnahme
- teilprojekte.md: TP23-Zeiger auf den Runbook + Vor-Ort-Gate

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-06 17:20:11 +02:00
7edf01b021 TP23 Stufe 5: HA-Self-Service + Dashboard-Draft + Doku-Nachzug
- agh-exception.py: Creds aus Env/Datei (Mac ~/.secrets + HAOS /config), Domain/IP-Validierung
- HA-Self-Service dokumentiert: shell_command + Helper/Timer/2 Automations (adguard/ha-self-service.md)
- Eigenes Dashboard 'dns-ausnahmen' (1. Draft, sections) inkl. Repro-JSON
- teilprojekte.md: TP23 Quick-Index + dated Update + Ist-Stand-Block nachgezogen
  (Stufe 1-5 durch; offen nur Stufe 6 Bypass-Sperre -> separate Session)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-06 16:45:00 +02:00
f507c50623 TP23 Stufe 4: AGH CIDR-Gruppen+Policy auf .36/.37 + Sync/Exception-Tooling
- A0: API-User 'automation' auf agh-bf1/.36 + agh-bf2/.37 (PW in ~/.secrets, TP30-Merkposten)
- A: 8 clients.persistent (7 VLAN-CIDR-Gruppen + dns-bypass-exempt), Policy-Matrix
  (INFRA/MEDIA/MGMT filtering=aus, GUEST safe-search+parental an), live verifiziert
- B: agh-sync.py (check/push), Repo-SSoT AdGuardHome.yaml mit REDIGIERTEN Hashes
  (Alt-Hash-Exposure im Git entfernt); Invariante .36==.37 (AGH normalisiert beim Restart)
- C: agh-exception.py (allow-domain/unallow/unfilter/refilter/status) gegen beide
  Instanzen, end-to-end getestet; Contract in adguard/README.md
- Stufe 6 (Bypass-Sperre) NICHT geschaltet; kein DHCP-/Firewall-Write

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 21:19:50 +02:00
f8982df200 TP25: Transaktion-State committed + Messrunden 2026-09-04
TP25-kanalplan-ap1-live.json state open->committed (Nachzug aus dem
gc-transaktion commit). Dazu die zwei In-situ-Messrunden vom 09-04:
tp25-runde-1er (Walk iphone/s22) und tp25-runde-dauerping (Dauerping
ipad/iphone/macbook/s22) als Rohdaten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 19:43:28 +02:00
c23628f62f TP25: ap3-FT-Drift behoben + Kanalplan committed (140/140)
ap3 trug auf wifi1/wifi2 einen Werks-Inline security.ft=yes (Bring-up-Skript
tp28-ap3-phase2-cap.rsc unset !ft-over-ds, aber nicht !ft; Abnahme zaehlt nur
benannte security-Objekte -> Inline-Wert unsichtbar). Gemischtes FT-ESS =
Strong-Signal-Abbrueche (-43/-45 dBm) NUR auf ap3 bei 3/3 Strichen. Live per
!security.ft geradegezogen (uniform ft=no), Bring-up-Quelle korrigiert.

Kanalplan committed: Template auf DFS-Frequenzlisten (ch-5g-ap1=5260,5280,
ch-5g-ap2=5300,5320) + ap1-Provisioning-Zeilen (radio-mac ...E5/...E6) wieder
aufgenommen. Push nach bf-golden-config + GitRepo-Sync + refresh-compliance ->
140/140, 0 Drifts; Transaktion TP25-kanalplan-ap1-live committed.

Doku: Ist-Stand, Fund-E-Block, CLAUDE.md Punkt 5 (Merkregel: nach jeder
sec-main-FT-Aenderung jeden CAP einzeln auf security.ft pruefen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 19:39:13 +02:00
b75336c9db TP25: ft=no auf sec-main als Dauerzustand (User-Entscheid 2026-09-04)
Hebel 2 (ft=no) doch gezogen: sec-main von ft=yes ft-over-ds=yes auf
ft=no ft-over-ds=no. Template (nautobot/mikrotik_routeros.j2) + Push nach
bf-golden-config + Nautobot-Sync; wifi-security damit gruen (Live stand
schon auf ft=no, das Template war der Drift).

Doku nachgezogen (CLAUDE.md Punkt 5, teilprojekte.md Ist-Stand/Quick-Index/
Fund-E-Block): Soll ft=yes ft-over-ds=yes -> ft=no ft-over-ds=no, 802.11r aus.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-04 15:24:25 +02:00
70afb165b7 TP25: Klick-Konsole auf N Clients + Pin-UI
Die Konsole (docs/tp6-marker/server.py) war beim Multi-Pin-Umbau nicht
mitgezogen worden: hartkodiert auf 2 Clients, pinnte ueber die alte
Gegen-AP-Automatik. Jetzt:

- Client-Liste aus geraete.txt (schreibt tp25-walk-messung.sh), Fallback
  auf die zwei alten MACs fuer Alt-Laeufe.
- Kein eigenes SSH mehr: je Client letzte Zeile von sampler-<name>.csv
  (AP/Signal) + Ping-Verlust aus walk-ping-<name>.csv.
- N Client-Karten; Alarm, wenn ein gepinnter Client nirgends haengt.
- Pin-UI: je Client AP/Band waehlen, set/off/verify via tp25-pin-multi.sh
  (POST /pinmulti). Alte 2-Client-Automatik (entscheide/pin_setzen/auto)
  entfernt; tp25-pin-s22.sh liefert nur noch die map.
- tp25-runde.sh loest beim Aufraeumen den Multi-Pin statt des S22-Pins.

Doku: Ist-Stand-Block + Quick-Index + Messwerkzeug-Bullets nachgezogen,
neuer Handoff 2026-09-04.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-04 14:18:07 +02:00
efb0f44fa7 TP25: Multi-Pin-Tool tp25-pin-multi.sh (band-genaues Pinnen, N Clients je 1 AP)
Fuer die gepinnte Pro-AP-Abdeckungsmessung: pinnt mehrere Clients gleichzeitig
band-genau auf je einen AP (je Sonde alle cap-wifiN AUSSER dem Ziel per
access-list reject, eigener Tag TP25-PINM-<name>), iPhone bleibt frei. Loest
AP+Band -> cap-wifiN live aus der Karte (reuse tp25-pin-s22.sh map), cacht nie.
Modi set/verify/off/map. 3.2-safe (keine assoziativen Arrays, macOS /bin/bash).
access-list steht unter keiner ComplianceRule -> kein Nautobot-Drift; off raeumt
vollstaendig auf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 13:56:55 +02:00
ac3a125c82 TP25/TP28: Walk-Harness auf N Geräte, Analyzer generalisiert, AP-Map-Fix
- tp25-walk-messung.sh: halber Refactor geschlossen — Rumpf schleift ueber die
  PH_*-Arrays (pro Geraet ein Sampler + ein Core-Ping, sampler-<name>.csv /
  walk-ping-<name>.csv), PID-Arrays im Cleanup, Archiv-/Echo-Block generisch.
  Lief vorher unter set -u gar nicht (unbound $PHONE_MAC).
- tp25-gehweg-auswertung.py: liest N benannte Geraete per glob; altes 2-Rollen-
  Schema (sampler.csv/walk-ping.csv/walk-ping-iphone.csv/beide-telefone.csv) bleibt
  als Legacy-Fallback erhalten. Beide Pfade getestet.
- tp25-pin-s22.sh: karte() repariert — channel.frequency ist seit dem DFS-Kanalplan
  (2026-09-03, Frequenz-Listen) ein Array; der alte Skalar-Vergleich blankte map,
  wodurch ap-map.txt leer blieb. Fix nimmt bei :typeof=array das erste Element.

Live-Smoke (4 Geraete) gruen: alle erreichbar, sauberes Cleanup, korrekte AP-Map.
Naechster Schritt: In-situ-Walk (nur Zahlen, Commit/Rollback des Kanalplans separat).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 12:42:30 +02:00
45e4540cf5 Handoff 2026-09-03: TP25/TP28 Kanalplan live, In-situ-Messung in naechster Session
Uebergabeprompt fuer die Messsession: Aufstellorte begehen, entscheiden
ob Zielzustand (Template + Commit) oder Nachjustieren. Enthaelt Messplan,
Rollback- und Commit-Weg, sowie die relevanten CLAUDE.md-Gotchas
(scan/registration-table nur am Manager, cap-wifiN wandert, DFS-CAC).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-03 21:38:44 +02:00
e8f58b0e5e TP25/TP28 Kanalplan live: ap1 am Sideboard, ap2+ap1 auf DFS Band B
Sideboard-Test fuer ap1 (TP28) plus Umsetzung des TP25-Kanalplans
in einem Zug am Manager (crs326-core):

L2 (TEST-ether3-trunk-ap1-sideboard-2, bridge-vlan, committed):
- ether3 zum AP-Trunk fuer ap1 hinzugefuegt (analog ether15/ether21)
- Template mikrotik_routeros.j2 nachgezogen: ether3 in allen VLAN-Zeilen

WLAN (TP25-kanalplan-ap1-live, wifi-channel, OFFEN bis 2026-09-10):
- ch-5g-ap1: 5180 -> Frequenz-Liste 5260,5280 (DFS Band B, ch52/56)
- ch-5g-ap2: 5220 -> Frequenz-Liste 5300,5320 (DFS Band B, ch60/64)
- Neue Provisioning-Regeln fuer ap1 (radio-mac E5=5G, E6=2G), analog ap2/ap3
- remote-cap provision fuer ap1 und ap2

Live-Ergebnis (35 Clients an der Registration-Table, vorher 30):
- ap1: 5260/5280 + 2412 (ch1), 9/9 Interfaces up
- ap2: 5300/5320 + 2462 (ch11), 9/9 up
- ap3: 5180 + 2437 (ch6), unveraendert
- Keine 5-GHz-Kollisionen mehr, 2,4-GHz sauber auf ch1/6/11

Follow-up in naechster Session: In-situ-Messungen an den Aufstellorten;
bei ok Template auf Frequenz-Listen + ap1-Provisioning-Regeln erweitern
und die offene Akte committen. Snapshot fuer Rollback liegt bereit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-03 18:53:01 +02:00
05a3fd957f TP25 Fund E geschlossen: 7.24.1 war die Ursache, nicht ft-over-ds
Abschlussmessung 2026-09-02: reauthenticating 218->40->4 (09-02 nur 4 in
8,6 h, alle iPhone F2:62, 0 Ausfaelle). Vorbedingung geprueft (Core-Uptime
1d18h, caps joined=0 -> keine Reboot-Artefakte). Hebel 1 widerlegt+
zurueckgebaut, Hebel 2-4 entfallen, kein Geraete-Write (Compliance 140/140).
Offen bleibt nur ap2-Unterperformance.

- neu: docs/handoff-20260902-tp25-fund-e-messung.md
- teilprojekte.md: Quick-Index + Ist-Stand + TP25-Abschnitt + Hebel-Tabelle
- CLAUDE.md: Pflichtlektuere Punkt 5 auf geschlossen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 08:44:32 +02:00
bf6d3605b7 TP42 durch: interner Namensraum auf bf.emsenhuber.net vereinheitlicht
(A) DHCP-Search-Domain der 7 Netze emsenhuber.net -> bf.emsenhuber.net ueber
die GC-Pipeline (kein Direkt-Write): Template Z.133 gehoben, per
push-gc-template.py ins bf-golden-config-Repo (7a4068c4), GitRepo-Sync,
neuer manueller Job tp42-dhcp-domain in gc-configplan.py (set [find], weil
add das existierende Netz doppeln wuerde), Deploy an crs326-core.
Live 7/7 = bf.emsenhuber.net, Compliance 140/140 keine Drifts.
Nebenbefund: Remote-GC-Template hing dem lokalen hinterher (noch *.bf.lan +
router.lan) -> mit an den Live-Stand angeglichen.

Loest den Kernkonflikt: DHCP verteilte bare emsenhuber.net, Records leben
unter bf.emsenhuber.net -> bare macmini loest jetzt beim Lease-Renew.

(B) .16 (adguard_bf1) abgebaut: lag im mit FM geteilten Portainer-Stack 195
zusammen mit adguard_fm2 (.17, Standort FM). Statt Stack-Delete die compose
auf nur .17 getrimmt + redeployt (Prune). .16 weg, .17 laeuft (kurzer Blip).

Nautobot-Soll (Scope 4) an TP37 gekoppelt, separat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 03:31:51 +02:00
8aae0f424f TP42: Live-Bestandsaufnahme + Zielschema-Entscheidung (bf.emsenhuber.net)
Gegen die Geraete gemessen: .bf.lan ist ueberall weg, DHCP-domain auf
emsenhuber.net vereinheitlicht, Core-Static + Caddyfile konsistent auf
.bf.emsenhuber.net (deckt sich mit GC-Template). Drift hat ~80% erledigt.

Kernkonflikt: DHCP verteilt bare emsenhuber.net, Records leben unter
bf.emsenhuber.net -> bare macmini loest nicht. Entscheidung (User):
Zielschema = bf.emsenhuber.net (wenig-Arbeit-Weg); .16 (adguard_bf1)
abbauen, .17 (=FM) bleibt.

Netto-Rest = 2 Infra-Eingriffe: DHCP-domain ->bf.emsenhuber.net ueber die
GC-Pipeline (Template Z.133 + push-gc-template.py + Deploy) und .16-Teardown.
Kein Core-Objekt haengt an .16 (Firewall/NAT/DNS/Addr-List live geprueft).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 03:19:25 +02:00
72db50fce2 TP31 abgeschlossen: Schritt 5+6 via TP16.3 (09-01), cf-sync.py-Fehlalarm gefixt
Kern von TP31 (Caddy als Host->Origin-SoT, cloudflared 6->1 Knoten) lief
über den Piloten TP16.3 durch: bf-public 12 conns, vier öffentliche Namen
über Caddy (https://10.40.20.40:443), Alttunnel bf-nas/bf-pve/bf-mm weg.

cf-sync.py:107 akzeptierte nur http://<caddy>; der Flip legte die Namen auf
https://...:443 -> Abnahme-Tool meldete vier Fehlalarme. Fix: auch https://
als "zeigt auf Caddy". Drift-Check jetzt grün (nur ds-bf als bewusst intern).

Schritt-6-Teil "MCP-Clients auf FQDN" durch TP35 Schicht 1 umgekehrt (LAN-IP),
damit gegenstandslos. Quick-Index/TP-Abschnitt/Ist-Stand-Block nachgezogen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 03:07:15 +02:00
cce88bdcba TP14.4 als in TP41 T4 aufgegangen markiert (zt-svc-Konsolidierung)
Kein eigenständiger claude-mcp-Token mehr: in TP41 T4 (2026-09-01) zu
zt-svc umbenannt+rotiert, mcp/cloudflare/.env trägt jetzt
CF_ACCESS_CLIENT_ID/_SECRET. Quick-Index (🔜→✅), TP-Abschnitt und
Ist-Stand-Block nachgezogen; alte ".env leer"-Notiz als überholt erhalten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-02 03:01:48 +02:00
133 changed files with 22348 additions and 1234 deletions

4
.gitignore vendored
View File

@@ -1,10 +1,6 @@
.DS_Store
.secrets
# Per-Projekt-MCP-Configs: können Tokens/URLs enthalten, projekt-spezifisch, nicht ins Repo
.mcp.json
# Python bytecode
__pycache__/
*.pyc

67
.mcp.json Normal file
View File

@@ -0,0 +1,67 @@
{
"mcpServers": {
"home-assistant": {
"type": "http",
"url": "${MCP_HOME_ASSISTANT_URL}"
},
"mikromcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mikromcp",
"serve"
],
"env": {
"MIKROMCP_CONFIG_PATH": "/Users/christophemsenhuber/dev/bf-infra/mcp/mikromcp/config/routers.yaml",
"MIKROMCP_DEFAULT_ROUTER": "ap1",
"ROUTER_AP1_USER": "admin",
"ROUTER_AP1_PASS": "${MCP_MIKROMCP_ROUTER_AP1_PASS}",
"ROUTER_AP2_USER": "admin",
"ROUTER_AP2_PASS": "${MCP_MIKROMCP_ROUTER_AP2_PASS}",
"CRS326_CORE_USER": "admin",
"CRS326_CORE_PASS": "${MCP_MIKROMCP_CRS326_CORE_PASS}",
"CRS326_BRANCH_USER": "admin",
"CRS326_BRANCH_PASS": "${MCP_MIKROMCP_CRS326_BRANCH_PASS}",
"ROUTER_AP3_USER": "admin",
"ROUTER_AP3_PASS": "${MCP_MIKROMCP_ROUTER_AP3_PASS}"
}
},
"hostinger-api": {
"alwaysLoad": true,
"type": "stdio",
"command": "hostinger-api-mcp",
"args": [],
"env": {
"HOSTINGER_API_TOKEN": "${MCP_HOSTINGER_API_TOKEN}"
}
},
"cloudflare": {
"alwaysLoad": true,
"type": "http",
"url": "https://mcp.cloudflare.com/mcp"
},
"ollama": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"ollama-mcp"
],
"env": {
"OLLAMA_HOST": "http://127.0.0.1:11434"
}
},
"pve-mcp": {
"type": "http",
"url": "http://10.40.20.173:3000/"
},
"n8n-mcp": {
"type": "http",
"url": "http://10.40.20.167:3001/mcp",
"headers": {
"Authorization": "Bearer ${N8N_MCP_BEARER}"
}
}
}
}

103
CLAUDE.md
View File

@@ -6,33 +6,70 @@ DNS/DHCP-Ablösung, WLAN via **CAPsMAN auf dem Core** (TP28, 2026-08-17 — der
## Pflichtlektüre pro Sitzung (Reihenfolge)
1. **`docs/teilprojekte.md`** (Quick-Index-Block) — kanonischer Stand, Scope, Abhängigkeiten, **offene** TPs. **1 Read reicht.**
0. 🔴 **TP45 = aktuell dringendster Posten (2026-09-21, Gitea #71):** interne `*.bf.emsenhuber.net`
lösen im Browser **nicht** auf (AGH wertet Rewrites im **Filter-Pfad** aus → für unfiltrierte
Clients übersprungen → Fallback auf den Core, der nur 10 von 26 Namen hält), und `ds-bf` ist
**öffentlich kaputt** (einziger Ingress-Eintrag, der Caddy umgeht → TP5-Drop). Reihenfolge:
VLAN20 ins TP32-Schema → VLAN30-Pool-Grenze → DNS/FQDN. Ausführlich: `### TP45`.
**`### TP46`** = CF-/Tunnel-SSoT + Recovery (eigene Baustelle).
1. **Status/Index = Gitea-Board** (seit TP36-Cutover 2026-09-07): [`admin/bf-infra` · Issues](https://gitea.emsenhuber.net/admin/bf-infra/issues) — TP = Issue, Status = Label `status:*`, Gruppierung = `thema:*`. Für den **Detail/Kontext** eines TP dann den `### TPnn`-Prosa-Abschnitt in **`docs/teilprojekte.md`** (aktiv) bzw. **`docs/teilprojekte-archiv.md`** lesen. *(Die frühere „Quick-Index-Block, 1 Read reicht"-Zeile ist überholt — Index/Status stehen nicht mehr in der Datei.)*
2. **`docs/handoff-*.md`** (neueste) — wo die letzte Session aufgehört hat.
3. Bei Live-Writes oder Inventur: **`docs/cf-tunnel-mapping.md`**, **`docs/teilprojekte-archiv.md`**.
4. ✅ **TP16.3 §5 durch (2026-09-01):** [`docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md`](docs/handoff-20260901-tp16.3-paragraph5-flip-durch.md)
— alle vier oeffentlichen Namen laufen ueber `bf-public`/Caddy; Alttunnel bleiben als Rueckfallebene
(§6 offen). Enthaelt den 10-Sekunden-DNS-Fund und drei Messfallen.
5. 🔴 **WLAN/Fund E — HEBEL 1 WIDERLEGT UND ZURUECKGEBAUT, Messung laeuft:**
[`docs/handoff-20260901-fund-e-hebel1-zurueckgebaut.md`](docs/handoff-20260901-fund-e-hebel1-zurueckgebaut.md)
— `ft-over-ds=no` lief 6,4 h **allein** und brachte 124 `reauthenticating` + zwei erlebte
Ausfaelle; der Einbruch auf 0/h faellt exakt auf das **TP27-Upgrade (7.24.1)** um 14:36.
Hebel 1 ist am **2026-09-01** zurueckgebaut (`ft-over-ds=yes`), Transaktion **geschlossen**,
**Compliance 140/140**. ⏳ **Offene Aufgabe: eine Messung am 2026-09-02 frueh** — bleibt es
ruhig, war 7.24.1 die Ursache. Vorstufen:
5. ✅ **WLAN/Fund E — GESCHLOSSEN 2026-09-02: 7.24.1 war die Ursache, nicht `ft-over-ds`:**
[`docs/handoff-20260902-tp25-fund-e-messung.md`](docs/handoff-20260902-tp25-fund-e-messung.md)
— die Abschlussmessung ergab am 09-02 nur **4 `reauthenticating` in 8,6 h** (alle iPhone `F2:62`,
isolierte Einzel, 0 Ausfaelle), Verlauf **218 → 40 → 4**; Vorbedingung geprueft (Core-Uptime 1d18h,
`caps joined=0`). Hebel 1 (`ft-over-ds=no`) war widerlegt (6,4 h allein → 124× + 2 Ausfaelle) und ist
am 09-01 zurueckgebaut; Hebel 2–4 entfallen, **kein Geraete-Write** (Soll stand: `ft=yes ft-over-ds=yes`,
**Compliance 140/140**). **Am 2026-09-04 hat Christoph `ft=no` auf `sec-main` als Dauerzustand
entschieden** (Hebel 2 doch gezogen: Template + bf-golden-config + Nautobot-Sync, `wifi-security` gruen).
⚠️ **Rueckgenommen am 2026-09-14 (Terrasse-In-situ-Session): `ft=yes ft-over-ds=yes` zurueck** — mit
`ft=no` war jeder Roam eine Voll-Reassoziation, darin starben 2 Anrufe; Rueckkehrstand = Fund-E-Known-Good
von 09-02 (ruhig auf 7.24.1). Weg: Template + `push-gc-template.py` + `gc-configplan.py
--refresh-compliance` + `gc-manual-plan.py --deploy` (Plan `b1135f3e`, Completed) → **140/140, 0 Drifts**;
CAP-Abnahme: **keine** Inline-Overrides auf ap1/ap2/ap3. Commands:
`docs/transaktionen/TP25-ft-yes-secmain.commands.rsc`, s. Handoff 2026-09-14.
🔴 **Nachtrag 09-04: `ft=no` war NICHT uniform.** ap3 trug einen Werks-Inline `security.ft=yes` auf
`wifi1/wifi2` (Bring-up unset `!ft-over-ds`, aber nicht `!ft`; Abnahme zählt nur benannte
security-Objekte → Inline-Wert unsichtbar). Gemischtes FT-ESS → Strong-Signal-Abbrüche (−43/−45 dBm)
**nur auf ap3** bei 3/3 Strichen. Fix: `!security.ft` auf ap3 (uniform `ft=no`), Quelle
`tp28-ap3-phase2-cap.rsc` korrigiert. **Merkregel: nach jeder `sec-main`-FT-Änderung jeden CAP einzeln
`get wifiN security.ft` prüfen — CAP-lokale Inline-Overrides sind compliance-unsichtbar.**
Der TP25-Kanalplan ist am 09-04 committed (DFS-Frequenzlisten + ap1-Provisioning, **140/140, 0 Drifts**).
Offen in TP25 bleibt nur **ap2 unterperformt** (2 m/−80 dBm). Vorstufen:
[Befund](docs/handoff-20260831-tp27-upgrade-und-hebel1-befund.md) ·
[Eingriff](docs/handoff-20260831-fund-e-hebel1-gezogen.md).
[Eingriff](docs/handoff-20260831-fund-e-hebel1-gezogen.md) ·
[Rueckbau](docs/handoff-20260901-fund-e-hebel1-zurueckgebaut.md).
6. ap3-Bring-up 2026-08-30: [`docs/handoff-20260830-ap3.md`](docs/handoff-20260830-ap3.md) — sechs Funde zu Werks-MikroTiks, CAPsMAN und Golden-Config-Lücken.
7. Inventur-Befund 2026-08-27: [`docs/handoff-20260827-inventur-und-architektur.md`](docs/handoff-20260827-inventur-und-architektur.md) — Master-Struktur, Asymmetrie, Drift.
## SSoT & Branch-Konvention (TP36-Cutover 2026-09-07)
- **SSoT-Dreiteilung:** **Index/Status = Gitea-Issues** (`admin/bf-infra`, Labels `status:*`/`thema:*`) ·
**Prosa/Detail = Repo** (`docs/teilprojekte.md` aktiv + `teilprojekte-archiv.md`, `### TPnn`-Abschnitte) ·
**Live-Gerätedaten = Nautobot** (Compliance-Zahl, RouterOS-Version …). Ein Status ändert sich **in Gitea**,
nicht mehr in einer Repo-Datei. Sync-/Abgleich-Werkzeug fürs Archiv: `bin/gitea-tp-sync.py` (Dry-Run default,
Token aus `~/.hermes/.env`, **nie ausgeben**).
- **Branch-Konvention:** Branch `tpNN-kurz` **jederzeit** mitten in der Session möglich (`git switch -c`,
uncommittete Arbeit wandert mit); für Multi-Session-TPs der Normalfall. **Merge nach `main`, sobald der
Code/Config des TP steht.** Weil Steuerungs-Updates nach **Gitea** gehen (nicht in `teilprojekte.md`),
kollidieren TP-Branches nicht mehr auf der Steuerungs-Doku — nur noch der eigene `### TPnn`-Prosa-Abschnitt
wird angefasst.
- **TP anlegen/schließen:** neues aktives TP = **direkt als Gitea-Issue** (Labels setzen), Prosa-Abschnitt
im Repo dazu; abschließen = Issue `closed`, Prosa wandert bei Bedarf ins Archiv. **Keine Handtabelle mehr.**
## Was du sofort wissen musst (Inventur 2026-08-27)
- **`bf-infra`** ist aktiver Master **mit Gitea-Remote**: `origin` = `https://gitea.emsenhuber.net/admin/bf-infra.git` (live verifiziert 2026-08-30). ⚠️ **Die frühere Zeile „lokal, kein Gitea-Remote → verloren bei Festplattencrash" ist überholt** — sie stammt aus der Inventur vom 2026-08-27 und war damals richtig; das Remote existiert seit spätestens 2026-08-28 (`origin/main` = `b917691`). **Die Backup-Lücke ist damit keine Struktur-, sondern eine Disziplinfrage: `git push`.** Am 2026-08-30 lagen vier Commits nur lokal. 🔴 **Das Remote ist nur so viel wert wie der letzte Push** — der Backup-Guard (`~/dev/.bin/backup-guard.sh`, TP35 Schicht 5) bricht Commits ab, solange kein Backup markiert ist; **das ist die Erinnerung ans Pushen, kein Hindernis.** Nicht mit `--no-verify` umgehen. 🔴 **Merkregel:** diese Zeile hat eine Session dazu gebracht, „kein Remote" zu behaupten, statt `git remote -v` zu tippen — vor jeder Aussage über Remotes/Backups **live prüfen**.
- **`admin/bf-network-r6`** (Gitea) ist Archiv, letzte aktive Commits 2026-08-25 → read-only-Header.
- **`admin/bf-golden-config`** (Gitea) ist Bot-Master (Nautobot 2×/Tag), nicht manuell.
- **`admin/bf-golden-config`** (Gitea) ist Bot-Master, nicht manuell. 🔴 **Korrigiert 2026-09-12:** die frühere Angabe „2×/Tag" war nie real — es gab **keinen** Scheduler, Backup/Intended/Compliance liefen nur manuell aus Sessions (zuletzt 09-04, 8 Tage Stillstand). Jetzt **täglich 03:30 UTC** per ScheduledJob **„GC Backup+Compliance – taeglich"** (Nautobot-Job *Execute All Golden Configuration Jobs - Multiple Device*, Scope `platform=RouterOS`, Reihenfolge Backup→Intended→Compliance). Stand prüfen: `backup_last_success_date` am Gerät bzw. `scheduled-jobs` in Nautobot.
- **`admin/blaueblueten-n8n`** (Gitea) ist Master für terpene-Repo.
- **`inventory/` ist tot** (Pipeline seit 2025-06 stale). Live-Daten aus MikroMCP/CF/Portainer.
- **`mcp/INVENTORY.md`** ist BF-Netz-SSoT; `~/.claude.json`/`opencode.jsonc` sind globalere Werkzeugkästen.
- **terpene.teilzeitladen.xyz**: Worker läuft auf Mac mini (`10.40.20.167:8890`), **kein Caddy-Block, kein CF-Tunnel** — Backfill via DB-Migration blockiert (Handoff 2026-08-27).
- **Terpenfinder = `420.teilzeitladen.xyz`** (CF-Worker, Repo `admin/blaueblueten-n8n`, hinter CF Access), **kein Caddy, kein Mac mini im Pfad**. `terpene.*` **existiert nicht und soll es nicht** (live geprüft 2026-09-10). Einziger terpene-benannter CF-Gegenstand: der **interne** Tunnel `terpene-db` (`f2d2fc8a`, ohne öffentlichen Hostname, Hyperdrive→VPC→Postgres, s. `docs/cf-tunnel-mapping.md` §17). ⚠️ **Grenze:** blaueblüten ist ein eigenes Projekt — nicht anfassen. *(Die frühere „terpene.teilzeitladen.xyz:8890 via Tunnel"-Zeile war veraltet — bf-mm ist gelöscht.)*
- **shelly-mcp / portainer-mcp bewusst NICHT als MCP-Client** (User-Direktive 2026-08-28): shelly-mcp-Container auf DS923 wird via **Portainer-API** (Skript-Aufrufe, `mcp/portainer/.env` als Token-Quelle) deployt, nicht via MCP-Protokoll. Inventar-Eintrag spiegelt das. `mcp-host-policy.md` ist SSoT für die Host-/IP-Konvention.
- **Mac mini `10.40.20.167`** ist der **n8n-Host** (n8n `:5678`, n8n-redis `:6379`, n8n-mcp `:3001`) — **NICHT** der zentrale MCP-Host. Performance-Überlegung: MCP-Clients würden auf dem macmini (User-Workstation) laufen und die Box zusätzlich belasten; deshalb liegt der MCP-Host auf der **DS923** (`nas-bf`, Portainer Endpoint 14). gitea-mcp läuft aktuell noch auf dem macmini (historisch, eigene Container-Definition dort) — gehört **bei Gelegenheit** auf die DS923 umgezogen (separater Punkt, **nicht** Teil dieser Session). Container-Definitionen für n8n leben auf dem macmini (Docker Desktop); FQDN→Backend-Mapping im `caddy/Caddyfile`.
@@ -40,12 +77,15 @@ DNS/DHCP-Ablösung, WLAN via **CAPsMAN auf dem Core** (TP28, 2026-08-17 — der
Wenn während einer Session ein neues Teilprojekt, eine Abhängigkeit oder ein Querschnittsthema sichtbar wird, das bisher in keinem TP abgebildet ist:
- Vorschlagen und mit dir abstimmen (nicht eigenmächtig anlegen).
- Auf dein Okay hin anlegen: Quick-Index-Zeile + `### TP<n>`-Abschnitt mit Status `🔜`, Scope,
Abhängigkeiten, Abgrenzung. Nächste freie Nummer vergeben (höchste vergebene + 1; Lücken aus
verworfenen TPs bleiben frei).
- Ist-Stand-Block mitziehen (Datum, betroffene Zeilen).
- Auf dein Okay hin anlegen: **Gitea-Issue** `TPnn — <Kurztitel>` mit Labels `status:🔜`(todo) +
passendem `thema:*` + Body (Anriss + Verweis auf den Prosa-Abschnitt) **und** einen
`### TP<n>`-Prosa-Abschnitt in `docs/teilprojekte.md` (Scope, Abhängigkeiten, Abgrenzung).
Nächste freie Nummer vergeben (höchste vergebene + 1; Lücken aus verworfenen TPs bleiben frei).
- **Status/Reihenfolge/„was lief zuletzt" gehen ins Gitea-Issue** (Label ändern, Kommentar), **nicht**
in eine Quick-Index-Tabelle oder einen Ist-Stand-Block — die gibt es seit dem TP36-Cutover (2026-09-07)
nicht mehr in der Datei.
**Abgeschlossene TPs** stehen seit 2026-08-23 in `docs/teilprojekte-archiv.md` (Volltext, unverändert, mit Inhaltsverzeichnis). **Ein TP wandert erst ins Archiv, wenn nichts mehr daran zu tun ist — und wieder zurück, sobald doch etwas dazukommt.** Ein archiviertes TP ist ein *geschlossenes Ticket, kein versiegeltes*: bei neuer Arbeit an derselben Baustelle wandert der **Volltext zurück** nach `teilprojekte.md` (Zeiger bleibt im Archiv), **kein** Zwillings-TP mit neuer Nummer (Christoph-Direktive 2026-08-30, erster Fall TP28/`ap3`) — und der **Ist-Stand-Block wird bei jeder Änderung mitgezogen**, nicht nur der betroffene TP-Abschnitt.
**Abgeschlossene TPs** stehen seit 2026-08-23 in `docs/teilprojekte-archiv.md` (Volltext, unverändert, mit Inhaltsverzeichnis) und ihr Gitea-Issue ist `closed` (Label `status:✅`/`❌`). **Ein TP wandert erst ins Archiv, wenn nichts mehr daran zu tun ist — und wieder zurück, sobald doch etwas dazukommt** (Issue dann `reopen`). Ein archiviertes TP ist ein *geschlossenes Ticket, kein versiegeltes*: bei neuer Arbeit an derselben Baustelle wandert der **Volltext zurück** nach `teilprojekte.md` (Zeiger bleibt im Archiv), **kein** Zwillings-TP mit neuer Nummer (Christoph-Direktive 2026-08-30, erster Fall TP28/`ap3`) — nur noch der betroffene `### TPnn`-Prosa-Abschnitt wird angefasst.
---
@@ -70,15 +110,15 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
|---|---|---|
| ~~ALLNET Core-Switch (sw1)~~ | — | ❌ **außer Betrieb (2026-08-08)** — durch `crs326-core` (L3-Router + Core-Switch, Technik UG) ersetzt; physisch abgelöst. (Telnet-Runner `switch/` = nur noch historisch.) |
| ~~Omada Access-Switch (sw2)~~ | — | ❌ **abgebaut 2026-07-23** (TP15 Branch-Tausch) — durch `crs326-branch` in Technik OG ersetzt, physisch entfernt |
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99) · Bootstrap Rev4 2026-08-08 | RouterOS **7.24.1** · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `crs326-branch` ✅ **live** (2026-08-16 verifiziert) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap2) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
| **crs326-branch** (CRS326, Technik OG) | **10.40.99.2** (VLAN99) · Bootstrap Rev4 2026-08-08 | RouterOS **7.24.1** · `admin`/`~/.secrets` (`CRS326_BRANCH_*`) · REST `http://10.40.99.2/rest` · MikroMCP `crs326-branch` ✅ **live** (2026-08-16 verifiziert) · **TP15 ✅: ersetzt sw2** (L2-Switch), volle Portbelegung (ether1 Uplink-Trunk, 2/8 NAS, 3 Drucker, 4 Dock, 5/6 Sonos, 7 macmini, 24 ap3) · sw-id RGZJ-UK0T, MAC 04:F4:1C:B4:15:58 |
| **crs326-core** (CRS326, Technik UG) | **10.40.99.1** (VLAN99-SVI = L3-GW; same-subnet-Fallback `10.40.10.1`) · Identity `crs326-core` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`CRS326_CORE_*`) · MikroMCP routerId `crs326-core` ✅ **live** (2026-08-16 verifiziert) · **TP15/TP21.1 ✅ 2026-08-08: PRODUKTIVER L3-Router** (ersetzt ap1) — Routing/DHCP (7 Server + 54 Leases)/DNS (**DoH zum CF-Gateway mit `verify-doh-cert=yes`**, TP23 Stufe 1 ✅ 2026-08-18; `servers=1.1.1.1` nur noch Bootstrap) · **NTP-Server für den Standort**/NAT/WG-Hub (fm+dw live); WAN `vlan100`=Liwest `90.146.33.177` · sw-id 4W04-URHT, MAC 04:F4:1C:B4:17:76 |
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` ✅ live · **TP28 ✅ 2026-08-17: reiner CAP** (Manager = `crs326-core`) · 🔴 **FUNKSTILL seit 2026-08-30**: keine Provisioning-Regel am Manager, weil ap3 daneben steht und denselben Kanal 5180 fährt. Gerät bleibt erreichbar. Beim Umzug ans Sideboard → `5260/Ce` (Band B, DFS) und Uplink auf `core ether3` — Uplink `ether1` (PoE-Port, `poe-out=off`) an crs326-core `ether15`; SSIDs/Kanäle kommen vom Manager, ch36/ch1 · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP28 ✅ 2026-08-17: reiner CAP** — Uplink `ether1` (PoE) an crs326-branch `ether24`; ch44/ch11 (TP25: ch149 war unter ETSI leistungsbegrenzt) · MAC D0:EA:11:4D:40:3A · Config `routeros/.secrets/ap2-prov-base.rsc` |
| **cAP ax (ap3)** | **10.40.99.13** (VLAN99) · Identity `ap3` | ✅ **LIVE seit 2026-08-30** (TP28-Nachtrag) · `cAPGi-5HaxD2HaxD`, RouterOS **7.24.1** + RouterBOOT 7.24.1 (**seit 2026-08-31 ist die ganze Flotte auf 7.24.1**, TP27-Angleichung erledigt) · reiner CAP, Manager `crs326-core` · Uplink `ether1` → **core `ether21`** (Trunk) · Kanäle **`5180/ax/Ce/I`** (5 GHz) + **`2437/ax`** (ch6) nach TP25-Plan · 🔴 **nur 2 Ethernet-Ports** (`ether1` PoE-in, `ether2` PoE-out, **kein** Bridge-Port) → `ap.extra_ports=[]` · `device-mode=basic` (scheduler/fetch/romon **erlaubt**, anders als ap1/ap2) · Dateien `routeros/tp28-ap3-phase{1,2}-*.rsc` + `-service-accounts.rsc` + `-werksreste.rsc` |
| hAP ax² #1 (ap1) | **10.40.99.11** (VLAN99) · Identity `ap1` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`ROUTER_AP1_*`) · REST `http://10.40.99.11/rest` · MikroMCP `ap1` ✅ live · **TP28 ✅ 2026-08-17: reiner CAP** (Manager = `crs326-core`) · ✅ **aktiv am Sideboard** (Wohnzimmer; Uplink `ether1` → core `ether3`, PoE-Port `poe-out=off`) — Kanäle `5260/Ce` (Band B, DFS, Fallback 5280) + `2412`/ch1, vom Manager · MAC D0:EA:11:4D:40:E0 · Config-Referenz `routeros/.secrets/ap1-prov-base.rsc` |
| hAP ax² #2 (ap2) | **10.40.99.12** (VLAN99) · Identity `ap2` | RouterOS **7.24.1** · `admin`/`~/.secrets` (`ROUTER_AP2_*`) · REST `http://10.40.99.12/rest` · MikroMCP `ap2` · **TP28 ✅ 2026-08-17: reiner CAP** — **Technik UG**, Uplink `ether1` (PoE) an core `ether21`; Kanäle `5300/Ce` (Band B, DFS, Fallback 5320) + `2462`/ch11 · MAC D0:EA:11:4D:40:39 (ether1; Bridge/Mgmt `:3A`) · Config `routeros/.secrets/ap2-prov-base.rsc` |
| **cAP ax (ap3)** | **10.40.99.13** (VLAN99) · Identity `ap3` | ✅ **LIVE seit 2026-08-30** (TP28-Nachtrag) · `cAPGi-5HaxD2HaxD`, RouterOS **7.24.1** + RouterBOOT 7.24.1 (**seit 2026-08-31 ist die ganze Flotte auf 7.24.1**, TP27-Angleichung erledigt) · reiner CAP, Manager `crs326-core` · **Technik OG**, Uplink `ether1` → **branch `ether24`** (Trunk) · Kanäle **`5180/ax`** (Band A, non-DFS, 5 GHz) + **`2437`** (ch6) nach TP25-Plan · 🔴 **nur 2 Ethernet-Ports** (`ether1` PoE-in, `ether2` PoE-out, **kein** Bridge-Port) → `ap.extra_ports=[]` · `device-mode=basic` (scheduler/fetch/romon **erlaubt**, anders als ap1/ap2) · Dateien `routeros/tp28-ap3-phase{1,2}-*.rsc` + `-service-accounts.rsc` + `-werksreste.rsc` |
| **🔑 Einheitliches Admin-PW (2026-08-08)** | alle 4 MikroTik (core/branch/ap1/ap2) | user `admin`, gleiches PW (`~/.secrets/credentials.env` → `ROUTER_*_PASS`/`CRS326_*_PASS`; „Überlebensversicherung", User-Vorgabe). Werks-Defaults ap1/ap2 damit obsolet. |
| NAS (nas-bf, DS923) | 10.40.20.10 | SSH `adm.christoph@10.40.20.10` (kein PW nötig) · Docker (Portainer endpointId=14) |
| platform-pg (LXC 105, pve) | 10.40.20.20 | SSH via pve (`pct exec 105 --`) · **TP20 ✅ 2026-07-16: PG16, DB `nautobot`, Creds `postgres/.secrets`** |
| Nautobot (Portainer-Stack, NAS) | 10.40.20.30 | Portainer ep14, Stack Id 203 · **TP21 ✅ 2026-07-16: `ghcr.io/nautobot/nautobot:3.1.7`, DB=platform-pg, Creds in `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored)** · **TP22 ✅ 2026-08-13: Golden-Config-App + Device-Adoption DURCH** — alle 4 MikroTik adoptiert, Deploy-Pipeline scharf (Image `3.1.7-gc9`), **68/68 Compliance-Checks grün / 0 Drifts** (2026-08-16) |
| Nautobot (Portainer-Stack, NAS) | **10.40.20.154** (TP45 Schicht A 2026-09-21: `.30/.31/.32/.34` → `.154/.155/.156/.158`) | Portainer ep14, Stack Id 203 · **TP21 ✅ 2026-07-16: `ghcr.io/nautobot/nautobot:3.1.7`, DB=platform-pg, Creds in `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored)** · **TP22 ✅ 2026-08-13: Golden-Config-App + Device-Adoption DURCH** — alle 4 MikroTik adoptiert, Deploy-Pipeline scharf (Image `3.1.7-gc9`), **68/68 Compliance-Checks grün / 0 Drifts** (2026-08-16) |
| ~~Omada-Controller~~ | — | ❌ **entfernt 2026-07-16** (User hat den Container gelöscht — overkill für 1 Switch auf der Abschussliste, s. TP2.1/TP15) |
| ~~omada-mcp~~ | — | ❌ **entfernt 2026-07-16** — mit dem Controller gelöscht. ✅ **Aufräumen erledigt/gegenstandslos (geprüft 2026-08-16):** nicht mehr in `mcpServers` registriert (nur noch als „disabled" in ein paar Projekt-Scopes = harmloser Merkposten), und **kein `omada`-Hostname mehr im CF-Ingress** |
| pve-mcp | 10.40.20.173 | **StreamableHTTP `http://10.40.20.173:3000/` (Root-Pfad, NICHT /sse)** · NAS-Stack ep14 (=nas-bf `.20.10`, NICHT LXC .126!) id 202 (vlan20-only, TP14.1 2026-07-10) · **mcp-pve v0.6.1 (Upgrade 2026-07-10: Single-Session-Bug 0.4.8 „Server already initialized" gefixt, TP14.2a)** · `~/.claude.json` ✓ |
@@ -116,6 +156,25 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
⚠️ **`POST /api/plugins/golden-config/config-plan/` ist `405` — das ViewSet ist read-only.** ConfigPlans
entstehen nur über den Job **`Generate Config Plans`** (`plan_type=manual` + `commands`-TextVar).
- **Docker-Management:** Portainer API `https://10.40.20.126:9443`, Key in `mcp/portainer/.env`.
- 🔴 **`pct push` meldet Exit 0, auch wenn es die Quelldatei NICHT lesen kann** (gemessen 2026-09-21).
`pct push 130 <fehlende-datei> /etc/caddy/Caddyfile` → `failed to open … for reading`, **`rc=0`**.
Ein `&&`/`||` hinter dem Push **beweist nichts**, und ein anschließendes `validate`/`reload` prüft
dann die **alte** Datei → **grüne Abnahme bei unverändertem Zustand**. Genau so sah der
Nautobot-Umzug am 2026-09-21 „gelandet" aus, während live noch die alte Backend-IP stand
(Symptom: 502 bei gesundem Backend). **Regel: Push-Werkzeug wird geprüft, nicht geglaubt** — nach
jedem `pct push` den Inhalt vergleichen (`md5sum` diesseits/jenseits in *einem* Remote-Aufruf,
Abbruch bei Abweichung). Muster: `push_verified()` in `caddy/deploy.sh`. Dieselbe Klasse wie
`nc -z` (09-01) und das `grep|sed`-Maskierungsmuster (08-31): **erst das eigene Werkzeug
verdächtigen, dann das Netz.**
- 🔴 **Die Core-Adressliste `nautobot` wird von Golden Config NIRGENDS gerendert** (Fund 2026-09-21).
Der Mgmt-Zugang des Cores für die Deploy-Pipeline läuft über `src-address-list=nautobot`
(Regel `*28`) — die Liste selbst stammt aber aus dem **handgelaufenen**
`routeros/tp5-etappe2-whitelists.rsc` und steht in **keinem** Template (`grep address-list` im
Template findet nur Kommentare). 🔴 **Ein GC-Recovery von null erzeugt damit einen Core, in den
Nautobot nicht mehr per SSH kommt** — die Pipeline wäre tot und könnte sich nicht selbst
reparieren. Gleiche Lücke wie die DHCP-Reservierungen. **Merkregel: was auf dem Gerät existiert,
aber nicht im Template, ist eine Recovery-Lücke, auch wenn Compliance 140/140 grün meldet** —
die Zahl prüft nur, was gerendert wird.
Ablösung durch Komodo (native MCP) geplant.
---
@@ -248,7 +307,7 @@ GW je VLAN = `.1` (crs326-core L3) · Mgmt VLAN99: core `.99.1`, branch `.99.2`,
danach die Ports gegen vorher vergleichen**, sonst verliert man still einen Dienst.
- **VLAN20-Docker-Hosts: Host-DNS nach dem Umzug prüfen (2026-07-10, TP14.2a):** NAS + pve-LXC zeigten `/etc/resolv.conf` noch auf totes `.41.254` → `docker pull` ghcr scheitert (`EAI_AGAIN`, aber Egress ok!). Fix = `.20.1`: LXC `pct set 400 --nameserver 10.40.20.1`; **Synology-Falle: DSM-„Allgemein"-DNS ≠ was `dockerd` liest** — Interface zieht DNS per DHCP → Fix an der *Netzwerkschnittstelle* „DNS manuell". Laufende Container frieren den `127.0.0.11`-Upstream zum Erstellzeitpunkt ein (Recreate nötig). Merkregel: `docker-pull-hängt` + `dns.lookup EAI_AGAIN` aber `TCP zu ghcr-IP:443 ok` = toter Resolver, nicht Egress.
- 📜 **~~ALLNET VLAN-DB (TP1)~~ — historisch.** Die VLAN-Semantik gilt weiter (**40=MEDIA, 50=UNTRUSTED**), die Portangaben (GE1/GE2/GE8) beziehen sich auf ein ausgebautes Gerät.
- **ap2 hängt an `crs326-branch ether24`** (Trunk, native VLAN1 + tagged 10-99); **branch-Uplink `ether1` → `crs326-core ether8`** (korrigiert 2026-08-16 — die frühere Angabe „→ sw1 GE8" stammt aus der Zeit vor dem Core-Tausch; MAC-hart belegt in TP22 Schritt 5).
- **ap3 hängt an `crs326-branch ether24`** (Trunk, native VLAN1 + tagged 10-99); **branch-Uplink `ether1` → `crs326-core ether8`** (korrigiert 2026-08-16 — die frühere Angabe „→ sw1 GE8" stammt aus der Zeit vor dem Core-Tausch; MAC-hart belegt in TP22 Schritt 5). ap2 hängt seit dem TP25-Tausch (2026-09-15) an `core ether21` (Technik UG), ap1 an `core ether3` (Sideboard).
- **Mesh = NEIN** (beide APs haben wired Trunk-Uplink → Loop-Risiko).
- **Beide APs = CAPs, Manager ist `crs326-core` (TP28 ✅ 2026-08-17).** Der Entscheid „kein CAPsMAN" von 2026-07-22 ist **revidiert**: er galt der Konstellation ap1=Manager+AP, in der ein Manager seine eigenen Radios nicht provisionieren kann — mit dem Core als Manager sind beide APs symmetrisch. Der Core braucht dafür **kein** `wifi-qcom`, `capsman` steckt im Basispaket.
- 🔴 **`/interface wifi scan` geht am CAP NICHT — nur am Manager** (Fund 2026-08-23). Das Gerät

18
__init__.py Normal file
View File

@@ -0,0 +1,18 @@
"""Macht die bf-infra-Repo-Wurzel zu einem regulären Python-Paket.
🔴 LOAD-BEARING — NICHT löschen (sonst laden die Nautobot-Jobs nicht mehr).
Nautobot klont dieses Repo nach GIT_ROOT/bf_infra/ und lädt Jobs über
`import_modules_privately()` → `pkgutil.walk_packages([GIT_ROOT])`. walk_packages
entdeckt ausschließlich *reguläre* Pakete (mit __init__.py), niemals
Namespace-Packages (Verzeichnisse ohne __init__.py). Ohne diese Datei ist
`bf_infra` für den Loader unsichtbar und `jobs/` wird nie importiert — Symptom:
Git-Sync SUCCESS, aber Log "No jobs were registered on loading the
`bf_infra.jobs` submodule" und kein Job-DB-Eintrag.
Der module_path-Filter des Loaders (["bf_infra","jobs"]) importiert nur
`bf_infra` + `bf_infra.jobs.*`; die übrigen Verzeichnisse (nautobot/, routeros/,
bin/, …) bleiben unangetastet und laufen weiter als Standalone-Skripte.
Verifiziert 2026-09-10 (Nautobot 3.1.7, Python 3.14) — TP44 Teil B.
"""

View File

@@ -13,7 +13,9 @@ http:
session_ttl: 30d
users:
- name: admin
password: $2a$10$ue8PEedG4t2JRyT83XiGHeqIU4PFRzhn8rjDOZGYGt0sFC2qju2fi
password: '!on-device (siehe ~/.secrets + Gerät)'
- name: automation
password: '!on-device (siehe ~/.secrets + Gerät)'
auth_attempts: 5
block_auth_min: 15
http_proxy: ""
@@ -69,7 +71,7 @@ dns:
ipset_file: ""
bootstrap_prefer_ipv6: false
upstream_timeout: 10s
private_networks: []
private_<redacted>: []
use_private_ptr_resolvers: true
local_ptr_upstreams: []
use_dns64: false
@@ -202,69 +204,9 @@ filtering:
- domain: gitea.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: nautobot.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: ds-bf.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: ccu.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: iobroker.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: z2m25.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: pve-mcp.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: ha-mcp.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: n8n-mcp.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: gitea-mcp.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: pve.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: portainer.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: pbs.emsenhuber.net
answer: 10.40.20.40
enabled: true
- domain: macmini.emsenhuber.net
answer: 10.40.20.167
enabled: true
- domain: mfc.emsenhuber.net
answer: 10.40.10.6
enabled: true
- domain: tv.emsenhuber.net
answer: 10.40.40.11
enabled: true
- domain: docker.emsenhuber.net
answer: 10.40.20.126
enabled: true
- domain: platform-pg.emsenhuber.net
answer: 10.40.20.20
enabled: true
- domain: core.emsenhuber.net
answer: 10.40.99.1
enabled: true
- domain: ap1.emsenhuber.net
answer: 10.40.99.11
enabled: true
- domain: ap2.emsenhuber.net
answer: 10.40.99.12
enabled: true
- domain: branch.emsenhuber.net
answer: 10.40.99.2
enabled: true
- domain: nas.bf.emsenhuber.net
answer: 10.40.20.10
enabled: true
@@ -316,7 +258,232 @@ clients:
rdns: true
dhcp: true
hosts: true
persistent: []
persistent:
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: dns-bypass-exempt
ids:
- 10.40.10.82
- 10.40.10.183
tags: []
upstreams: []
uid: 381d431a-1a43-41ea-adaa-2d67ada9aab0
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: false
filtering_enabled: false
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: true
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-guest
ids:
- 10.40.90.0/24
tags: []
upstreams: []
uid: af70dd86-43a9-4165-8228-26c7b90db5e6
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: false
filtering_enabled: true
parental_enabled: true
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-infra
ids:
- 10.40.20.0/24
tags: []
upstreams: []
uid: 78b2da82-1946-41ee-b386-b04eaee49bc3
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: false
filtering_enabled: false
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-iot
ids:
- 10.40.30.0/24
tags: []
upstreams: []
uid: 7a8ac674-4365-4b06-ad51-2516400903a1
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: true
filtering_enabled: true
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-main
ids:
- 10.40.10.0/24
tags: []
upstreams: []
uid: 39955cc1-6ec2-4cf6-a757-233672b9dc3d
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: true
filtering_enabled: true
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-media
ids:
- 10.40.40.0/24
tags: []
upstreams: []
uid: 44e4a1d7-d1b6-446c-a753-65e714ec93aa
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: false
filtering_enabled: false
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-mgmt
ids:
- 10.40.99.0/24
tags: []
upstreams: []
uid: 4c5eeafb-f7f2-4fb1-ab87-fd2a2366d57a
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: false
filtering_enabled: false
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
- safe_search:
enabled: false
bing: false
duckduckgo: false
ecosia: false
google: false
pixabay: false
yandex: false
youtube: false
blocked_services:
schedule:
time_zone: Local
ids: []
name: grp-untrusted
ids:
- 10.40.50.0/24
tags: []
upstreams: []
uid: 7f182498-7b82-4580-b1b0-0a2d46c205ef
upstreams_cache_size: 0
upstreams_cache_enabled: false
use_global_settings: true
filtering_enabled: true
parental_enabled: false
safebrowsing_enabled: false
use_global_blocked_services: true
ignore_querylog: false
ignore_statistics: false
log:
enabled: true
file: ""

75
adguard/README.md Normal file
View File

@@ -0,0 +1,75 @@
# AdGuard Home — `agh-bf1` (.36) / `agh-bf2` (.37) · TP23 Stufe 2/4/5
Das AGH-**Paar** (pve LXC 110/111, `10.40.20.36` / `.37`) ist der Client-Resolver des BF-Netzes
(DHCP liefert beide in allen 7 VLANs). Upstream: DoH zum CF-Gateway; conditional
`[/bf.emsenhuber.net/] → 10.40.20.1`. **Kein natives HA** → Sync ist Betriebsaufwand.
## Dateien
| Datei | Zweck |
|---|---|
| `AdGuardHome.yaml` | **Repo-SSoT** der Config. **Passwort-Hashes REDIGIERT** (`'<redacted>'`) — keine Secrets im Git. Echte Hashes leben auf den Geräten; Klartext des API-Users in `~/.secrets`. |
| `agh-sync.py` | `check` (Drift `.36`↔`.37`) · `push` (SSoT auf beide, gestaffelter Restart, reinjiziert Hashes live). |
| `agh-exception.py` | Exception-Primitive (Stufe 5) gegen **beide** Instanzen. |
## Client-Policy (Stufe 4, `clients.persistent`)
Ein VLAN = eine CIDR-Gruppe. Alle nutzen denselben CF-Upstream-Filter; Divergenz = per-Client-Toggle.
| Gruppe | CIDR | filtering | safe_search | parental |
|---|---|---|---|---|
| grp-main | 10.40.10.0/24 | an (global) | – | – |
| grp-infra | 10.40.20.0/24 | **aus** | – | – |
| grp-iot | 10.40.30.0/24 | an | – | – |
| grp-media | 10.40.40.0/24 | **aus** | – | – |
| grp-untrusted | 10.40.50.0/24 | an | – | – |
| grp-guest | 10.40.90.0/24 | an | **on** | **on** |
| grp-mgmt | 10.40.99.0/24 | **aus** | – | – |
| dns-bypass-exempt | 10.40.10.183 + .82 | **aus** | – | – |
`filtering aus` bei INFRA/MEDIA/MGMT = bewusste Reduktion (Streaming/Server/Mgmt nicht brechen), per Gruppe rückholbar.
## Personen-Clients (Stufe 5 Redesign 2026-09-12) — SSoT für Person→Gerät
Zusätzlich zu den VLAN-CIDR-Gruppen bekommt **jede Person einen eigenen AGH-Client**
(`/control/clients`): `name` = Personenname, `ids` = **alle** Geräte-IPs der Person. Das ist der
**einzige** Ort, an dem Person→Gerät gepflegt wird (kein zweites Mapping-File). Damit:
- wirken Self-Service-Ausnahmen **pro Person**: `@@||domain^$client='Personenname'` statt global;
- filtert `recent-blocked --client <person>` das Query-Log auf **ihre** Geräte;
- bleiben Ausnahmen stabil bei Gerätewechsel (Name statt IP).
🔴 **On-network verifizieren, bevor Stufe 6 scharf geht:** dass AGH `$client=` auf **Allow**-Regeln
(`@@`) in der laufenden Version greift. Fällt der Test negativ aus → Fallback `$client=<ip>|<ip>`
(die Geräte-IPs); `agh-exception.py scoped_rule()` kann beides. Die CIDR-Gruppen (Policy-Grenze)
bleiben unberührt — Personen-Clients tragen **nur** die Ausnahmen.
## Sync-Invariante
AGH **schreibt die YAML beim Restart um** (normalisiert) → **nicht** gegen die Repo-Datei diffen,
sondern **`.36` == `.37`**. Genau das prüft `agh-sync.py check`.
## Exception-Contract (Stufe 5 — was die HA-Schicht auslöst)
Auth: Basic, User `automation` (`~/.secrets` → `AGH_AUTOMATION_*`). **Immer auf `.36` UND `.37`.**
🔴 **Wichtig für D:** die beiden AGH-Endpunkte sind **read-modify-write**, kein simples Append —
`set_rules` **ersetzt die ganze Liste**, `clients/update` braucht das **volle Client-Objekt**.
Ein zustandsloses HA-`rest_command` reicht deshalb **nicht**; `agh-exception.py` ist die
Referenz-RMW-Implementierung, die D aufruft (Deploy-Weg auf HAOS in Etappe D zu entscheiden:
`shell_command`/`command_line` gegen die deployte CLI **oder** ein dünner Wrapper-Endpunkt).
| Aktion | CLI | AGH-API (RMW) |
|---|---|---|
| Domain **pro Person** entsperren | `allow-domain <d> --client <person>` | `GET /control/filtering/status` → +`@@\|\|<d>^$client='<person>'` → `POST /control/filtering/set_rules` |
| Domain global entsperren (Admin) | `allow-domain <d>` | dito, ohne `$client` |
| Entsperrung zurück | `unallow-domain <d> [--client <person>]` | dito, exakt dieselbe Regel entfernen |
| „meine Ausnahmen" | `list-exceptions --client <person> --json` | `GET /control/filtering/status`, `@@`-Regeln parsen/filtern |
| „zuletzt geblockt" | `recent-blocked --client <person> --json` | `GET /control/querylog?response_status=blocked`, client-seitig auf Geräte-IPs gefiltert |
| Client entfiltern (grob) | `unfilter <ip>` | `GET /control/clients` → Objekt, `filtering_enabled=false` → `POST /control/clients/update` |
| Client wieder filtern | `refilter <ip>` | dito, zurück auf global |
Reine Regel-/Filter-Logik ist netzunabhängig getestet: `python3 agh-exception.py selftest`.
**Kein Timing in der CLI** — Ablauf/Revert macht der Aufrufer (HA-Timer) und, ab Stufe 6, der
RouterOS-Backstop.
## RouterOS-Backstop (Stufe 6, noch NICHT gebaut)
Analog `jit-admin` (`routeros/tp5-etappe4-input-mgmt.rsc`): Address-List `jit-dns-bypass` mit
`timeout` + Forward-Regel, die dieser Liste 53/853 nach außen erlaubt — der Fail-safe, falls HA
den Revert verpasst. Gebaut via **Nautobot GC** (kein Direkt-Write), erst wenn die Bypass-Sperre
scharf geschaltet wird.

287
adguard/agh-exception.py Executable file
View File

@@ -0,0 +1,287 @@
#!/usr/bin/env python3
"""
agh-exception.py — TP23 Stufe 5 Exception-Primitive gegen das AGH-Paar (.36 + .37).
Von der HA-Self-Service-Schicht (shell_command) ODER von Hand aufrufbar. Wirkt IMMER auf
BEIDE Instanzen (kein Sync im Datenpfad). KEIN eigenes Timing — Ablauf/Revert macht der
Aufrufer (HA-Timer) bzw. der RouterOS-Backstop (Stufe 6). Diese CLI ist reines add/remove/read.
allow-domain <domain> [--client <name|ip[,ip]>] → user_rules += @@||domain^[$client=…]
unallow-domain <domain> [--client <name|ip[,ip]>] → dieselbe Regel wieder entfernen
list-exceptions [--client <name>] [--json] → alle @@-Regeln, nach Client gruppiert
recent-blocked --client <name|ip[,ip]> [--limit N] [--json]
→ zuletzt geblockte Domains DIESER Person
unfilter <ip> → Client (dessen ids <ip> enthält) filtering_enabled=false (grob!)
refilter <ip> → denselben Client wieder filtern (use_global_settings=true)
status → user_rules + Client-Policy beider Instanzen
--client:
* ein AGH-Client-NAME (empfohlen, stabil bei Gerätewechsel) → Regel bekommt $client='Name',
IPs werden für recent-blocked aus /control/clients (ids) aufgelöst.
* ODER eine/mehrere IP/CIDR, komma-getrennt → $client=<ip>|<ip>, recent-blocked filtert darauf.
ohne --client bei allow/unallow = GLOBAL (für alle) — nur für Admin-Zwecke.
🔴 ANNAHME, on-network zu verifizieren, BEVOR Stufe 6 scharf geht: dass AGH $client= auf
ALLOW-Regeln (@@) in der laufenden Version wirkt. Die Regelkonstruktion steht isoliert in
scoped_rule()/parse_allow_rule() — falls die Syntax abweicht, nur dort anpassen.
Auth: AGH_AUTOMATION_USER/_PASS aus ~/.secrets/credentials.env (nie in argv).
"""
import sys, os, json, base64, urllib.request, urllib.error, urllib.parse, pathlib, re, ipaddress, argparse
DOMAIN_RE = re.compile(r"^(?=.{1,253}$)([a-z0-9](-?[a-z0-9]+)*\.)+[a-z]{2,}$", re.I)
IP_RE = re.compile(r"^\d{1,3}(\.\d{1,3}){3}$")
CIDR_RE = re.compile(r"^\d{1,3}(\.\d{1,3}){3}/\d{1,2}$")
# Ein Client-„spec" ist IP-artig, wenn JEDES komma-Glied IP oder CIDR ist; sonst = Name.
INST = ["10.40.20.36", "10.40.20.37"]
# Creds-Quellen in Reihenfolge: erste, die User+Pass liefert, gewinnt.
# So läuft derselbe Code auf dem Mac (~/.secrets) und auf HAOS (/config).
CRED_FILES = [
os.environ.get("AGH_CREDS_FILE"),
str(pathlib.Path.home() / ".secrets/credentials.env"),
"/config/agh-exception.secrets",
]
def _from_file(path):
u = p = None
try:
for line in open(path).read().splitlines():
if line.startswith("AGH_AUTOMATION_USER="): u = line.split("=", 1)[1].strip()
if line.startswith("AGH_AUTOMATION_PASS="): p = line.split("=", 1)[1].strip()
except OSError:
return None
return (u, p) if (u and p) else None
def creds():
eu, ep = os.environ.get("AGH_AUTOMATION_USER"), os.environ.get("AGH_AUTOMATION_PASS")
if eu and ep:
return eu, ep
for f in CRED_FILES:
if f and (r := _from_file(f)):
return r
sys.exit("AGH_AUTOMATION_USER/_PASS: weder Env noch eine Creds-Datei gefunden")
_AUTH = None
def auth_header():
# lazy: erst beim ersten echten API-Call — so bleibt das Modul ohne Creds importier-/testbar.
global _AUTH
if _AUTH is None:
_AUTH = "Basic " + base64.b64encode(":".join(creds()).encode()).decode()
return _AUTH
def api(ip, path, method="GET", body=None):
url = f"http://{ip}{path}"
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data=data, method=method,
headers={"Authorization": auth_header(),
"Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=8) as r:
raw = r.read()
return json.loads(raw) if raw else {}
except urllib.error.HTTPError as e:
sys.exit(f"{ip} {path} → HTTP {e.code}: {e.read().decode()[:200]}")
except Exception as e:
sys.exit(f"{ip} {path} → {e}")
# ---------------------------------------------------------------------------
# Reine Regel-Logik (netzunabhängig, self-testbar). Bei AGH-Syntax-Drift NUR hier anfassen.
# ---------------------------------------------------------------------------
def is_ip_spec(spec):
"""True, wenn spec eine (Komma-)Liste aus lauter IPs/CIDRs ist (→ IP-spec), sonst Name."""
parts = [s.strip() for s in spec.split(",") if s.strip()]
return bool(parts) and all(IP_RE.match(p) or CIDR_RE.match(p) for p in parts)
def client_modifier(spec):
"""$client-Modifier-Wert für eine Regel. IP-spec → ip|ip ; Name → 'Name' (quoted)."""
if is_ip_spec(spec):
return "|".join(s.strip() for s in spec.split(",") if s.strip())
return "'" + spec.replace("'", "") + "'"
def scoped_rule(domain, client=None):
"""@@||domain^ bzw. @@||domain^$client=… (client = Name oder ip[,ip])."""
base = f"@@||{domain}^"
return base if not client else f"{base}$client={client_modifier(client)}"
_ALLOW_RE = re.compile(r"^@@\|\|(?P<domain>[^\^]+)\^(?:\$client=(?P<client>.+))?$")
def parse_allow_rule(rule):
"""@@-Regel → {'domain':…, 'client': <str oder None>, 'raw': rule} oder None."""
m = _ALLOW_RE.match(rule.strip())
if not m:
return None
return {"domain": m.group("domain"), "client": m.group("client"), "raw": rule.strip()}
def ip_in_specs(ip, specs):
"""Ist ip (aus dem Query-Log) von einer der specs (IP oder CIDR) erfasst?"""
try:
addr = ipaddress.ip_address(ip)
except ValueError:
return False
for s in specs:
s = s.strip()
try:
if "/" in s:
if addr in ipaddress.ip_network(s, strict=False):
return True
elif ip == s:
return True
except ValueError:
continue
return False
# ---------------------------------------------------------------------------
def resolve_client_ips(spec):
"""spec → Liste von IP/CIDR-strings. IP-spec direkt; Name → ids des AGH-Clients (von .36)."""
if is_ip_spec(spec):
return [s.strip() for s in spec.split(",") if s.strip()]
data = api(INST[0], "/control/clients")
for c in data.get("clients", []):
if c.get("name") == spec:
return list(c.get("ids", []))
sys.exit(f"kein AGH-Client mit name={spec!r} (für IP-spec Komma-Liste aus IP/CIDR angeben)")
def allow(domain, client=None, remove=False):
domain = domain.strip().lower()
if not DOMAIN_RE.match(domain):
sys.exit(f"ungültige Domain: {domain!r}")
r = scoped_rule(domain, client)
for ip in INST:
st = api(ip, "/control/filtering/status")
rules = st.get("user_rules", [])
if remove:
rules = [x for x in rules if x.strip() != r]
elif r not in rules:
rules = rules + [r]
api(ip, "/control/filtering/set_rules", "POST", {"rules": rules})
print(f"{ip}: {'entfernt' if remove else 'gesetzt'} {r} (user_rules={len(rules)})")
def list_exceptions(client=None, as_json=False):
st = api(INST[0], "/control/filtering/status") # .36 == .37 (Invariante, via agh-sync geprüft)
items = []
for raw in st.get("user_rules", []):
p = parse_allow_rule(raw)
if not p:
continue
if client is not None and (p["client"] or "") != client_modifier(client):
continue
items.append(p)
if as_json:
print(json.dumps(items, ensure_ascii=False))
return
if not items:
print("— keine Ausnahmen —"); return
for p in items:
who = p["client"] or "GLOBAL"
print(f" {p['domain']:40} client={who}")
def recent_blocked(client, limit=20, as_json=False):
specs = resolve_client_ips(client)
q = urllib.parse.urlencode({"response_status": "blocked", "limit": max(limit * 8, 100)})
data = api(INST[0], f"/control/querylog?{q}")
seen = {} # domain -> {count, last}
for e in data.get("data", []):
c = e.get("client", "")
if not ip_in_specs(c, specs):
continue
dom = (e.get("question", {}) or {}).get("name", "").rstrip(".").lower()
if not dom:
continue
rec = seen.setdefault(dom, {"domain": dom, "count": 0, "last": e.get("time", "")})
rec["count"] += 1
if e.get("time", "") > rec["last"]:
rec["last"] = e.get("time", "")
out = sorted(seen.values(), key=lambda r: r["last"], reverse=True)[:limit]
if as_json:
print(json.dumps(out, ensure_ascii=False)); return
if not out:
print("— nichts geblockt —"); return
for r in out:
print(f" {r['domain']:40} x{r['count']:<4} {r['last']}")
def set_filter(ip_addr, enabled):
if not IP_RE.match(ip_addr):
sys.exit(f"ungültige IP: {ip_addr!r}")
for ip in INST:
data = api(ip, "/control/clients")
c = None
for cand in data.get("clients", []):
if ip_addr in cand.get("ids", []):
c = cand; break
if not c:
sys.exit(f"{ip}: kein Client mit id exakt {ip_addr} — für Gruppen die CIDR angeben")
c = dict(c)
c["use_global_settings"] = enabled
c["filtering_enabled"] = enabled
api(ip, "/control/clients/update", "POST", {"name": c["name"], "data": c})
print(f"{ip}: {c['name']} filtering={'an' if enabled else 'AUS'}")
def status():
for ip in INST:
st = api(ip, "/control/filtering/status")
allows = [r for r in st.get("user_rules", []) if r.startswith("@@")]
cl = api(ip, "/control/clients").get("clients", [])
print(f"== {ip} == allow-rules={allows or '—'}")
for c in cl:
print(f" {c['name']:16} ids={c['ids']} global={c['use_global_settings']} filt={c['filtering_enabled']}")
def _selftest():
"""Netzunabhängiger Test der reinen Regel-Logik."""
assert is_ip_spec("10.40.10.82") and is_ip_spec("10.40.10.82,10.40.10.183")
assert is_ip_spec("10.40.10.0/24") and not is_ip_spec("christoph")
assert scoped_rule("x.com") == "@@||x.com^"
assert scoped_rule("x.com", "10.40.10.82,10.40.10.183") == "@@||x.com^$client=10.40.10.82|10.40.10.183"
assert scoped_rule("x.com", "christoph") == "@@||x.com^$client='christoph'"
p = parse_allow_rule("@@||x.com^$client='christoph'")
assert p and p["domain"] == "x.com" and p["client"] == "'christoph'"
p2 = parse_allow_rule("@@||y.com^")
assert p2 and p2["client"] is None
assert parse_allow_rule("||block.com^") is None
assert ip_in_specs("10.40.10.82", ["10.40.10.82"]) is True
assert ip_in_specs("10.40.10.5", ["10.40.10.0/24"]) is True
assert ip_in_specs("10.40.20.5", ["10.40.10.0/24"]) is False
# round-trip: eine scoped Regel wird von list-exceptions --client wieder getroffen
assert (parse_allow_rule(scoped_rule("z.com", "christoph"))["client"]
== client_modifier("christoph"))
print("selftest OK")
if __name__ == "__main__":
ap = argparse.ArgumentParser(add_help=False)
ap.add_argument("cmd", nargs="?")
ap.add_argument("arg", nargs="?")
ap.add_argument("--client")
ap.add_argument("--permanent", action="store_true") # semantisch = kein Timer; wirkt in HA, nicht hier
ap.add_argument("--limit", type=int, default=20)
ap.add_argument("--json", action="store_true")
a = ap.parse_args()
if not a.cmd:
sys.exit(__doc__)
if a.cmd == "allow-domain": allow(a.arg, a.client)
elif a.cmd == "unallow-domain": allow(a.arg, a.client, remove=True)
elif a.cmd == "list-exceptions": list_exceptions(a.client, a.json)
elif a.cmd == "recent-blocked":
if not a.client: sys.exit("recent-blocked braucht --client <name|ip[,ip]>")
recent_blocked(a.client, a.limit, a.json)
elif a.cmd == "unfilter": set_filter(a.arg, False)
elif a.cmd == "refilter": set_filter(a.arg, True)
elif a.cmd == "status": status()
elif a.cmd == "selftest": _selftest()
else: sys.exit(f"unbekannt: {a.cmd}\n{__doc__}")

113
adguard/agh-sync.py Executable file
View File

@@ -0,0 +1,113 @@
#!/usr/bin/env python3
"""
agh-sync.py — AdGuard-Home-Paar agh-bf1 (.36) / agh-bf2 (.37) synchron halten.
TP23 Stufe 2/4: die beiden AGH-Instanzen (pve LXC 110/111) haben KEIN natives HA →
Config-Sync ist Betriebsaufwand. Dieses Werkzeug ist der Sync.
SSoT = adguard/AdGuardHome.yaml (Passwort-Hashes REDIGIERT — keine Secrets im Git).
Wahrheit im Datenpfad = die beiden Live-Instanzen; die Invariante ist .36 == .37
(AGH normalisiert die YAML beim Restart, daher NICHT gegen die Repo-Datei vergleichen,
sondern die beiden Live-Configs gegeneinander).
check pull .36 + .37, Passwörter redigiert diffen → meldet Drift (exit 1 bei Drift)
push Repo-SSoT nehmen, echte users-Hashes aus .36 (live) reinjizieren, validieren,
auf beide pushen, GESTAFFELT neu starten (110 → prüfen → 111), .36==.37 + API prüfen
Kein Direkt-`sshpass -p` (Leak). SSH-Key zu root@pve vorausgesetzt.
"""
import subprocess, sys, tempfile, base64, os, re, pathlib, urllib.request
PVE = "root@10.40.20.100"
INST = {"110": "10.40.20.36", "111": "10.40.20.37"} # ct-id -> ip
PRIMARY = "110" # Reihenfolge: primary zuerst
SVC = "AdGuardHome.service"
CFG = "/opt/AdGuardHome/AdGuardHome.yaml"
REPO = pathlib.Path(__file__).resolve().parent
SSOT = REPO / "AdGuardHome.yaml"
PW_RE = re.compile(r"^( password: ).*$")
def sh(*args, inp=None):
return subprocess.run(args, input=inp, capture_output=True, text=True)
def pull(ct):
r = sh("ssh", "-o", "ConnectTimeout=8", PVE, f"pct exec {ct} -- cat {CFG}")
if r.returncode:
sys.exit(f"pull {ct} fehlgeschlagen: {r.stderr.strip()}")
return r.stdout
def redact(text):
return "\n".join(PW_RE.sub(r"\1'<redacted>'", l) for l in text.splitlines())
def live_users_hashes(ct):
"""echte password-Zeilen (in Reihenfolge) aus der Live-Config von ct."""
out, inusers = [], False
for l in pull(ct).splitlines():
if l.startswith("users:"): inusers = True; continue
if inusers and l and not l.startswith((" ", "\t")): break
if inusers:
m = PW_RE.match(l)
if m: out.append(l)
return out
def cmd_check():
a, b = redact(pull("110")), redact(pull("111"))
if a == b:
print("✅ .36 == .37 (synchron)")
return 0
print("🔴 DRIFT zwischen .36 und .37:")
import difflib
for line in difflib.unified_diff(a.splitlines(), b.splitlines(),
".36", ".37", lineterm=""):
print(line)
return 1
def cmd_push():
if not SSOT.exists():
sys.exit(f"SSoT fehlt: {SSOT}")
ssot = SSOT.read_text()
# echte Hashes aus dem primary reinjizieren (SSoT trägt nur Redaktions-Platzhalter)
hashes = live_users_hashes(PRIMARY)
red = [i for i, l in enumerate(ssot.splitlines()) if PW_RE.match(l)]
if len(red) != len(hashes):
sys.exit(f"users-Anzahl SSoT({len(red)}) != live({len(hashes)}) — manuell prüfen")
lines = ssot.splitlines()
for idx, real in zip(red, hashes):
lines[idx] = real
merged = "\n".join(lines) + "\n"
# validieren
try:
import yaml
doc = yaml.safe_load(merged)
assert doc["users"] and doc["clients"]["persistent"]
except Exception as e:
sys.exit(f"merge invalide: {e}")
b64 = base64.b64encode(merged.encode()).decode()
order = [PRIMARY] + [c for c in INST if c != PRIMARY]
for ct in order:
print(f"→ push + restart {ct} ({INST[ct]}) …")
r = sh("ssh", "-o", "ConnectTimeout=10", PVE,
f"pct exec {ct} -- sh -c 'base64 -d > {CFG}.new && "
f"cp -a {CFG} {CFG}.presync && mv {CFG}.new {CFG} && "
f"systemctl restart {SVC} && sleep 2 && systemctl is-active {SVC}'",
inp=b64)
if r.returncode or "active" not in r.stdout:
sys.exit(f"push {ct} fehlgeschlagen: {r.stdout} {r.stderr}")
print(f" {ct} active")
print(cmd_check_msg())
return cmd_check()
def cmd_check_msg():
return "— Verifikation:"
if __name__ == "__main__":
cmd = sys.argv[1] if len(sys.argv) > 1 else "check"
sys.exit({"check": cmd_check, "push": cmd_push}.get(cmd, cmd_check)())

View File

@@ -0,0 +1,98 @@
# TP23 Stufe 5 (Redesign 2026-09-12) — DAU-tauglicher, personenbezogener DNS-Self-Service
> 🔴 **Status: Bau-Spec, noch nicht deployt.** Die alte Fassung (single-domain, temp-only,
> HA-Neustart bei neuer Domain) war „funktional ein kastriertes Pi-hole" (User-Befund 2026-09-12)
> und ist ersetzt. Bau + Abnahme laufen **on-network** (HAOS `10.40.20.105`, AGH `.36/.37`) — beim
> Anlegen den **home-assistant-best-practices-Skill** konsultieren und via **ha-mcp** in `.storage`
> anlegen (native Helper, `entity_id` statt `device_id`). Diese Datei ist die Repro-/SSoT-Quelle.
## Ziel (User-Requirements 2026-09-12)
Ein **einfaches, klar verständliches** End-User-UI zum Entsperren:
- **alles was den Nutzer betrifft, nichts** von anderen / Admin / Power-User;
- Policy nur sichtbar, wo sie für den einfachen Nutzer Relevanz hat.
| # | Requirement | Umsetzung |
|---|---|---|
| 1 | **Pro Person** (Login), Sicht über alle Geräte | HA-User = Person; Person → AGH-Client (Name), dessen `ids` = ihre Geräte-IPs |
| 2 | **„zuletzt geblockt" → 1 Klick** | `recent-blocked --client <person>` aus dem AGH-Query-Log, auf die Geräte der Person gefiltert |
| 3 | **temporär UND dauerhaft**, Modus umschaltbar | Dauer-Select inkl. „dauerhaft"; `input_boolean` self-permanent ⇄ Anfrage. **Start: self-permanent** |
| 4 | **HA-Dashboard, scoped** pro Person | ein View je Person, nur für ihre HA-User-ID sichtbar |
## Identitätsmodell — AGH-Client je Person ist die SSoT
- Pro Person **ein AGH-Client** (`/control/clients`), `name` = Personenname, `ids` = **alle** Geräte-IPs
der Person (die per DHCP faktisch statisch sind). Damit ist Person→Gerät **an einem Ort** gepflegt
(kein zweites Mapping-File), und Ausnahmen sind stabil bei Gerätewechsel.
- Ausnahme-Regel = `@@||domain^$client='Personenname'` (statt globalem `@@||domain^`).
🔴 **Vor Scharfschalten on-network verifizieren, dass AGH `$client=` auf `@@`-Regeln wirkt**
(s. `agh-exception.py` Kopf). Fällt der Test negativ aus: Fallback = `$client=<ip>|<ip>` mit den
Geräte-IPs statt dem Namen (Code kann beides, `scoped_rule()`).
- Die bestehenden **VLAN-CIDR-Gruppen** bleiben die Policy-Grenze (Filter an/aus je VLAN);
Personen-Clients sind spezifischer und tragen nur die *Ausnahmen*.
## CLI (deployt nach `/config/agh-exception.py`, wirkt auf `.36`+`.37`)
```
allow-domain <domain> --client <person> # Ausnahme setzen (temp: HA revertiert; perm: kein Timer)
unallow-domain <domain> --client <person> # dieselbe Ausnahme entfernen
list-exceptions --client <person> --json # „meine Ausnahmen" (für Übersicht + Entfernen)
recent-blocked --client <person> --json # „zuletzt geblockt" (nur Geräte der Person)
```
`--client` nimmt einen AGH-Client-Namen (→ IPs via `/control/clients`) ODER eine Komma-IP/CIDR-Liste.
## `configuration.yaml` — `shell_command` (einziger YAML-Teil, Backup `.bak-tp23-*`)
Domain **und** Client sind Parameter → **kein HA-Neustart mehr** bei neuer Domain (das war der alte
DAU-Killer: pro Domain ein eigener `shell_command`).
```yaml
shell_command:
agh_allow: "python3 /config/agh-exception.py allow-domain '{{ domain }}' --client '{{ client }}'"
agh_unallow: "python3 /config/agh-exception.py unallow-domain '{{ domain }}' --client '{{ client }}'"
```
## Helfer / Entities (via ha-mcp in .storage)
Pro Person (Beispiel `christoph`) — bei mehreren Personen je einmal, Suffix = Personen-Slug:
| Typ | entity_id | Zweck |
|---|---|---|
| command_line sensor | `sensor.dns_recent_blocked_<slug>` | `recent-blocked --client <person> --json` → `json_attributes: items` (Liste {domain,count,last}); Scan-Intervall ~60 s |
| command_line sensor | `sensor.dns_exceptions_<slug>` | `list-exceptions --client <person> --json` → aktive Ausnahmen der Person |
| input_select | `input_select.dns_dauer_<slug>` | 1 Stunde / 4 Stunden / **dauerhaft** |
| timer | `timer.dns_ausnahme_<slug>` | JIT-Countdown je temporärer Freigabe (restore=false) |
| input_boolean | `input_boolean.dns_permanent_ohne_anfrage` | **global**: an = „dauerhaft" wirkt sofort (Start); aus = erzeugt Admin-Genehmigung |
| script | `script.dns_freigeben_<slug>` | nimmt `domain` als Feld → `agh_allow`; bei „dauerhaft"+Switch-aus → `todo`/Notification statt Freigabe; sonst Timer starten |
| automation | `automation.dns_ablauf_<slug>` | `timer.finished`/`.cancelled` → `agh_unallow`, Aufräumen |
## Dashboard — ein scoped View je Person
- Eigener storage-Dashboard-View, **nur für die HA-User-ID der Person sichtbar** (`visible:` mit
der user-id; `require_admin:false`). Kleiner Haushalt → ein View je Person ist praktikabel und
umgeht das „Template kennt den aktuellen Betrachter nicht"-Problem.
- **Karte 1 „Zuletzt geblockt (antippen zum Freigeben)":** rendert `sensor.dns_recent_blocked_<slug>`
Attribut `items`; jede Zeile hat eine `tap_action` → `script.dns_freigeben_<slug>` mit `domain`
der Zeile + aktueller `input_select`-Dauer. (Dynamische Per-Zeilen-tap_action braucht i.d.R.
`auto-entities` + `template`/`button-card` **oder** ein kleines Custom-List-Template — **beim Bau
on-network entscheiden**, das ist der Teil, der Live-Verifikation braucht.)
- **Karte 2 „Meine Ausnahmen":** `sensor.dns_exceptions_<slug>` als Liste, je Eintrag Entfernen
(`agh_unallow`).
- **Karte 3 „Dauer":** `input_select.dns_dauer_<slug>` (inkl. „dauerhaft").
- **Kein** globaler Status, keine fremden Clients, keine Policy-Interna. Nur wenn relevant ein
kurzer Hinweis („durch den Familien-Filter blockiert").
## Genehmigungs-Variante (Modus-Switch aus)
`input_boolean.dns_permanent_ohne_anfrage = off` → „dauerhaft"-Klick legt statt der Freigabe einen
Eintrag in einer **`todo`-Liste** „DNS-Freigaben zu prüfen" an (+ Notification an Christoph). Beim
Abhaken führt eine Admin-Automation `agh_allow` ohne Timer aus. Beide Varianten sind gebaut; der
Switch entscheidet zur Laufzeit.
## Alt-Reste, die beim Bau wegfallen/fixen
- Single-domain-Flow (`input_text.dns_ausnahme_domain/_aktiv`, `input_button…_starten`,
`automation…_starten/_ablauf`) und der `agh_allow_domain`/`_unallow_domain`-**pro-Domain**-Zwang.
- Statuskachel-Sensor `binary_sensor.adguard_bf1_status` hing am toten `.16` → auf `.36`/`.37` neu.
## Abnahme (on-network, = neue echte Stufe-6-Vorbedingung)
Mit einem **echten Nicht-Admin-Login**: geblockte Seite → erscheint in *ihrer* Fläche → 1 Klick
temporär (revertiert nach Ablauf) **und** 1 Klick dauerhaft (bleibt) → wirkt **nur** für diese
Person (Gegentest: anderer Client sieht die Domain weiter geblockt). `.36 == .37`
(`agh-sync.py check`). Modus-Switch beide Wege einmal durchgespielt.
## Verweise
- CLI: `adguard/agh-exception.py` (Subcommands + `selftest`). Deploy-Weg unverändert (base64→scp,
s. unten). Creds `/config/agh-exception.secrets` (chmod 600).
- Redeploy: `base64 < adguard/agh-exception.py | ssh admin@10.40.20.105 "base64 -d | sudo tee /config/agh-exception.py >/dev/null"`.
- Personen-Client-Modell: `adguard/README.md`. Kontext/Reihenfolge: TP23 in `docs/teilprojekte.md`.

218
bin/gitea-tp-sync.py Normal file
View File

@@ -0,0 +1,218 @@
#!/usr/bin/env python3
"""
TP36 (reframed) — teilprojekte.md Index/Status → Gitea Issues (admin/bf-infra).
Idempotenter Sync (get-or-create, Match ueber "TPnn" im Titel):
- Archiv-Header in docs/teilprojekte-archiv.md -> closed Issues (nur TPs, die in Gitea
NICHT offen sind; ein reopentes TP mit Archiv-Zeiger bleibt offen).
- Labels status:* (Marker) + thema:* (Gruppierung) werden vorab get-or-create.
SSoT-Modell (seit TP36-Cutover 2026-09-07): Gitea fuehrt Index+Status — aktive TPs werden
DIREKT als Gitea-Issue angelegt/gepflegt, NICHT mehr aus einer Datei-Tabelle abgeleitet
(die Quick-Index-Tabelle wurde aus teilprojekte.md entfernt). Dieses Werkzeug haelt nur noch
die ARCHIVIERTEN (closed) TPs mit teilprojekte-archiv.md idempotent abgeglichen und fasst
offene Issues nie an. Die per-TP-Prosa bleibt in docs/teilprojekte.md / teilprojekte-archiv.md.
Token: ~/.hermes/.env (GITEA_ACCESS_TOKEN, GITEA_HOST) — wird NIE ausgegeben.
Aufruf:
python3 bin/gitea-tp-sync.py # Dry-Run (default) — zeigt, was passieren wuerde
python3 bin/gitea-tp-sync.py --commit # legt Labels + Issues an / gleicht sie ab
"""
import json
import os
import re
import sys
import urllib.request
import urllib.error
from pathlib import Path
REPO = Path(__file__).resolve().parent.parent
ACTIVE = REPO / "docs" / "teilprojekte.md"
ARCHIV = REPO / "docs" / "teilprojekte-archiv.md"
HERMES = Path.home() / ".hermes" / ".env"
OWNER_REPO = "admin/bf-infra"
COMMIT = "--commit" in sys.argv
# Marker -> (status-label, gitea-state)
MARKER = {
"🔜": ("status:todo", "open"),
"⏳": ("status:wip", "open"),
"⏸️": ("status:paused", "open"),
"💡": ("status:idea", "open"),
"🟢": ("status:concept", "open"),
"✅": ("status:done", "closed"),
"❌": ("status:dropped", "closed"),
}
LABEL_COLORS = {
"status:todo": "#ededed", "status:wip": "#fbca04", "status:paused": "#c5def5",
"status:idea": "#d4c5f9", "status:concept": "#bfdadc", "status:done": "#0e8a16",
"status:dropped": "#e11d21",
"thema:firewall-dns": "#b60205", "thema:wlan": "#1d76db", "thema:cloudflare-proxy": "#f9a825",
"thema:nautobot-doku": "#5319e7", "thema:infra": "#0e8a16", "thema:ipv6-matter": "#006b75",
"thema:identity": "#e99695", "thema:backlog": "#cccccc",
}
# TP-Nummer -> Themen-Label (aus dem Statusbaum-Gruppierung; nur aktive TPs brauchen ein Board-Thema)
THEME = {
"5.1": "firewall-dns", "23": "firewall-dns",
"25": "wlan", "28": "wlan", "13": "wlan", "17.1": "wlan", "17.3": "wlan",
"16": "cloudflare-proxy", "16.2": "cloudflare-proxy", "16.3": "cloudflare-proxy",
"31": "cloudflare-proxy", "41": "cloudflare-proxy", "14.4": "cloudflare-proxy",
"42": "cloudflare-proxy", "43": "cloudflare-proxy", "44": "cloudflare-proxy",
"32": "nautobot-doku", "34": "nautobot-doku", "35": "nautobot-doku",
"36": "nautobot-doku", "37": "nautobot-doku",
"30": "infra", "40": "infra", "20.1": "infra", "18": "infra",
"24": "infra", "38": "infra", "11": "infra",
"12": "ipv6-matter", "12.1": "ipv6-matter",
"8": "identity",
"29": "backlog", "33": "backlog",
}
def hermes_env():
tok = host = None
for line in HERMES.read_text().splitlines():
m = re.match(r"\s*(GITEA_ACCESS_TOKEN|GITEA_HOST)\s*=\s*(.+?)\s*$", line)
if not m:
continue
if m.group(1) == "GITEA_ACCESS_TOKEN":
tok = m.group(2).strip().strip('"').strip("'")
else:
host = m.group(2).strip().strip('"').strip("'")
if not tok:
sys.exit("GITEA_ACCESS_TOKEN nicht in %s gefunden." % HERMES)
host = (host or "https://gitea.emsenhuber.net").rstrip("/")
if not host.startswith("http"):
host = "https://" + host
return tok, host
TOKEN, HOST = hermes_env()
API = HOST + "/api/v1"
def api(method, path, body=None):
url = API + path
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data=data, method=method, headers={
"Authorization": "token " + TOKEN,
"Accept": "application/json", "Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=30) as r:
return r.status, json.load(r)
except urllib.error.HTTPError as e:
return e.code, (json.load(e) if e.headers.get("content-type", "").startswith("application/json") else {})
# --------------------------------------------------------------------------- parse
def parse_archiv(exclude_nums):
"""Archiv-Header -> archivierte TPs. exclude_nums = TP-Nummern, die in Gitea OFFEN sind
(reopente TPs mit Archiv-Zeiger) -> die bleiben offen, nicht als closed abgleichen."""
out = []
hdr = re.compile(r"^#{2,4}\s*(TP[\d.\-A-Za-z]+)\s*—\s*(.+?)\s*▸", )
seen = set()
for line in ARCHIV.read_text().splitlines():
m = hdr.match(line)
if not m:
continue
tp, title = m.groups()
num = tp[2:]
if num in exclude_nums or num in seen:
continue
seen.add(num)
short = re.sub(r"\*\*|`", "", title).strip()[:80]
out.append({"tp": tp, "num": num, "marker": "✅",
"title": short, "date": "", "src": "archiv"})
return out
# --------------------------------------------------------------------------- gitea sync
def ensure_labels(existing):
by_name = {l["name"]: l for l in existing}
for name, color in LABEL_COLORS.items():
if name in by_name:
continue
if COMMIT:
api("POST", f"/repos/{OWNER_REPO}/labels",
{"name": name, "color": color.lstrip("#")})
print(f" [{'+' if COMMIT else 'DRY'}] label {name}")
st, cur = api("GET", f"/repos/{OWNER_REPO}/labels?limit=100")
return {l["name"]: l["id"] for l in (cur if isinstance(cur, list) else [])}
def all_issues():
out, page = [], 1
while True:
st, d = api("GET", f"/repos/{OWNER_REPO}/issues?state=all&type=issues&limit=50&page={page}")
if not isinstance(d, list) or not d:
break
out += d
page += 1
return out
def main():
print(f"Gitea {HOST} repo {OWNER_REPO} mode={'COMMIT' if COMMIT else 'DRY-RUN'}")
st, existing_labels = api("GET", f"/repos/{OWNER_REPO}/labels?limit=100")
label_id = ensure_labels(existing_labels if isinstance(existing_labels, list) else [])
issues = all_issues()
by_tp = {}
open_nums = set()
for iss in issues:
# Titel ist "TPxx — …"; volle ID inkl. Buchstaben/Bindestrich (TP14.2a, TP-R) bis zum " — "
m = re.match(r"^(TP[\w.\-]*?)\s+—", iss["title"])
if m:
by_tp[m.group(1)] = iss
if iss.get("state") == "open":
open_nums.add(m.group(1)[2:])
# Aktive TPs sind seit dem TP36-Cutover SSoT direkt in Gitea -> nur das Archiv abgleichen,
# und offene (reopente) TPs davon ausschliessen, damit sie nicht faelschlich geschlossen werden.
items = parse_archiv(open_nums)
print(f"Geparst: {len(items)} archivierte TP (aktive TPs = SSoT in Gitea: "
f"{len(open_nums)} offen, nicht angetastet)\n")
created = updated = 0
for it in items:
status_label, state = MARKER.get(it["marker"], ("status:todo", "open"))
labels = [status_label]
th = THEME.get(it["num"])
if th:
labels.append(f"thema:{th}")
title = f"{it['tp']} — {it['title']}"
body = (f"Steuerungs-SSoT: Index/Status hier in Gitea; **Prosa/Detail** im Repo unter "
f"`docs/{'teilprojekte-archiv.md' if it['src']=='archiv' else 'teilprojekte.md'}` "
f"(Abschnitt `{it['tp']}`).\n\n"
f"- Status: {it['marker']} ({status_label})\n"
+ (f"- Abschluss: {it['date']}\n" if it["date"] else ""))
want_ids = [label_id[l] for l in labels if l in label_id]
cur = by_tp.get(it["tp"])
if cur is None:
print(f" [{'+' if COMMIT else 'DRY'}] NEW {title} {labels} state={state}")
if COMMIT:
sc, res = api("POST", f"/repos/{OWNER_REPO}/issues",
{"title": title, "body": body, "labels": want_ids})
if state == "closed" and isinstance(res, dict) and res.get("number"):
api("PATCH", f"/repos/{OWNER_REPO}/issues/{res['number']}", {"state": "closed"})
created += 1
else:
have = {l["name"] for l in cur.get("labels", [])}
drift = (have != set(labels)) or (cur.get("state") != state)
if drift:
print(f" [{'~' if COMMIT else 'DRY'}] UPD #{cur['number']} {title} "
f"{sorted(have)}->{labels} state {cur.get('state')}->{state}")
if COMMIT:
api("PATCH", f"/repos/{OWNER_REPO}/issues/{cur['number']}",
{"labels": want_ids, "state": state})
updated += 1
print(f"\n{'Angelegt' if COMMIT else 'Wuerde anlegen'}: {created} · "
f"{'Abgeglichen' if COMMIT else 'Wuerde abgleichen'}: {updated}")
if not COMMIT:
print("Dry-Run — nichts geschrieben. Mit --commit ausfuehren.")
if __name__ == "__main__":
main()

View File

@@ -47,7 +47,7 @@ gitea.emsenhuber.net {
# INTERN (Mesh/LAN; Split-Horizon zeigt diese Namen auf 10.40.20.40)
# =========================================================================
nautobot.bf.emsenhuber.net {
reverse_proxy http://10.40.20.30:8080
reverse_proxy http://10.40.20.154:8080
}
# grafana.emsenhuber.net — 2026-08-25 entfernt: LXC 104 war seit Langem gestoppt und stand

View File

@@ -104,7 +104,7 @@ def main():
continue
if host not in caddy:
drift.append(f"NUR-CF {host:<32} {tun}: {svc} (in Caddy nicht vorhanden)")
elif not svc.startswith(f"http://{CADDY_IP}"):
elif not (svc.startswith(f"http://{CADDY_IP}") or svc.startswith(f"https://{CADDY_IP}")):
drift.append(f"ABWEICHEND {host:<32} CF={svc} (zeigt nicht auf Caddy {CADDY_IP})")
# Caddy-Sites ohne CF-Ingress: nur die suffixlosen Namen sind potenziell Drift.
# *.bf.*-Namen sind bewusst intern (Split-Horizon) und brauchen keinen Ingress.

View File

@@ -19,12 +19,35 @@ if [ -z "${TOKEN}" ]; then
exit 1
fi
# 🔴 `pct push` meldet Exit 0 AUCH wenn es die Quelle nicht lesen kann
# ("failed to open <src> for reading", rc=0 — live gemessen 2026-09-21).
# Ein `&&`/`||` hinter dem Push beweist deshalb NICHTS, und die anschliessende
# `caddy validate` validiert dann die ALTE Datei -> gruene Abnahme bei
# unveraendertem Zustand. Genau so ist der Nautobot-Umzug am 2026-09-21
# scheinbar gelandet, obwohl live noch die alte Backend-IP stand.
# Deshalb: Push + md5-Vergleich in EINEM Remote-Aufruf, der bei Abweichung
# hart abbricht. Gepusht wird nur der lokal bekannte Pfad — die frueheren
# `\$\$`/`$$`-Verrenkungen waren der Ausloeser.
push_verified() { # push_verified <quelle-auf-pve> <ziel-im-ct> <perms> <label>
local src=$1 dst=$2 perms=$3 label=$4
ssh "${PVE}" "set -e
pct push ${CTID} '${src}' '${dst}' --perms ${perms}
want=\$(md5sum '${src}' | cut -d' ' -f1)
got=\$(pct exec ${CTID} -- md5sum '${dst}' | cut -d' ' -f1)
rm -f '${src}'
if [ \"\$want\" != \"\$got\" ]; then
echo \"FEHLER: ${label} nicht gelandet (\$want != \$got)\" >&2; exit 1
fi
echo \" ${label} verifiziert (\$got)\""
}
echo "-> Caddyfile"
scp -q "${HERE}/Caddyfile" "${PVE}:/tmp/.caddyfile.$$"
ssh "${PVE}" "pct push ${CTID} /tmp/.caddyfile.\$\$ /etc/caddy/Caddyfile --perms 644 2>/dev/null || pct push ${CTID} /tmp/.caddyfile.$$ /etc/caddy/Caddyfile --perms 644; rm -f /tmp/.caddyfile.$$"
push_verified "/tmp/.caddyfile.$$" "/etc/caddy/Caddyfile" 644 "Caddyfile"
echo "-> Token (maskiert: Laenge ${#TOKEN})"
printf 'CF_DNS_API_TOKEN=%s\n' "${TOKEN}" | ssh "${PVE}" "cat > /tmp/.cenv.$$ && chmod 600 /tmp/.cenv.$$ && pct push ${CTID} /tmp/.cenv.$$ /etc/caddy/caddy.env --perms 600 && rm -f /tmp/.cenv.$$"
printf 'CF_DNS_API_TOKEN=%s\n' "${TOKEN}" | ssh "${PVE}" "cat > /tmp/.cenv.$$ && chmod 600 /tmp/.cenv.$$"
push_verified "/tmp/.cenv.$$" "/etc/caddy/caddy.env" 600 "caddy.env"
echo "-> validate"
ssh "${PVE}" "pct exec ${CTID} -- sh -c 'set -a; . /etc/caddy/caddy.env; set +a; /usr/local/bin/caddy validate --config /etc/caddy/Caddyfile' 2>&1 | tail -3"

47
docs/announcements.md Normal file
View File

@@ -0,0 +1,47 @@
# Announcements — bf-infra
Breaking News / Querschnitts-Änderungen, die **jede** folgende Session kennen muss, bevor sie
losarbeitet — Dinge, die man sonst erst nach dem ersten Fehlschlag merkt. Kein Ersatz für die
TP-Prosa (`docs/teilprojekte.md`) oder das Gitea-Board; hier steht nur, was *quer* zu den TPs gilt.
**Format je Eintrag:** Überschrift `## YYYY-MM-DD — <Titel>`, dann die Zeilen
**Betrifft:** (wer/was) und **Aktion:** (was eine Session konkret anders machen muss),
optional ein, zwei Sätze Kontext. **Neueste oben.** Der Skill `/news` liest diese Datei und
zeigt die Einträge, die seit dem letzten `/news`-Lauf dazugekommen sind (Rest auf Wunsch).
<!-- TP35 Schicht 4. Eintrag hinzufügen = neuen ##-Block ganz oben unter dieser Zeile einfügen. -->
---
## 2026-09-12 — Golden-Config-Backups laufen jetzt täglich (vorher KEIN Scheduler)
**Betrifft:** alle, die sich auf GC-Backups/Compliance oder `gc-snapshot.py`-Werte verlassen.
**Aktion:** Es gab **nie** einen automatischen GC-Backup-Zeitplan — Backup/Intended/Compliance liefen
nur manuell aus Sessions (zuletzt 09-04 → 8 Tage Stillstand). Jetzt ScheduledJob **„GC Backup+Compliance
– taeglich"** (Nautobot, *Execute All GC Jobs - Multiple Device*, `platform=RouterOS`, täglich 03:30 UTC,
Reihenfolge Backup→Intended→Compliance). Wenn `backup_last_success_date` eines Geräts alt ist: zuerst
prüfen, ob der ScheduledJob noch `enabled` ist (`/api/extras/scheduled-jobs/`), nicht das Gerät verdächtigen.
## 2026-09-12 — claude.json-Secrets laufen über `{env:}` (TP35 Schicht 2 ✅)
**Betrifft:** alle, die `~/.claude.json` oder `~/.secrets/exports.zsh` anfassen.
**Aktion:** Keine Klartext-Secrets mehr in `~/.claude.json` — MCP-Credentials referenzieren jetzt
`{env:MCP_*}` (dieselben Namen wie `opencode.jsonc`, bidirektional kompatibel). SSoT ist
`~/.secrets/exports.zsh` (25 Vars). Nach jeder Änderung dort: `~/dev/.bin/gui-env-sync.sh`
**und App-Neustart** (laufender Prozess erbt die launchd-Umgebung nicht). ⚠ `~/.claude.json` nie aus
einer **laufenden** Session editieren — Claude Code schreibt dort State, der Edit würde überschrieben;
der Flip läuft bei beendeter App über `~/dev/.bin/schicht2-claude-json-migrate.py --apply-claude`.
## 2026-09-12 — TP36-Live: Gerätedaten stehen als CustomFields in Nautobot
**Betrifft:** alle, die Geräte-Ist-Werte (RouterOS-Version, Compliance %, DHCP-Server-Zahl,
DNS-Modus, Mgmt-IP) brauchen.
**Aktion:** Nicht mehr aus der Prosa ablesen und nicht raten — die fünf Felder (`grouping: TP36-Live`)
hängen an den 5 RouterOS-`dcim.Device` in Nautobot. Aktualisieren: `python3 nautobot/gc-snapshot.py
--commit` (liest nur aus Nautobot/GC, kontaktiert kein Gerät). Die Werte sind so aktuell wie das
letzte Golden-Config-Backup (`backup_last_success_date` am Gerät).
## 2026-09-07 — SSoT-Cutover: Index/Status = Gitea, NICHT mehr teilprojekte.md
**Betrifft:** jede Session, die einen TP-Status ändert, anlegt oder abschließt.
**Aktion:** Status/Reihenfolge/„was lief zuletzt" gehen ins **Gitea-Issue**
([`admin/bf-infra`](https://gitea.emsenhuber.net/admin/bf-infra/issues), Labels `status:*`/`thema:*`),
**nicht** in eine Tabelle in `docs/teilprojekte.md`. Die Datei trägt nur noch die `### TPnn`-Prosa.
`/projektstatus` liest Baum + Status aus der Gitea-API. Branch `tpNN-kurz` jederzeit möglich, Merge
nach `main`, sobald Code/Config steht.

View File

@@ -2,15 +2,39 @@
> 🆕 **SSoT-Wechsel im Aufbau (TP44, seit 2026-09-02):** Die CF-Estate (Tunnel, WARP-Connector,
> VPC-Services, Hyperdrive, Workers, Access-Apps) wird als **native `nautobot.cloud`-Objekte** in
> Nautobot (`10.40.20.30`) geführt — Etappe 1 (manuelle Erstbefüllung) ✅. Seeder:
> `nautobot/tp36-cf-estate-seed.py`, Detail: `docs/handoff-20260902-cf-estate-nautobot-ssot.md`.
> Nautobot (`10.40.20.154`, TP45 Schicht A 2026-09-21; vorher `.30`) geführt — Etappe 1 (manuelle Erstbefüllung) ✅. Seeder:
> `nautobot/tp44-cf-estate-seed.py`, Detail: `docs/handoff-20260902-cf-estate-nautobot-ssot.md`.
> **CF bleibt operativer Master, Nautobot = Dokumentations-SSoT.** Dieses File bleibt gültige Historie
> und As-Built-Log; die *strukturierte* Estate liest man ab jetzt in Nautobot. Etappe 2 (CF-API→Nautobot-Sync)
> ist offen.
> **Aktueller Stand: → §10 (2026-07-10, TP16 UMGESETZT ✅).** §9 = Analyse/Zielbild, §10 = As-Built.
> Abschnitte 1–8 sind Historie (Track A, 2026-06-30); die „3 Connectors gut/Zielbild"-Aussagen dort sind
> durch §9/§10 **überholt** (Round-Robin = macvlan-Host-Isolation → 1/N-Ausfälle). Track A aus `docs/handoff-cf-tunnel-1033.md`.
> **Aktueller Stand: → §0 (unten).** §1–16 sind Historie/As-Built-Log früherer Sessions und beschreiben
> Topologien, die **nicht mehr live** sind (v.a. das 3-Tunnel-HA `bf-mm`/`bf-nas`/`bf-pve`). §9 = Analyse,
> §10–15 = As-Built des inzwischen abgelösten 3-Tunnel-Designs. Track A aus `docs/handoff-cf-tunnel-1033.md`.
## §0 — Live-Ist-Stand (2026-09-08, maßgeblich)
> Der einzige aktuelle Topologie-Stand. **§1–16 nicht als aktuelle Konfiguration lesen** — insbesondere das
> 3-Tunnel-HA `bf-mm`/`bf-nas`/`bf-pve` (§10–15) existiert seit dem TP16.3-Cutover (bf-public/Caddy,
> 2026-08-27) **nicht mehr**. Strukturierte Estate = Nautobot (TP44, deckt sich mit diesem Stand);
> operativer Master = Cloudflare. Read-only gemessen gegen die CF-API (`cfd_tunnel`, `warp_connector`,
> `teamnet/routes`) am 2026-09-08.
**cloudflared-Tunnel (live) — es gibt genau drei:**
| Tunnel | ID | Conns | Zweck |
|---|---|---|---|
| **bf-public** | `48d3b0b6-7233-4781-a76a-1de4a5e957ce` | 2, healthy | **einziger öffentlicher BF-Tunnel** (TP31/TP16.3), erstellt 2026-08-27 |
| **fm.emsenhuber.net** | `b697d124-53bf-4a33-8fcf-384cced4db1a` | 1, healthy | Standort FM (`ds-fm`, `gateway-fm`), separat |
| **terpene-db** | `f2d2fc8a-54ae-41df-b09a-97312cdb9fe2` | 1, healthy | DB-Pfad (Hyperdrive→VPC-Service), Rebuild 2026-09-01 — s. §17 |
**bf-public-Ingress** → alle vier auf **Caddy `10.40.20.40:443`** (Caddy macht das Fan-out), catch-all 404:
`vw` · `hass` · `n8n` · `gitea` (`.emsenhuber.net`).
**WARP / Private Access — nativer Mesh, KEIN cloudflared:**
- warp_connector **bf-core-mesh** `d1da7c8a-2736-4cbb-8af1-32db5393fb9c`, healthy — nativer
WireGuard-Mesh-Node auf dem Core (TP16.1). **Live und produktiv** (nicht mehr „gated/Konzept" wie in §14).
- Routen: `10.40.0.0/16` → **bf-core-mesh** · `10.101.0.0/24` → **fm**. Ein vnet `vnetemsenhuber` (default).
## 1. Alle Tunnel im Account (`393c…66c36`)
| Tunnel | ID | Status | Conns | Verwendung |
@@ -234,6 +258,9 @@ Der macmini ist vollwertiger dritter Knoten (nicht „vergessen").
---
<details>
<summary>🗄️ <b>ARCHIV (§10–16)</b> — überholtes 3-Tunnel-HA <code>bf-mm</code>/<code>bf-nas</code>/<code>bf-pve</code>. Seit dem TP16.3-Cutover (2026-08-27) nicht mehr live — siehe §0. Aufklappen nur für die Historie.</summary>
## 10. AS-BUILT 2026-07-10 (TP16 umgesetzt) — reziprokes 3-Tunnel-HA ✅
> Gebaut & verifiziert in eigener Session. Round-Robin-#1033 **strukturell weg** (Loop-Gegentest 0×530 über alle 19 Live-FQDNs, HA per Host-Ausfall-Sim bewiesen). Schritte 1–4+HA durch; **Schritt 5 (Access/WARP + `vw`) offen** (user-gated).
@@ -337,6 +364,10 @@ Letzte in §9.2/§8 als „bleibt `.41`" geführte Origin-Klasse (`pve .41.100`,
## 14. Richtungsentscheid 2026-07-16 — Private Access via native Cloudflare Mesh (WARP Connector) auf dem CRS326 Core-Switch (TP16.1)
> ✅ **Nachtrag 2026-09-08 (live):** umgesetzt. warp_connector **bf-core-mesh** (`d1da7c8a-…`) ist healthy
> und trägt die Route `10.40.0.0/16` — der „Scharfschalten = eigene Session, gated"-Status unten ist
> überholt. Siehe §0.
> ✅ **Update 2026-07-22 (User-Entscheid):** Ziel-Device retargeted von **ap1** auf den **CRS326 Core-Switch** — konsistent mit TP15-Endstand (kein RB5009, Router bleibt ap1/ap2) und TP21s Kabel-Fabric-Modell. Reine Ziel-Doku-Änderung, Scharfschalten bleibt gated bis TP21 den CRS326 abdeckt. Der Rest dieser Sektion ist entsprechend auf den neuen Zielhost umgeschrieben; CRS326 ist aktuell noch Werkszustand, Management-IP/Interface TBD.
**Trennung der Concerns (wichtig):**
@@ -452,6 +483,8 @@ Netzwerk-Namespace, sieht ohnehin alles), und die cloudflared-Connectoren laufen
eigene Maschinen, auf denen die Blindheit prinzipiell nicht auftreten kann. Der Shim bleibt als Option
für den Fall, dass später doch ein Dienst neben macvlan-Nachbarn einziehen soll.
</details>
## 17. Terpenfinder-DB-Pfad neu aufgebaut 2026-09-02 (Fremdprojekt-Handout blaueblüten)
**Auslöser:** Handout `blaueblueten-n8n/docs/handout-bf-infra-db-pfad-20260902.md` — der Cloudflare-Worker

View File

@@ -82,7 +82,7 @@ terpene.teilzeitladen.xyz {
"type": "http",
"url": "https://n8n-mcp.emsenhuber.net/mcp",
"headers": {
"Authorization": "Bearer 47a34f5589388d37d8b7503abac07b930df264c469ef0674aaeeea9b71dde847"
"Authorization": "Bearer <redacted>"
}
}
```

View File

@@ -41,10 +41,10 @@ Manufacturer "Cloudflare"
## Werkzeug
`nautobot/tp36-cf-estate-seed.py` — **idempotenter** Seeder (get-or-create), Datenstand als Inline-Struktur.
`nautobot/tp44-cf-estate-seed.py` — **idempotenter** Seeder (get-or-create), Datenstand als Inline-Struktur.
Token aus `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored). Aufruf: Dry-Run default,
`--commit` schreibt. Re-Run = 26/26 „existiert".
*(Dateiname trägt noch `tp36`-Präfix aus dem ersten Arbeitsstand; inhaltlich TP44. Umbenennen bei Gelegenheit.)*
*(Datei am 2026-09-06 von `tp36-…` auf `tp44-cf-estate-seed.py` umbenannt — Präfix jetzt korrekt.)*
## Gotchas (für Etappe 2 / Folgesessions)
@@ -54,15 +54,17 @@ Token aus `docs/nas-vlan20/stacks/210-nautobot.yml` (gitignored). Aufruf: Dry-Ru
- VPC-Service-API liegt unter `connectivity/directory/services` (Update = **PUT**, voller Body), nicht `/vpc/`.
- Der Repo-`CF_API_TOKEN` darf `cfd_tunnel`, aber **nicht** Workers-VPC (`connectivity/directory`) — dort
über den `cloudflare`-MCP-Credential gehen.
> ⚠️ **ÜBERHOLT (2026-09-11):** falsch. Live getestet liest der `CF_API_TOKEN` aus
> `~/.secrets/credentials.env` Hyperdrive/VPC/Workers (alle 200) — der schmale ist `CF_DNS_API_TOKEN`.
> Der Teil-B-Sync deckt damit 14/14 ab. Details: `handoff-20260910-tp44-teilb-sync-live.md`.
## Offen (Etappe 2, eigene Session)
1. **CF-API→Nautobot-Sync** (Python/n8n): Inline-Daten im Seeder durch Live-Pull ersetzen, periodisch
(analog golden-config-bot). Dann ist Nautobot driftfrei.
2. **TP44 in `teilprojekte.md`** eintragen (Quick-Index + Abschnitt + Ist-Stand), sobald die dortigen
fremden Änderungen committet/geklärt sind.
2. ✅ **TP44 in `teilprojekte.md`** eingetragen (Quick-Index + Abschnitt + Ist-Stand) — 2026-09-06.
3. IPAM-Prefixe `10.40.0.0/16` + `10.101.0.0/24` anlegen → dann greifen die Prefix-Assignments automatisch.
4. Seeder-Datei nach `tp44-…` umbenennen.
4. ✅ Seeder-Datei nach `tp44-cf-estate-seed.py` umbenannt — 2026-09-06.
## Verifikation (2026-09-02)

View File

@@ -0,0 +1,57 @@
# Handoff 2026-09-02 — TP25 Fund E: die Abschlussmessung, und was sie entschieden hat
**Kurz:** Die für heute früh vorgemerkte Messung ist gelaufen. **7.24.1 hat den
`reauthenticating`-Sturm aufgelöst, nicht `ft-over-ds`.** Hebel 1 war widerlegt und ist zu Recht
zurückgebaut; Hebel 2–4 entfallen. **Fund E ist geschlossen** — ohne Geräte-Write.
## Was Fund E war
Ein `reauthenticating`-Sturm, sauber isoliert auf **einen** Client (iPhone
`F2:62:4C:E1:AF:09`) und **eine** SSID (`dirtyvader-main`, die einzige mit
`ft=yes ft-over-ds=yes`). Baseline: 93/93 auf genau diesem Client und dieser SSID. Hebel 1
(`ft-over-ds=no`) lief am 31.08. **6,4 h allein** und machte es **schlimmer** (124 ≈ 19/h + 2
erlebte Ausfälle) → am 01.09. zurückgebaut, Transaktion `TP25-fund-e-ft-over-ds` geschlossen.
Der Einbruch auf ~0/h fiel exakt auf das **TP27-Upgrade 7.24.1** (Core-Reboot 31.08. 14:36).
## Vorbedingung zuerst (CLAUDE.md-Gotcha: „grep caps + uptime vor Client-Diagnose")
- Core-Uptime **1d18h** → letzter Reboot 31.08. 14:36; **kein** Reboot am 01./02.09.
- `caps joined = 0` an beiden Tagen.
- ⇒ Die Zahlen unten sind echte Client-Ereignisse, keine Reboot-Artefakte.
## Messung (Kollektor `/opt/tp5-syslog/log/10.40.20.1/`, via pve→`pct exec 400`)
| Tag | reauth total | davon iPhone F2:62 | distinct MACs | data loss / deauth | Kontext |
|---|---|---|---|---|---|
| 08-31 | 225 | 218 | 6 | (Upgrade+Hebel1) | Hebel-1-Fenster + 2 Upgrade-Reboots |
| 09-01 | 44 | 40 | 4 | 0 | 7.24.1, Hebel 1 mittags zurückgebaut |
| **09-02** (00:00–08:37) | **4** | **4** | **1** | **0** | 7.24.1 + `ft-over-ds=yes`, sauberes Fenster |
- **218 → 40 → 4.** Am 09-02 vier isolierte Einzelereignisse (01:13, 02:00, 03:14, 08:01),
**kein Burst**, alle `dirtyvader-main` (Interface `cap-wifi3`/`cap-wifi6` — die `cap-wifiN`-Karte
wandert, deshalb NICHT einem AP zugeschrieben). ≈ **0,46/h** gegen Baseline 93 bzw. Hebel-1 **19/h**.
- Der iPhone ist **präsent und stabil** — er verbindet und erzeugt die 4 Zeilen, ist also nicht
„still, weil abwesend".
- Die 97 `association rejected` am 09-01 fallen auf den **Rollback-/Re-Provisioning-Vorgang**
(viele MACs = Infrastruktur, per Gotcha), nicht auf einen Client; am 09-02 nur 5.
## Schluss & Entscheidung
**7.24.1 war die Ursache/der Fix, nicht `ft-over-ds`.** Der Restwert (~0,5/h isolierte
Einzel-Reauth eines iPhones, 0 Ausfälle) ist normales iOS-Roaming, kein Defekt.
**Hebel 2–4 (`ft=no`, `2g-probe-delay`, `signal-range`) werden NICHT gezogen. Fund E geschlossen.**
Kein Geräte-Write: Sollzustand steht bereits (`sec-main` = `ft=yes ft-over-ds=yes`, Flotte 7.24.1,
Transaktion `zurueckgebaut`, Compliance **140/140**).
## Bleibt offen (nicht Fund E)
- **ap2 unterperformt** (2 m / −80 dBm, 23:02-Befund) — eigener In-situ-Unterpunkt in TP25,
kein FT-/Auth-Thema. TP25 bleibt deshalb als Sammel-TP offen.
## Merkregel bestätigt
Der Fall ist ein Lehrstück für zwei CLAUDE.md-Regeln: (a) **Reboots zuerst ausschließen** hätte am
31.08. verhindert, den Upgrade-Reboot-Burst für Client-Instabilität zu halten; (b) **eine Drift/ein
Symptom im offenen Versuch sieht aus wie ein Defekt** — Hebel 1 „verbesserte auf 0/h" war in
Wahrheit das parallele Upgrade. Die einzelne Messung nach dem Rückbau hat beides getrennt.

View File

@@ -0,0 +1,113 @@
# Handoff 2026-09-03 — TP25/TP28: Kanalplan live, In-situ-Messung offen
**Kurz:** ap1 haengt jetzt am Sideboard (Trunk auf `ether3`), der TP25-Kanalplan ist am
Manager gesetzt (**ap1 5260/5280 + ch1**, **ap2 5300/5320 + ch11**, **ap3 5180 + ch6**),
und alle drei APs funken. 35 Clients an der Registration-Table (vorher 30, +5 auf ap1).
**Was fehlt: die In-situ-Messung** — Aufstellorte begehen und entscheiden, ob der Zustand
Zielzustand wird (dann Template + Commit der Akte) oder ob nachjustiert werden muss.
## Was am 03.09. live gesetzt wurde
L2 auf `crs326-core`:
- `ether3` als AP-Trunk fuer ap1 (analog `ether15`/`ether21`) — Template gepflegt
- Akte `TEST-ether3-trunk-ap1-sideboard-2` (Scope `bridge-vlan`, `state=committed`,
expires 2026-09-10)
WLAN am Manager (`crs326-core`):
- `ch-5g-ap1`: 5180 → **Frequenz-Liste 5260,5280** (DFS Band B, ch52/56)
- `ch-5g-ap2`: 5220 → **Frequenz-Liste 5300,5320** (DFS Band B, ch60/64)
- Zwei Provisioning-Regeln fuer ap1 neu (radio-mac `E5`=5G, `E6`=2G) — analog ap2/ap3
- `remote-cap provision` auf ap1 und ap2 gefahren
- Akte `TP25-kanalplan-ap1-live` (Scope `wifi-channel`, `state=open`, expires 2026-09-10)
Live-Verifikation:
- ap1: 9/9 Interfaces `running=true` am CAP (Manager-Anzeige `running=false` ist der bekannte
Post-Reprovisioning-Gotcha, s. CLAUDE.md — Wahrheit am CAP)
- ap2: 9/9 Interfaces `running=true`
- ap3: unveraendert
- 35 Clients (vor Aenderung 30)
## Was fuer die naechste Session zu tun ist
**Fokus = messen, nicht nachjustieren, bis die Aufstellorte belegt sind.**
Zwei offene Frage aus TP25/TP28, die vor Ort beantwortet werden muessen:
1. **Aufstellort ap1 (Sideboard)** — Abdeckung akzeptabel? Vorher stand ap1 im Technik UG, jetzt
am Sideboard (Test). Signal in den Ecken (Terrasse, Bad, hintere Zimmer) messen.
2. **ap2 unterperformt** (TP25 Rest-Punkt, In-situ 2 m/−80 dBm am 08-31). Vermutung: RF/Antenne/HW,
moeglicherweise auch nur `ch149`-Leistungsproblem (jetzt weg, 5300 statt 5220). Die
Kanalaenderung koennte das Symptom bereits behoben haben — deshalb **zuerst neu messen**,
bevor man an Antennen oder Hardware denkt.
## Aufstellorts-Messplan (Vorschlag, bewusst knapp)
Pro Standort (Wohnzimmer, Kueche, Bad, Terrasse, Schlafzimmer, Technik UG):
- Signal in dBm auf `dirtyvader-main` (5 GHz) mit App am Handy
- Welcher AP wird ausgewaehlt (BSSID am APx-Radio abgleichen — s. Manager-Registration-Table)
- Kurz eine Datei ziehen (SpeedTest oder `iperf3` gegen `10.40.20.10`), damit reale Throughput-
Zahl da ist, nicht nur RSSI
- 2,4 GHz nur pruefen, wenn das 5-GHz-Signal an dem Standort schlecht ist (< −75 dBm)
Am Manager parallel:
- `/interface wifi registration-table print terse where ssid=dirtyvader-main` — Signal/Rate live
- `/interface wifi radio print` gibt aktuelle Frequenz je Radio (5260 vs 5280, 5300 vs 5320 —
DFS hat einen der beiden gewaehlt)
## Gotchas fuer die Messsession (aus CLAUDE.md)
- **`/interface wifi scan` NUR am Manager**, nicht am CAP (`not allowed`).
- **Registration-Table NUR am Manager** — am CAP leer.
- **`cap-wifiN`-Karte wandert bei jedem Rejoin.** Vor der Auswertung eines Ereignisses
`/interface wifi radio print terse proplist=cap,radio-mac,interface` am Manager lesen; wenn
zwischen Ereignis und Auswertung ein Rejoin liegt, Zuordnung als **unbekannt** behandeln.
- **`list_wifi_interfaces` leakt PSKs** — nicht benutzen; stattdessen
`/interface wifi radio print` bzw. `/interface wifi print terse where master=yes proplist=...`.
- **Ein `caps,info`-Burst ist Infrastruktur, ein Client-MAC-Burst ist ein Client** — vor jeder
Client-Diagnose `/system resource get uptime` am Core lesen und `grep " caps,"` im TP5-Log.
- **DFS-CAC** dauert beim ersten Einschalten eines DFS-Kanals ~60 s. Bei einem Radar-Event
wechselt der Kanal automatisch auf den Zweitwert (5260↔5280 bzw. 5300↔5320) — deshalb steht
im Channel-Objekt eine **Liste**, kein Einzelwert.
## Rollback (falls die Messung schlecht ausfaellt)
Der Snapshot `docs/transaktionen/TP25-kanalplan-ap1-live.snapshot.rsc` haelt den Vorher-Zustand
(ap1=5180, ap2=5220, keine ap1-Provisioning-Regeln). Rollback per:
```
python3 nautobot/gc-transaktion.py rollback --change-id TP25-kanalplan-ap1-live
```
Der Trunk auf `ether3` (physischer Umbau) muss separat via
`TEST-ether3-trunk-ap1-sideboard-2` behandelt werden.
## Commit-Weg (falls die Messung gut ausfaellt)
Zwei Sachen ins Template `nautobot/mikrotik_routeros.j2`:
1. Zeilen 206–207: `frequency=5180`/`5220` → Frequenz-Listen `5260,5280`/`5300,5320`
2. Nach den bestehenden Provisioning-Zeilen fuer ap2/ap3 die zwei ap1-Regeln einfuegen
(radio-mac `D0:EA:11:4D:40:E5` = 5G, `D0:EA:11:4D:40:E6` = 2G) — Slave-Set analog ap2/ap3
Danach:
```
python3 nautobot/gc-transaktion.py commit --change-id TP25-kanalplan-ap1-live
```
Skript verweigert den Commit, solange die SoT nicht nachgezogen ist — der Ablauf funktioniert
nur in dieser Reihenfolge.
## Ein-Scope-Grenze der Akte (wichtig, wenn Compliance-Status gelesen wird)
Die Akte deckt formell **nur `wifi-channel`**. Die zwei ap1-Provisioning-Adds fallen unter
`wifi-provisioning` — das begin-Skript erlaubt aber **nur eine offene Akte je Geraet** (Regel 3).
Deshalb steht im `commands.rsc` der Akte ein Header, der beides zusammenfuehrt. Im naechsten
Compliance-Run wird `wifi-provisioning` als „fremd" (nicht durch die aktive Akte gedeckt)
gemeldet werden — das ist **erklaerbarer, nicht undokumentierter Drift**. Beim Commit gehoert
BEIDES ins Template.
## Aufraeumkandidat, wenn alles glatt geht
- TP25-Ist-Stand-Block: Punkt „ap2 unterperformt" als geloest markieren (falls Messung das
bestaetigt).
- TP28-Ist-Stand-Block: „ap1 funkstill" ausbauen — ist mit 09-03 erledigt.
- Quick-Index-Zeile TP25 kann bei erfolgreichem Commit auf `✅` gesetzt werden.

View File

@@ -0,0 +1,70 @@
# Handoff 2026-09-04 — TP25: Klick-Konsole auf N Clients + Pin-UI
**Kurz:** Die Klick-Konsole (`docs/tp6-marker/server.py`, Port 3031) war beim Multi-Pin-Umbau
(2026-09-04, `tp25-pin-multi.sh` + `TP25_PHONES`) **nicht** mitgezogen worden — sie zeigte weiter
hartkodiert zwei Clients (iPhone/S22) und pinnte ueber die alte Gegen-AP-Automatik. Jetzt ist sie
auf **N Clients** generalisiert und hat eine **Pin-UI**: Signal/AP/Ping-Verlust je Client live,
Pinnen band-genau direkt in der Konsole. Die alte 2-Client-Automatik ist entfernt.
## Was umgebaut wurde
`docs/tp6-marker/server.py` (Hauptumbau):
- **Client-Liste aus Datei statt hartkodiert:** `geraete()` liest `geraete.txt` aus dem
Laufverzeichnis (schreibt `tp25-walk-messung.sh`, eine Zeile `name|ip|mac` je Client). Fallback
auf die zwei alten MACs fuer Alt-Laeufe.
- **Kein eigenes SSH mehr in der Konsole:** der `beobachter()`-Thread (2 MACs per SSH,
`beide-telefone.csv`) ist raus. Stattdessen liest die Konsole je Client die **letzte Zeile** von
`sampler-<name>.csv` (`sta_iface`, `sta_signal`) und den **juengsten Ping-Verlust** aus
`walk-ping-<name>.csv` (leeres `ms` = Verlust). Eine SSH-Session weniger gegen den Core-SPOF.
- **N Client-Karten** statt der festen iPhone/S22-Zeile: Name, AP (via `ap_map()`), Signal dBm,
Ping-Verlust der letzten ~30 s. **Alarm**, wenn ein **gepinnter** Client `sta_iface == "absent"`
ist → „<name> HAENGT NIRGENDS — nicht weitergehen" (Nachfolger des alten S22-Alarms).
- **Pin-UI** (Karte „Pinnen (Multi-Pin)"): je Client ein `<select>` mit `frei` / `apX/5GHz` /
`apX/2,4GHz` (Ziele aus `ap_map()` abgeleitet) plus drei Aktionen:
- **„Pin setzen"** → baut `TP25_PINSPEC="name|mac|ap|band;…"` aus den Nicht-`frei`-Auswahlen und
ruft `bash docs/tp25-pin-multi.sh set` im Thread.
- **„Pin loesen"** → `bash docs/tp25-pin-multi.sh off`.
- **„verify"** → `bash docs/tp25-pin-multi.sh verify`, Ausgabe als Statuszeile.
Neuer Endpunkt `POST /pinmulti` (analog zum alten `/pin`).
- **Entfernt:** `IPHONE_MAC`/`S22_MAC`, `_live`/`_auto`, `entscheide()`, `pin_lesen()`/
`pin_setzen()` (via `tp25-pin-s22.sh`), die ap1/ap2/auto-Buttons und der `PIN_SH`-Aufruf.
`tp25-pin-s22.sh` bleibt als Skript erhalten (liefert `map`), wird aber von der Konsole nicht
mehr zum Pinnen aufgerufen.
`docs/tp25-runde.sh`:
- `aufraeumen()` loest jetzt `tp25-pin-multi.sh off` statt `tp25-pin-s22.sh off` (Kommentar
angepasst: die Konsole pinnt nicht mehr automatisch).
## Bedienung (Messablauf)
```
bash docs/tp25-runde.sh [name] # Konsole (3031) + Messung, Adresse fuer das Telefon
```
1. Am Telefon die Konsole oeffnen, einmal irgendwo tippen (schaltet den Signalton frei).
2. In der Konsole **pinnen**: je Client AP/Band waehlen, „Pin setzen". Clients ohne Ziel bleiben
frei (das Skript raeumt vorher alle `TP25-PINM-*`-Regeln ab).
3. Losgehen. 🚶 beim Losgehen, 📍 beim Stehenbleiben, Raum antippen. Alarm = ein gepinnter Client
haengt nirgends.
4. „⏹ Aufzeichnung stoppen" (oder Ctrl-C im Terminal). Der Wrapper loest den Multi-Pin beim Beenden.
Auswertung: `python3 docs/tp25-gehweg-auswertung.py --dir docs/messdaten/tp25-runde-<name>`
## Was noch offen ist (braucht die Geraete vor Ort)
- **Live-Test mit N Geraeten im Netz** (Plan-Verifikation Schritt 3): `TP25_PHONES="…" bash
docs/tp25-runde.sh test` → N Karten sichtbar, pinnen → `bash docs/tp25-pin-multi.sh verify` zeigt
die Regeln, gehen/Raeume/stoppen → Auswertung liefert die Raumtabelle mit N Geraeten.
- **Aufraeumen** (Schritt 4): nach dem Lauf `bash docs/tp25-pin-multi.sh off` — keine
`TP25-PINM-*`-Regeln am Manager zurueck.
Statisch verifiziert (ohne Geraete): AST-Parse ok, keine stale Referenzen auf die alte Automatik,
Smoke-Render mit 2 Test-Clients ok, `bash -n` auf allen drei Shell-Skripten ok.
## Gotchas (unveraendert, aus CLAUDE.md)
- **`cap-wifiN`-Karte wandert bei jedem Rejoin** — `tp25-walk-messung.sh` friert sie als
`ap-map.txt` im Messlauf ein; die Konsole beschriftet daraus.
- **Registration-Table nur am Manager** — die Sampler (`tp6-monitor-core.sh`) fragen den Core ab,
nicht die CAPs.
- **`sshpass -e`, nie `-p`** — gilt weiter fuer alle Skripte, die den Core ansprechen.

View File

@@ -0,0 +1,127 @@
# Handoff 2026-09-06 — Plan TP37 (P1+2) → TP34, TP36 parallel
> **Sessiontyp:** „erst planen, nichts bauen" (User-Entscheid 2026-09-06). **Kein Nautobot-Write.**
> Dieses Dokument ist der verzahnte Runbook für die drei nachfolgenden Build-Sessions.
> Datenmodell-Entscheid: **native Nautobot-Modelle, keine eigene App** (konsistent zu TP44).
## 1. Ausgangslage — live gegen die API gelesen (2026-09-06)
| | Wert | Bedeutung |
|---|---|---|
| Nautobot | `http://10.40.20.30:8080`, v3.1.7 | Apps: **Golden Config 3.0.7 + Nornir** (cloud-Modelle sind Core) |
| Devices | 9 | 4 aktive MikroTik + decommissioned/Rest — in Build-Schritt 0 verifizieren |
| **VirtualMachines** | **0** | TP37 P1 offen |
| **Clusters** | **0** | TP37 P1 offen |
| **ipam.Service** | **0** | TP37 P2 offen |
| **CustomFields** | **0** | TP36 offen |
| Relationships / Tags | 0 / 0 | — |
| `cloud.*` (Account/ResType/Network/Service) | 1 / 6 / 4 / 14 | ✅ **TP44 Etappe 1** — CF-Estate steht |
**Kernbefund:** TP37 **Punkt 3 (CF-Connectoren) ist durch TP44 erledigt** (native cloud-Modelle). Echt
offen bleibt das **Substrat** (P1) und die **Dienste** (P2) — und genau darauf sitzt TP34.
## 2. Entscheidungen (User, 2026-09-06)
1. **Erst planen, nichts bauen** — diese Session schreibt nichts nach Nautobot.
2. **Native Modelle** — `virtualization.Cluster/VirtualMachine` + `ipam.Service`, **keine eigene App**.
3. **TP44-Doku aufgeräumt** — Quick-Index-Zeile + Abschnitt in `teilprojekte.md`, Seeder
`nautobot/tp36-…` → `tp44-cf-estate-seed.py` umbenannt.
## 3. Reihenfolge / Abhängigkeit (korrigiert)
```
TP37 P3 (CF-Connectoren) ─── ✅ ERLEDIGT via TP44 ───┐
│ gleiche native-Modell-Linie
TP37 P1 (Hosts/Container → VirtualMachine) │
└─► TP37 P2 (Dienste → ipam.Service) ─► TP34 (Caddyfile via GC)
TP36 (CustomFields auf den 4 Devices + Datei-Split) ── ∥ unabhängig, jederzeit parallel
```
**Grund für die Unabhängigkeit von TP36:** seine Live-Daten-CustomFields hängen an den **bestehenden
`dcim.Device`**, nicht an neuen VM/Service-Objekten. TP34 dagegen kann ohne die Backend-`ipam.Service`
aus P2 nichts rendern → **TP37 vor TP34** bleibt zwingend.
---
## 4. TP37 Punkt 1 — Substrat: Hosts + Container als VMs
**Modell-Mapping (nativ):**
- `virtualization.ClusterType`: `Proxmox VE`, `Synology Docker`, `Docker Desktop`.
- `virtualization.Cluster`: `pve`, `nas-bf`, `macmini` (je einer, passender ClusterType).
*(Die physischen Hosts als eigene `dcim.Device` sind **optional** und kommen frühestens in einer
Etappe 2 — für den Doku-SSoT reicht der Cluster als Gruppierung. Empfehlung: Etappe 1 ohne Host-Devices.)*
- `virtualization.VirtualMachine` je Workload, mit `cluster` + `primary_ip4`:
- **pve:** alle LXCs (u.a. `platform-pg` 105/`.20.20`, Docker-LXC 400/`.20.126`, `mcast-relay` 108,
influxdb, MariaDB 302/`.20.23`, …).
- **nas-bf (DS923, Portainer ep14):** Nautobot-Stack-Container, ggf. Caddy/weitere.
- **macmini (Docker Desktop):** `n8n`/`n8n-redis`/`n8n-mcp`/`gitea-mcp` + terpene-Worker `:8890`.
**Build-Schritt 0 (read-only Inventur, BEVOR geseedet wird):** je Host die Workloads mit Name, Rolle,
primärer IP enumerieren — `pct list` + `pct config <id>` über **pve-mcp**, Portainer-API (ep14) für die
NAS, `docker ps` auf dem macmini. Ergebnis in eine **Inline-Datenstruktur** (Muster: `tp44-cf-estate-seed.py`)
→ idempotenter Seeder `nautobot/tp37-substrat-seed.py` (get-or-create, Dry-Run default, `--commit`).
## 5. TP37 Punkt 2 — Dienste als `ipam.Service`
- Je exponiertem Port ein `ipam.Service`, an die VM (bzw. später das Device) gebunden, das ihn betreibt:
Caddy `:80/:443`, AdGuard `:53` (bf1/bf2), Nautobot `:8080`, n8n `:5678`, HA `:8123`, Portainer `:9443`,
`pve-mcp :3000`, gitea, Vaultwarden, …
- **Quelle ohne Raten:** die Ports stehen in `CLAUDE.md` (Hardware/Tooling) **und** in den
`extra_config.origin/port`-Feldern der TP44-`CloudService`-Objekte — gegeneinander abgleichen.
- Idempotenter Seeder `nautobot/tp37-dienste-seed.py`.
## 6. 🔴 Auflage: Compliance-Gegenprobe (aus TP37 selbst)
Nach P1+2 **muss** `python3 nautobot/gc-transaktion.py status` bzw. `gc-configplan.py --refresh-compliance`
zeigen, dass die Geräte-Compliance **unverändert 140/140** ist. VMs/Services hinzuzufügen darf die
Golden-Config-Pipeline der 4 MikroTik **nicht** berühren. P1 und P2 sind je ein **abnehmbarer** Schritt
mit dieser Gegenprobe danach — nicht als Nebeneffekt von etwas anderem.
---
## 7. TP34 — Caddyfile via Golden Config (nach P2)
- **Vorbedingung:** Backend-Dienste existieren als `ipam.Service` (P2).
- **Modell (nativ):** Proxy-Route = **Relationship** (oder CustomField) Frontend `caddy`-Service ↔ Backend-
Service, plus den öffentlichen Hostname am Backend. GC-Job + Jinja rendert den Caddyfile, Diff gegen
live `caddy-bf1`, neue ComplianceRule `caddyfile`.
- **Schritt 0 / Quick-Win (sobald gebaut wird):** `terpene.teilzeitladen.xyz → http://10.40.20.167:8890`
als **manueller** Caddy-Block, damit terpene läuft, bevor die GC-Pipeline steht.
- ⚠️ **Offener Design-Punkt:** Caddy ist **kein RouterOS-Gerät** — GC an ein Nicht-Netzgerät zu deployen
(Caddy-Reload) ist neu (die „nicht in TP37"-Grenze). Deploy-Pfad in der TP34-Build-Session entscheiden.
## 8. TP36 — Live-Daten-CustomFields + Datei-Split (parallel)
- **CustomFields auf `dcim.Device`:** `ros_version`, `compliance_pct`, `dhcp_server_count`, `mgmt_ip`,
`dns_upstream_mode`. Compliance-Zahl kommt aus **GC selbst**, der Rest aus MikroMCP/REST.
- **Skript `nautobot/gc-snapshot.py`** (neu — existiert noch nicht): liest live, setzt die CFs, rendert
`docs/teilprojekte-aktuell.md` als **read-only Snapshot**.
- **Datei-Split:** `teilprojekte-index.md` (nur aktive TPs, eine Zeile) · `teilprojekte-aktuell.md`
(Live-Snapshot) · `teilprojekte-archiv.md` (unverändert). `/projektstatus` liest **Index + Archiv**.
- **Unabhängig von TP37** → kann sofort/parallel starten.
---
## 9. Empfohlene Reihenfolge der Build-Sessions
1. **TP37 P1** (Substrat) — Inventur → Seeder → Compliance-Gegenprobe.
2. **TP37 P2** (Dienste) — schließt an P1 an, gleiche Gegenprobe.
3. **TP34** — nach P2 (Quick-Win terpene als Schritt 0).
4. **TP36** — jederzeit parallel zu 1–3.
## 10. Offene Entscheidungen je Build-Session (nicht heute)
- **TP34:** Proxy-Route-Modell (Relationship vs. CustomField) + Caddy-Deploy-Pfad (GC an Nicht-Netzgerät).
- **TP37:** Hosts als eigene `dcim.Device` anlegen oder nur Cluster? (Empfehlung: Etappe 1 nur Cluster.)
- **TP36:** genaues Feld-Set + wie oft `gc-snapshot.py` läuft (Bot analog golden-config vs. on-demand).
## 11. Was diese Session geändert hat (nur Doku)
- `nautobot/tp36-cf-estate-seed.py` → **`nautobot/tp44-cf-estate-seed.py`** umbenannt (+ 4 Referenzen,
+ Docstring-Titel TP36→TP44).
- `teilprojekte.md`: Quick-Index-Zeile TP44; Ist-Stand-Bullet 2026-09-06; TP34/TP36/TP37-Abschnitte auf
den korrigierten Stand gezogen; **neuer TP44-Abschnitt** mit Anker.
- `handoff-20260902-cf-estate-nautobot-ssot.md` + `cf-tunnel-mapping.md`: Dateiname-Referenzen + erledigte
TODOs nachgezogen.
- **TP23-Quick-Index-Zeile** (fremde, korrekte Fremd-Änderung ✅→⏳) auf User-Okay mit übernommen.

View File

@@ -0,0 +1,57 @@
# Handoff 2026-09-10 — TP44 Teil B: CF-Estate-Sync als Nautobot-Job LIVE
> **Ergebnis:** Der Cloudflare-Estate→Nautobot-Sync läuft als **täglicher Nautobot-Job**
> (`CFEstateSync`, grouping `TP44 / Cloudflare`). Dry-Run + Commit-Run sauber: **4 CloudNetworks /
> 14 CloudServices, alle CF-Endpoints lesbar, 0 Drift.** CF bleibt operativer Master, Nautobot ist
> read-only Dokumentations-SSoT. **TP44 ist damit vollständig durch.**
## Governance (User, 2026-09-09)
Periodische externe→Nautobot-Syncs leben als **Nautobot-Jobs** in `bf-infra/jobs/` und werden **in
Nautobot geplant** — kein per-Task-Container, kein Cron. Künftige Syncs = weitere Jobs in `jobs/`.
## Was live ist
- **Runtime:** `jobs/cf_estate_sync.py` (`CFEstateSync`, ORM). Pull der CF-API (urllib+Bearer),
Upsert per `extra_config`-Match (`tunnel_id`/`script`/`id`/`service_id`), Verwaisung = `stale`-Flag
statt Löschen. 403-tolerant (fehlender Scope kippt den Sync nicht; Verwaisung wird dann übersprungen).
- **Registrierung:** `jobs/__init__.py` ruft `register_jobs(CFEstateSync)`; **Repo-Wurzel-`__init__.py`**
macht `bf_infra` als reguläres Paket sichtbar.
- **Token:** Nautobot-Secret `cf-api-token` (Provider `environment-variable`) → `CF_API_TOKEN` am
`nautobot-worker`, verdrahtet im Anchor-`environment` von `docs/nas-vlan20/stacks/210-nautobot.yml`
(gitignored). Wert = der breite `CF_API_TOKEN` aus `~/.secrets/credentials.env` (liest 14/14).
- **Schedule:** `ScheduledJob "CF Estate Sync – taeglich"`, `interval=daily`, `start_time=2026-09-11T03:00:00Z`
(= 05:00 Europe/Vienna, vor den Golden-Config-Läufen), `enabled=True`, `dryrun=False`.
- **GitRepository:** `bf-infra` (`provided_contents=['extras.job']`) — war schon verdrahtet.
## Drei load-bearing Funde (sonst lädt/plant der Job nicht)
1. **Repo-Wurzel `__init__.py` ist Pflicht.** Nautobot 3.1.7 lädt Git-Repo-Jobs über
`import_modules_privately()` → `pkgutil.walk_packages([GIT_ROOT])`. walk_packages entdeckt **nur**
reguläre Pakete (mit `__init__.py`), **keine** Namespace-Packages. Ohne die Datei ist der geklonte
`GIT_ROOT/bf_infra/` unsichtbar → `jobs/` wird nie importiert. Symptom: Git-Sync **SUCCESS**, aber
Log „No jobs were registered on loading the `bf_infra.jobs` submodule" und **kein** Job-DB-Eintrag.
bf-infra ist das **erste** Git-Repo mit `extras.job` — daher nie zuvor aufgetreten. Der `module_path`-
Filter des Loaders importiert nur `bf_infra` + `bf_infra.jobs.*`; `nautobot/`, `routeros/` etc. bleiben
unberührt.
2. **`register_jobs()` gehört ins Paket-`__init__`**, nicht nur ins Submodul (Doku bestätigt).
3. **`Meta.has_sensitive_variables = False`** nötig — Default `True` ⇒ Nautobot verweigert das Scheduling
(„Job may have sensitive input variables"). Der Job nimmt nur `dryrun` (Boolean); das Token kommt aus
dem Secret, nicht aus einer Job-Variable.
## Zwei Daten-/Code-Funde beim Dry-Run
- **VPC-Bug:** VPC-Directory-Services tragen ihren Identifier in **`service_id`**, nicht `id`. Der Job las
`id` (=None) → per `.get(mk)==None` matchte er ein Fremdobjekt (App Launcher) und ließ den echten
`terpene-db` auf stale laufen. Fix: VPC nutzt `service_id`; `_upsert` überspringt `mv=None` generell.
- **Seed-Artefakt:** der geseedete CloudService `terpene-db` hatte `extra_config.service_id: null`
(der echte `019fa3d5-…` stand beim Seed nur in den Hyperdrive-Einträgen als `vpc_service_id`).
**Einmalig reconciled** (PATCH `service_id=019fa3d5-…`) → seither matcht der Sync sauber, 0 Drift.
## Drift-Korrektur (nicht stillschweigend)
Die frühere Notiz „Repo-`CF_API_TOKEN` darf kein Workers-VPC → über den `cloudflare`-MCP-Credential"
(TP44-Prosa + `handoff-20260902-…`) war **falsch**. Live getestet liest der `CF_API_TOKEN` aus
`~/.secrets/credentials.env` Hyperdrive/VPC/Workers (alle 200). Der schmale Token ist `CF_DNS_API_TOKEN`
(403). Der `cloudflare`-MCP ist der **remote OAuth-MCP** (kein API-Token) und für einen serverseitigen
Job ohnehin nicht nutzbar.
## Nächster CF-Sync = neuer Job im selben Muster
Modul in `jobs/` anlegen, Klasse importieren + `register_jobs(...)` im `jobs/__init__.py` ergänzen,
`Meta.has_sensitive_variables=False` setzen, Git-Sync, enablen, Dry-Run, dann Schedule. Die Wurzel-
`__init__.py` gilt schon.

View File

@@ -0,0 +1,28 @@
# Handoff 2026-09-13 — CF_API_TOKEN gerollt (Gitea bf-infra #69)
## Was passiert ist
`CF_API_TOKEN` (id `493ed8bd…`, konsolidiert) war nach TP41 tot (Fehler `1000` an allen drei
Fundorten). Statt eines separaten railplanner-Tokens wurde das konsolidierte Token am 2026-09-13
im CF-Dashboard **gerollt** (neuer Wert, gleicher Scope). Workers-Scope verifiziert:
`GET /accounts/{id}/workers/scripts` listet `railplanner` / `blaueblueten-n8n` / `terpene`.
## Drift behoben
Der neue Wert lag zunächst nur in `credentials.env`. Realignt auf identischen Wert in:
- `~/.secrets/exports.zsh` (SSoT) — vorher gar kein `CF_API_TOKEN`
- `~/.secrets/credentials.env`
- `bf-infra/mcp/cloudflare/.env` (vorher `…4148`)
- `bf-network-r6/mcp/cloudflare/.env` (vorher `…2174`)
## Gotcha (hat die Session zweimal „Token kaputt" fehldeuten lassen)
Account-owned Tokens verifizieren an `GET /accounts/{account_id}/tokens/verify` — am alten
`/user/tokens/verify` liefern sie `1000 "Invalid API Token"`, **obwohl gültig**. Siehe
`docs/tp16.1-warp-mesh-native-crs326.md:164` und `docs/teilprojekte-archiv.md:830`.
Ins Memory notiert (`reference_cf_account_token_verify.md`).
## Status
Gitea #69 `closed` (`status:done`). Kein Repo-Code geändert — alles Secret-Store + Gitea-Status.

View File

@@ -0,0 +1,111 @@
# Handoff 2026-09-14 — TP25: ap2-In-situ-Messung (Terrasse), Hebel-A-Machbarkeitsprüfung
**Anlass:** Christoph beobachtete 19:18 auf der Terrasse springende WLAN-Balken (1→2→3 binnen
Sekunden) und zwei Anruf-Aussetzer; danach Umstellung des Telefons auf 5G-Zellular. Verdacht:
Das Telefon probe die APs ab und falle dabei hinaus.
**Beteiligte:** iPhone `F2:62:4C:E1:AF:09` (das bekannte Fund-E-Gerät), Manager `crs326-core`.
Alle Reads am Manager; **kein einziger Geräte-Write** in dieser Session.
## cap-wifi-Karte (verifiziert live 19:22, vor jeder Auswertung gelesen)
`cap-wifi1` = ap2 5G (5300/ax/Ce/DI, tx-power 18) · `cap-wifi6` = ap2 2,4G (2462, tx-power 15) ·
`cap-wifi2` = ap3 5G (5180) · `cap-wifi4` = ap3 2,4G · `cap-wifi3`/`cap-wifi5` = ap1 (5G 5280/2,4G).
⚠️ Das CLAUDE.md sagt „ap1 FUNKSTILL seit 08-30" — **überholt**: seit dem 09-04-Kanalplan-Commit
hat ap1 wieder eine Provisioning-Zeile und dient live (heute 16:51:53 sogar ein Radar-Event auf
5280 mit sauberem Kanalwechsel auf 5260/5280-Liste). Doku-Drift, hier vermerkt.
## Befund 1 — das Flapping ist echt und überwiegend band-intern an ap2
Kollektor-Log 18:53–19:18: **~30 Roams**, fast alle `cap-wifi1 ↔ cap-wifi6` = **ap2 5G ↔ ap2 2,4G**
(derselbe AP), Feldstärke −68…−81 dBm. Drei echte Abwürfe `disconnected, not responding`
(19:01:29, 19:12:10, 19:47:51 — der letzte tötete den Anruf). Ein Ausflug zu ap1-5G (19:35:45,
**−64**) und ap3 (−78…−82).
## Befund 2 — In-situ vor ap2: Hardware-Verdacht WIDERLEGT
Christoph stellte sich 1–2 m vor ap2. Registration-Table live (3 Stichproben + Log):
| Position | Interface | Signal | Verhalten |
|---|---|---|---|
| 1–2 m vor ap2 | cap-wifi1 (5G) | **−49…−51** | **>2 min stabil, 0 Roams** |
| Rückweg (Weg) | cap-wifi1 → cap-wifi6 | −76…−78 | 2 Roams binnen 26 s |
| Terrassenplatz | cap-wifi6 (2,4G) | **−65…−73** | 36 s im 1-s-Takt, 0 Roams, ±4 dB |
⇒ Der offene TP25-Unterpunkt „**ap2 unterperformt (2 m/−80, 23:02-Befund)**" ist **in situ
widerlegt**: ap2 sendet auf 2 m mit −49…−51 dBm und bleibt dort stabil. Der 23:02-Befund
reproduziert sich nicht — plausibel, weil seitdem der 09-04-Kanalplan (5220→5300/5320,
Band-B-Liste) committed ist; alternativ war die damalige Position/Attribution anders.
**ap2 RF/Antenne/HW: sauber. Kein Hardware-Tausch begründet.**
## Befund 3 — Ursache-Modell Terrasse: 5-GHz-Zellkante + client-getriebene Band-Aggressivität
- Terrassenplatz: 5 GHz **−76…−81** (Zellkante), 2,4 GHz **−65…−73** — die ~7 dB sind normale
Bandspreizung plus Wand. Link-Budget, kein Defekt.
- Das iPhone **bleibt**, sobald ein Band klar gewinnt (am Platz: 2,4 GHz, minutenlang ruhig).
Das Thrash passiert ausschließlich in der **Überlappungszone −70…−77**, wo beide Bänder
gleichauf liegen und 5 GHz ständig um die iOS-Aufgabeschwelle (~−75) pendelt.
- Client-Aggressivität als Second Layer: 19:44:21 stand das Telefon bei **−52 auf ap2-5G** und
floh 13 s später auf 2,4 (−77) — dasselbe Muster wie im Archiv-Fund E („Abbruch bei −47").
Steering-Objekte `st-main`/`st-guest` haben **keine Schwellen** (nur rrm/wnm) — der AP
drängt nichts aktiv per BTM, die Entscheidungen trifft das iPhone.
- Mit `ft=no` (Dauerzustand seit 09-04) ist jeder Roam eine Voll-Reassoziation in Sekundenhöhe
⇒ genau darin sterben Anrufe.
## Hebel-A-Machbarkeitsprüfung (Dry-Run, kein Write)
**Ziel:** 5-GHz-Boden für `dirtyvader-main` (reject unter ~−76), damit das Telefon an der
Zellkante sofort endgültig auf 2,4 GHz committet statt zu thrashen.
Live + MikroTik-Doku verifiziert:
- `signal-range` wird **kontinuierlich** geprüft (Grace über `allow-signal-out-of-range`,
Default 0s) — der Mechanismus trägt grundsätzlich.
- ABER: `/interface/wifi/access-list` hat **kein `band`-Property**. Band-Scoping nur über
`interface=` möglich — und die `cap-wifiN`-Namen wechseln bei jedem CAP-Rejoin (Gotcha
2026-08-31): die Regel würde stillschweigend auf ein falsches Radio zeigen (im Worst Case
ein 2,4-Master ⇒ Lockout-Schatten). Alternativen fallen alle durch:
- **Nur SSID scope** (ohne Band): trifft auch 2,4 GHz — Schlafzimmer-Gegenmessung 08-22
(−84 dBm am Counter-AP) ⇒ Lockout, exakt das 08-22-Gegenargument.
- **Nur MAC scope** (iPhone): trifft beide Bänder — das iPhone saß heute selbst bei −89 auf
2,4 GHz (19:01) ⇒ WiFi-Verlust in schwachen Räumen.
- **Fazit: Der Band-Boden ist in der aktuellen wifi-qcom-Access-List nicht sauber ausdrückbar.
Nicht umgesetzt; Dry-Run-Preview des Kandidaten gefahren, kein Apply.**
Kandidat (NICHT angewendet, nur als Referenz wie er *heute* aussehen würde):
```
/interface wifi access-list add interface=cap-wifi1 ssid-regexp=dirtyvader-main \
signal-range=-120..-76 action=reject comment="TP25-hebel-a-5g-boden"
```
(× cap-wifi1/2/3 — die drei 5G-Master — bricht bei jedem CAP-Rejoin)
**Verbleibende Hebel:**
1. **`ft=yes` uniform auf `sec-main`** — macht Roams nahtlos ⇒ Anrufe überleben das (verbleibende)
Springen. Bewusste Aufweichung der 09-04-Entscheidung (`ft=no`), Fund-E-Ursache (7.24.1) ist
längst behoben, FT-Flotte uniform. Ein Config-Weg: Template + Compliance + Transaktion.
2. **Deckungsfix (TP25 Variante 3)** — der eigentliche Hebel: ein AP muss an der Terrasse
eindeutig stärker sein als alle anderen. Bemerkenswert: ap1-5G erreichte die Terrasse heute
mit −64 (besser als ap2-5G mit −78) — ap1 sitzt bereits auf der Band-B-Liste 5260/5280.
3. Monitoring: wireless-Logging läuft persistent; das Flapping ist damit künftig rückwirkend
diagnostizierbar.
## Nachweise
- Live-Log am Manager: 43 + 18 + 8 Zeilen `wireless,info` zu `F2:62:4C:E1:AF:09`, 18:53–19:56.
- 1-s-Sampling: zwei 18-Sekunden-Loops (`:for` am Manager, Registration-Table), 20:01:44–20:02:26.
- Monitor-Reads: `cap-wifi1` → `5300/ax/Ce/DI tx-power 18`; `cap-wifi6` → `2462/ax tx-power 15`.
- Doku-Verifikation Access-List: help.mikrotik.com/docs/display/ROS/Wifi (signal-range kontinuierlich,
kein band-Property, first-match-wins, kein impliziter Reject).
## Offen / nächste Schritte
1. Entscheidung Christoph: `ft=yes` ja/nein (Hebel 1 oben) — ich lege dazu auf Go den
GC-ConfigPlan als Dry-Run vor.
2. Deckungsfix-Terminierung (Variante 3 / ap1-Endausbau) — TP25 bleibt offen.
3. CLAUDE.md-Drift „ap1 FUNKSTILL" beim nächsten CLAUDE.md-Edit korrigieren (nur Vermerk hier,
kein stiller Fix).
4. Gitea-TP25-Issue **#17** hat einen Kommentar mit diesem Befund erhalten.
5. 🔴 **Sicherheitsvorfall dieser Session:** durch einen Env-Parse-Fehler stand der
`GITEA_ACCESS_TOKEN` in einer URL im Traceback — **Token ist als kompromittiert zu
betrachten und zu rotieren** (neues Token erzeugen, `~/.hermes/.env` aktualisieren, altes
widerrufen). Siehe Merkregel-Klasse „Werte nie suchen, um sie zu sehen".

View File

@@ -0,0 +1,72 @@
# Handoff 2026-09-15 — TP25: Steering-Threshold 5G deployed, Terrasse verifiziert, MacBook-Klebrigkeit „wird nicht umgesetzt"
**Anlass:** Folgesession zum TP25-Handoff „zuordnung-und-redundanz" ([[handoff-20260915-tp25-zuordnung-und-redundanz]]). Ziele: (1) Doku-Drift schließen, (2) Roaming-Threshold für die Terrasse (5G bricht früher zur 2,4G ab), (3) Terrasse-Nachmessung nach dem Deploy.
## 1. Steering-Threshold 5G — DEPLOYED, 140/140
**Problem:** Am Rundgang 09-15 saß der Terrasse-Client auf der **−80/5G-Kante** (genau der Default
`transition-threshold`); auf 2,4 GHz wäre das nicht passiert.
**Umsetzung (nur 5G):** neues Steering-Profil `st-main-5g` mit `transition-threshold=-72`
(statt Default −80) und `transition-threshold-time=5s` (statt 10s). Die drei 5G-Configs
(`cfg-main-5g-ap1/ap2/ap3`) zeigen darauf; die drei 2G-Configs bleiben auf `st-main` (unset −80),
weil 2,4 GHz draußen (Terrasse/außerhalb) Reichweite behalten soll. **8 dB Abstand = kleine Hysterese.**
Weg: Template-Edit (`nautobot/mikrotik_routeros.j2`) → `push-gc-template.py` (GC-Commits `6a4b504f`,
`242ed108`) → manueller Plan (`gc-manual-plan.py`, Plan `cc8340a8`, Completed) → Refresh:
**140/140, 0 Drifts.** Commands-File:
[`docs/transaktionen/TP25-steering-5g-threshold.commands.rsc`](transaktionen/TP25-steering-5g-threshold.commands.rsc).
## 2. Gotcha: Parameter-Reihenfolge im Template
Nach dem ersten Push meldete Compliance **139/140** mit einem `wifi-steering`-Drift: `extra`/`missing`
derselben Zeile, aber mit unterschiedlicher Feld-Reihenfolge. **RouterOS exportiert `transition-threshold`
vor `wnm` (alphabetisch)** — mein Template hatte `wnm` davor. Fix = Template-Zeile auf die Export-Reihenfolge
gebracht (`… rrm=yes transition-threshold=-72 transition-threshold-time=5s wnm=yes`). Kein Re-Deploy nötig
(das Gerät war schon korrekt, nur das Template war es nicht). **Merkregel: bei neuen Parametern im
`/interface wifi steering add` die RouterOS-Export-Reihenfolge (alphabetisch) verwenden, sonst Drift ohne
Fehlfunktion.**
## 3. Terrasse-Nachmessung — Threshold wirkt am iPhone, nicht am MacBook
Zwei Apple-Geräte 20 cm auseinander auf der Terrasse, beide auf `dirtyvader-main`, beide physisch
rein/raus bewegt (A/B):
| Gerät | Band | Signal | Roam-Verhalten |
|---|---|---|---|
| iPhone `F2:62:4C:E1:AF:09` | **2,4 GHz** | −55…−66 | ✅ roamt sauber (rein→5G, raus→2,4G) |
| MacBook `56:71:6C:22:E6:A9` | **5 GHz** | −73…−75 | ❌ kein Roam (uptime 1h15m unverändert) |
**Befund:** gleiche Bewegung, gegensätzliches Verhalten. iOS folgt dem Band-Wechsel; **macOS hält 5 GHz
klebrig fest** und ignoriert die 802.11v-Transition-Request — selbst unter der −72-Schwelle und beim
physischen Umhertragen. Christoph: das MacBook hatte an diesem Ort nie Probleme (−73/5G reicht ihm).
## 4. Entscheidung: MacBook-Klebrigkeit = ❌ WIRD NICHT UMGESETZT
Der einzige Hebel dagegen wäre `transition-time=immediate` (deauth-Erzwingung nach der
Transition-Request statt bloßem Vorschlag) — ein schärferer Eingriff mit Abbruch-Risiko für aktive
Sitzungen. **Christoph-Entscheid 2026-09-15: nicht umsetzen.** Kein Handlungsbedarf, da das MacBook
dort funktioniert. Nur dokumentiert, falls es später doch wieder aufkommt.
## 5. Doku-Drift geschlossen (diese Session)
- **CLAUDE.md:** ap1 „FUNKSTILL"→aktiv am Sideboard (`core ether3`), ap2→Technik UG (`core ether21`,
ether1-MAC `:39`), ap3→Technik OG (`branch ether24`), Branch-Portliste `24 ap3`, Gotcha-Zeile
ap2/ap3-Uplink. Kanäle mitkorrigiert (ap1 `5260/Ce`, ap2 `5300/Ce`).
- **teilprojekte.md:** neuer Stand-Block 2026-09-15 (definitive Zuordnung + Tausch-Befund ap2↔ap3).
- **Nautobot Location** (war `None`): ap1→`Wohnzimmer Sideboard`, ap2→`Technik UG`, ap3→`Technik OG`.
## 6. Handoff-Punkte (aus dem Vorgänger) — aufgelöst
1. **ap1 behalten/abbauen** → **behalten** (Christoph). APs bleiben an ihren jetzigen Orten.
2. **Tausch korrigieren** (cAP ax → Sideboard) → **verworfen**; aktueller Zustand bleibt.
3. **Drei-Räume-Schatten** nachmessen → **verworfen**; Signal war beim letzten Rundgang gut.
4. **Doku-Drift** → ✅ geschlossen (s. §5).
## Übergabeprompt (nächste Session)
> TP25: Steering-Threshold 5G deployed (st-main-5g, −72/5s, 140/140), Terrasse am iPhone verifiziert
> (2,4G statt 5G/−80). MacBook-Klebrigkeit auf 5G dokumentiert und per Christoph-Entscheid
> „wird nicht umgesetzt" (transition-time=immediate). Doku-Drift geschlossen, Handoff-Punkte aufgelöst
> (ap1 bleibt, APs bleiben, Drei-Räume verworfen). Siehe
> [[handoff-20260915-tp25-steering-threshold-und-terrasse]].

View File

@@ -0,0 +1,105 @@
# Handoff 2026-09-15 — TP25: AP-Zuordnung geklärt, Messrunde (Vorher), Tausch ap1↔ap3 begonnen
**Anlass:** Christoph wieder on site in Linz. Zurückgestellter Job = TP25 Deckungsfix Variante 3
(„Deckenstrahler an den guten Platz, hAP in den Schatten"). Session lief als große Messrunde
(Vorher) + physischer Tausch ap1↔ap3. **Tausch ist physisch angefangen, aber der Netzzustand ist
zum Sitzungsende unklar — ap2 ist down.**
## 🔑 AP-Zuordnung — EINDEUTIG per physischem Test geklärt
Die Session lief lange mit vertauschter Zuordnung (auch Christoph hat sie zwischenzeitlich falsch
„korrigiert"). Der **Kabel-Test** hat sie eindeutig festgelegt:
| Gerät | IP | Position | Uplink |
|---|---|---|---|
| **ap1** | 10.40.99.11 | **Sideboard / Wohnzimmer** | core `ether3` |
| **ap2** | 10.40.99.12 | **Technik OG** | core `ether8` → branch `ether24` |
| **ap3** | 10.40.99.13 | Technik UG | core `ether21` |
**Beweis:** Christoph zog das Kabel in Technik OG → `cap-wifi1`/`cap-wifi6` (= ap2,
Radio-MAC `D0:EA:11:4D:40:3E/3F`) verschwanden aus der cap-wifi-Karte, ap1/ap3 blieben.
⇒ ap2 = Technik OG, ap1 = Sideboard. Die ARP zeigt ap2 noch ~30 s „reachable" (Cache), die
CAPWAP-Karte ist die Wahrheit.
⚠️ **CLAUDE.md-Drift:** die Hardware-Tabelle sagt für ap1 „core ether15" — überholt, ap1 hängt an
`ether3`. Und die Doku-Aussage „ap1 FUNKSTILL seit 08-30" ist überholt (ap1 dient live).
## Messrunde (Vorher) — Methode
iPhone `F2:62:4C:E1:AF:09` (Fund-E-Gerät) wurde per **Access-List-Reject** gezielt auf je einen AP
gelenkt (die anderen zwei APs ablehnen), dann Registration-Table am Manager gelesen. Reject-Regeln
nur auf `ssid-regexp=dirtyvader-main`, am Ende immer `remove [find where comment~"TP25-messung"]`.
⚠️ **Zwei Methodik-Gotchas (neu):**
1. `interface=` in der Access-List nimmt **nur EINEN Wert** (keine Komma-Liste) — pro AP zwei
Regeln (5G- + 2,4G-Radio). Eine Komma-Liste wirft `input does not match any value of interface`.
2. **MAC-Tippfehler** `F2:62:4C:E1:41:AF:09` (ein „41" zu viel) ist mir **zweimal** passiert und
hat stille Fehl-Reads (leere Registration-Table) erzeugt. Korrekt ist `F2:62:4C:E1:AF:09`.
**Methodischer Vorbehalt:** die wiederholten Rejects + Disconnects drosseln die iOS-Wiederverbindung.
Ein „✗ tot"-Wert direkt nach mehreren Disconnects kann teils Artefakt sein — Christoph hat den
ap1-tot-Befund auf der Terrasse aber selbst per manuellen Verbindungsversuchen bestätigt.
## Messwerte (Vorher)
**Innenräume** (Durchschaltung, je Station alle 3 APs):
| Ort | ap1 (Sideboard) | ap2 (OG) | ap3 (UG) |
|---|---|---|---|
| Küche | 5G −52 | — | — |
| Schlafzimmer | 5G −52 | ✗ tot | 2,4G −57 / 5G −73 |
| Bad | 2,4G −71…−76 | ✗ tot | 5G −73 / 2,4G −72 |
| Klo | ✗ tot | 2,4G −75…−81 | 5G −69 |
| Technik OG | (−52 erst, dann ✗)† | 5G −47…−57 | 5G −68…−71 |
**Terrasse** (3 Runden je AP: sitzend → Rundgang entlang der Mauern → wieder sitzen):
| | ap1 (Sideboard) | ap2 (OG) | ap3 (UG) |
|---|---|---|---|
| Sitzend | ✗ tot | 5G −78…−85 / 2,4G −67 (Thrash) | ✗ tot |
| Rundgang | ✗ überall | 2,4G −63…−74 / 5G −73…−75 | ✗ (nur 1 Mauerdurchlass −70…−82) |
† Vorbehalt s.o.
**Kernbefunde:**
1. **Die Terrasse wird ausschließlich von ap2 (Technik OG) bedient — marginal** (Band-Thrash
5G −78…−85 / 2,4G −67). ap1 (Sideboard) erreicht die Terrasse **nicht**, ap3 nur an einem
Mauerdurchlass kurz (−70…−82). Die Prämisse „Sideboard-AP deckt die Terrasse" ist **widerlegt**.
2. **ap1 (Sideboard) ist der Innenraum-König:** Küche −52, Schlafzimmer −52, Bad −71…−76.
3. **ap3 (cAP ax, UG) hält als einziger beide Geschoße** (UG: Schlafzimmer/Bad/Klo −69…−73,
OG: Technik OG −68…−71 über die Decke).
## Tausch ap1↔ap3 — Status UNKLAR (Sitzungsende)
Christoph hat ap1 und ap3 physisch getauscht: **ap3 (cAP ax) liegt jetzt „am Kasten auf
ap1-Position"**, bewusst „oben/unten ausgerichtet wie Deckenmontage" (Abstrahlwinkel). Ports/VLAN
sollten laut Vorgabe gleich bleiben.
**Live-Befund direkt nach dem Tausch (Vorsicht, Zustand kann sich noch setzen):**
- ap2 = **down** (10.40.99.12 ARP `incomplete`, fehlt in cap-wifi-Karte). Vermutlich Kabel beim
Tausch abgezogen.
- ap1 = reachable, noch an `ether3` (Sideboard).
- ap3 = reachable, aber Bridge-Host zeigt es an **`ether8` (branch)**, nicht an `ether21`.
- `ether21` ist **leer**.
⇒ Der Tausch ist im Netz noch nicht so angekommen, wie physisch beabsichtigt. **Bevor irgendetwas
weitergemessen wird: ap2 wieder einstecken und die tatsächliche Verkabelung (welches Kabel an
welchem Gerät) klären.**
## Offen / nächste Schritte
1. **ap2 (Technik OG) wieder versorgen** — Kabel prüfen, ARP `10.40.99.12` wieder `reachable`.
2. **Verkabelung nach dem Tausch verifizieren:** Bridge-Host-Tabelle (`mac-address~"D0:EA:11"`)
gegen Soll (ap1=`ether3`, ap2=`ether8`/branch, ap3=`ether21`) stellen. ap3 hängt aktuell an
`ether8` — klären, ob das Absicht ist oder Verwechslung.
3. **Nachher-Messung** derselben Stationen (Terrasse + Innenräume), erst wenn 1+2 sauber sind.
4. **Nautobot hat keine Location/Position** für ap1/ap2/ap3 hinterlegt (`location: None`). Nach dem
abgeschlossenen Tausch die korrekten Positionen dort nachtragen (SSoT-Drift schließen).
5. Gitea-TP25-Issue #17 bekommt den Befund als Kommentar (Zitat auf Messwerte + Zuordnung).
## Messwerte-Kurzform (für Folgesession)
`cap-wifi`-Karte war am Sitzungsende nach ap2-Rejoin: `cap-wifi1`=ap3-5G, `cap-wifi2`=ap3-2,4G,
`cap-wifi3`=ap1-5G, `cap-wifi5`=ap1-2,4G, ap2 fehlte (down). **Die cap-wifiN-Nummern verschieben
sich bei jedem CAP-Rejoin — vor jeder Messung neu lesen** (`/interface wifi radio print terse
proplist=cap,radio-mac,interface` am Manager).

View File

@@ -0,0 +1,96 @@
# Handoff 2026-09-15 — TP25: AP-Zuordnung fixiert, Tausch-Befund, ap1-Redundanz gemessen
**Anlass:** Folgesession zur unklaren Tausch-Lage vom Vormittag ([[handoff-20260915-tp25-tausch-und-zuordnung]]).
Ziele: (1) AP-Positionen definitiv per IP/MAC/Switch-Port klären, (2) ob die Messwerte den richtigen
Geräten zugeordnet sind, (3) Rundgang-Messung im natürlichen Zustand, (4) ap1-Redundanz-Test (ap1 aus).
## 🔑 AP-Zuordnung — DEFINITIV (IP + MAC + Switch-Port)
| Gerät | IP | ether1-MAC | Bridge/Mgmt-MAC | Radios (5G/2,4G) | Port | Position |
|---|---|---|---|---|---|---|
| **ap1** | .11 | `D0:EA:11:4D:40:E0` | `:E1` | `:E5` / `:E6` | core **ether3** | Sideboard (Wohnzimmer) |
| **ap2** | .12 | `D0:EA:11:4D:40:39` | `:3A` | `:3E` / `:3F` | core **ether21** | Technik **UG** |
| **ap3** | .13 | `D0:EA:11:FF:16:9D` | `:9E` | `:9F` / `:A0` | branch **ether24** | Technik **OG** |
Beweis: Neighbor-Tabelle (MNDP, L2) + Bridge-Host-Tabelle + Port-Link-Status am Core, live gelesen.
⚠️ **MAC-Korrektur:** ap2s `ether1` ist **`:39`**, nicht `:3A`. `:3A` ist die Bridge-/Mgmt-MAC
(die CLAUDE.md als „ap2" führt). ap2s Radios sind **`:3E`/`:3F`** — das Handoff-09-15 hatte damit
recht; meine frühere „um eins versetzt"-Korrektur war falsch (ich hatte `:3A` fälschlich als
ether1-Basis angenommen).
## Tausch-Befund — ap2↔ap3 statt ap1↔ap3
Geplant (Deckungsfix Variante 3): **ap1↔ap3** (cAP ax → Sideboard, hAP → UG-Schatten).
Tatsächlich getauscht: **ap2↔ap3**:
- **ap1** blieb Sideboard (ether3)
- **ap2** ging von OG → UG (ether21)
- **ap3** (cAP ax) ging von UG → OG (branch ether24)
⇒ Drei-Wege-Drehung mit dem **falschen Paar**. Der „Deckenstrahler" (cAP ax) steht jetzt in **OG**,
nicht am guten Platz (Sideboard). Ursache war die ap1/ap2-Verwechslung während der Session.
## Rundgang 1 — alle APs an, natürlicher Zustand (ohne Fixierung)
Methode: Registration-Table am Manager im 1-s-Takt, iPhone `F2:62:4C:E1:AF:09` auf `dirtyvader-main`.
- **0 Disconnects**, Signal **−45…−77 dBm** (alles brauchbar, meist deutlich besser).
- Roaming natürlich über **alle 3 APs** (ap3→ap2→ap1→ap2→ap3) — funktioniert.
- **Terrasse** (das Sorgenkind): **−58 dBm stabil** an OG-Position (jetzt cAP ax), 2,4G.
- **ap1 (Sideboard)** wurde nur **kurz gestreift** (−52…−60); den Rest dominieren ap3 (OG) + ap2 (UG).
- Kein Band-Thrash: nur ein sinnvoller 2,4G-Ausflug bei 5G-Zellkante (−77), sonst sauber 5G.
## Rundgang 2 — ap1 komplett aus (Redundanz-Test)
**Methode (neues CAPsMAN-Wissen):** ap1-Radios lassen sich **nicht** über `cap-wifiN` abschalten
(`failure: can not change dynamic interface`). Richtig: Provisioning-Regeln auf `action=none`, dann
re-provisionieren:
```
/interface wifi provisioning set [find where radio-mac=D0:EA:11:4D:40:E5 or radio-mac=D0:EA:11:4D:40:E6] action=none
/interface wifi capsman remote-cap provision [find where identity="ap1"]
```
Rückbau = `action=create-dynamic-enabled` + dieselbe re-provision. (Merkregel: `cap-wifiN` sind
dynamische Interfaces; Abschalten geht nur über die Provisioning-Regel + re-provision.)
**Ergebnis:**
- **Main-Client (iPhone):** ohne ap1 voll abgedeckt (ap2+ap3), tiefster Wert **−80 dBm** (ap3/OG 5G,
an der Terrasse — dieselbe bekannte Zellkante, nur diesmal auf 5G statt 2,4G erwischt), kein Disconnect.
- **IOT:** vorher 27 Geräte (19 ap1 + 8 ap2). Nach Abschalten **alle 27 zurück** — 23 auf ap2, 4 auf ap3.
MAC-gegengeprüft, keiner verloren. **Aber ~4 Geräte sitzen marginal bei −77…−80 dBm** (Wohnzimmer-Geräte,
vorher nah am Sideboard-AP, jetzt an der ap2/UG-2,4G-Zellkante).
- **ap1 wieder eingeschaltet** (Revert) — Zustand vor dem Test wiederhergestellt.
## Befund: ap1 technisch redundant, aber 4 IOT-Geräte an der Kante
| Aspekt | Ergebnis |
|---|---|
| Main-Client | ✅ ohne ap1 voll abgedeckt, tiefster Wert −80, kein Disconnect |
| IOT (27) | ✅ alle verbunden, **aber ~4 marginal −77…−80 dBm** |
ap1 ist **technisch redundant** — nichts fällt aus, wenn es weg ist. Aber die ~4 Wohnzimmer-IOT-Geräte
verlieren ihre Signal-Reserve (verbunden ja, Aussetzer-Risiko erhöht). „ap1 abbauen" ist eine echte
Option, aber kein Selbstläufer.
## Offen / nächste Schritte
1. **Entscheidung ap1:** behalten (Status quo) oder Richtung Abbau? Nur sinnvoll, wenn die ~4 marginalen
IOT-Geräte akzeptiert werden (oder deren Platzierung/ap2-Abdeckung verbessert wird).
2. **Tausch korrigieren?** Aktuell cAP ax @ OG, hAP @ UG, hAP @ Sideboard — misst gut, ist aber nicht der
geplante Zustand (cAP ax → Sideboard). Der **Drei-Räume-Schatten** (Schlafzimmer/Bad/Küche, 08-22:
−82…−84) ist mit dem jetzigen Arrangement **noch nicht verifiziert** — der Rundgang lief ohne
Raumnamen/Fixierung. Nächste Messung sollte die drei Räume gezielt prüfen.
3. **Doku-Drift schließen** (nicht in dieser Session angefasst): CLAUDE.md-Hardware-Tabelle (ap2-MAC
`:3A`→`:39` ether1, ap2 Position OG→UG, ap3 UG→OG, ap1 „FUNKSTILL" überholt), teilprojekte.md TP25-Abschnitt,
Nautobot Location (nach wie vor `None`).
4. Gitea-Issue #17 trägt den Befund als Kommentar.
## Übergabeprompt (nächste Session)
> TP25 weiter: Die AP-Zuordnung ist jetzt definitiv geklärt (Handoff 2026-09-15 „zuordnung-und-redundanz").
> ap1=Sideboard (core ether3), ap2=Technik UG (core ether21), ap3=Technik OG (branch ether24) — der Tausch
> hat ap2↔ap3 vertauscht statt ap1↔ap3, ap1 blieb stehen. Rundgang ergab: Coverage überall gut (0 Disconnects,
> −45…−77 dBm), Terrasse −58 stabil an OG, ap1 nur kurz gestreift. ap1-Aus-Test: Main-Client voll abgedeckt,
> alle 27 IOT-Geräte kehren zurück, aber ~4 Wohnzimmer-IOT sitzen marginal −77…−80 dBm. ap1 ist wieder an.
> Offen: (1) ap1 behalten oder abbauen? (2) Tausch auf Plan korrigieren (cAP ax → Sideboard)? (3) Drei-Räume-
> Schatten (Schlafzimmer/Bad/Küche) gezielt nachmessen. (4) Doku-Drift (CLAUDE.md MAC/Positionen, Nautobot
> Location) schließen.

View File

@@ -68,7 +68,7 @@ den *damals geplanten* Werten und ⬜-Status. Sie sind erledigt bzw. gegenstands
| ~~FritzBox 6660~~ | — | WAN/Transfer | — | — | ❌ **physisch entfernt** | Liwest-Kabelmodemtausch 2026-07-01 (Edge-Cutover), kein Zurück — Arris-Kabelmodem im Bridge-Mode ersetzt sie komplett |
| platform-pg (LXC 105, pve) | — (neu) | Platform-Postgres (TP20), PG16, DB `nautobot` | 20 INFRA | `10.40.20.20` | ✅ **live** | TP20 2026-07-16: erstellt via `pct create`, Ubuntu 24.04 (native PG16, kein PGDG-Repo nötig), UTF8/en_US.UTF-8, `wal_level=replica`, `archive_mode` bewusst noch aus (s. Memory) bis pgBackRest/Garage-S3 da ist; Creds `postgres/.secrets` |
| nautobot (Portainer-Stack, NAS) | — (neu) | Nautobot Golden Config (TP21), App/API | 20 INFRA | `10.40.20.30` | ✅ **live** | TP21 2026-07-16: `ghcr.io/nautobot/nautobot:3.1.7`, ep14 Stack Id 203, DB=platform-pg; Begleitcontainer `nautobot-worker`.20.31, `nautobot-scheduler`.20.32, `nautobot-redis`.20.34 |
| nautobot (Portainer-Stack, NAS) | — (neu) | Nautobot Golden Config (TP21), App/API | 20 INFRA | `10.40.20.154` | ✅ **live** | TP21 2026-07-16: `ghcr.io/nautobot/nautobot:3.1.7`, ep14 Stack Id 203, DB=platform-pg; Begleitcontainer `nautobot-worker`.20.155, `nautobot-scheduler`.20.156, `nautobot-redis`.20.158. **TP45 Schicht A 2026-09-21:** Oktett-Klasse `.150–.199` (App-Services) — die alten `.30–.34` gibt Nautobot an AGH `.30`/`.31` frei |
> Weitere Geräte (Home Assistant, HA-IoT, Drucker-Reservierung, etc.) hier ergänzen, sobald relevant.

View File

@@ -0,0 +1,6 @@
cap-wifi1=ap2/5GHz
cap-wifi2=ap3/5GHz
cap-wifi3=ap1/5GHz
cap-wifi4=ap3/2,4GHz
cap-wifi5=ap1/2,4GHz
cap-wifi6=ap2/2,4GHz

View File

@@ -0,0 +1,2 @@
iphone|10.40.10.196|F2:62:4C:E1:AF:09
s22|10.40.10.178|2A:0D:B0:5D:AD:A7

View File

@@ -0,0 +1,6 @@
ts_epoch,ts_local,marker
1788526676,14:57:56,PINM=off
1788526735,14:58:55,PINM=off
1788526763,14:59:23,PINM=off
1788526765,14:59:25,PINM=off
1788526770,14:59:30,PINM=s22|2A:0D:B0:5D:AD:A7|ap1|24
1 ts_epoch ts_local marker
2 1788526676 14:57:56 PINM=off
3 1788526735 14:58:55 PINM=off
4 1788526763 14:59:23 PINM=off
5 1788526765 14:59:25 PINM=off
6 1788526770 14:59:30 PINM=s22|2A:0D:B0:5D:AD:A7|ap1|24

View File

@@ -0,0 +1 @@
{"mode": "langzeit", "phase": "GEHWEG", "title": "Roaming-Messung l\u00e4uft", "instruction": "Aufzeichnung gestoppt.", "step": 0, "steps": 0, "ends": 0}

View File

@@ -0,0 +1,26 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788526644,14:57:24,14:57:24,41,472232,195392,cap-wifi3,-57,309700000,325000000,2800,2960,00:04:37,00:00:00
1788526646,14:57:26,14:57:26,11,229864,36304,cap-wifi3,-57,309700000,325000000,2800,2960,00:04:39,00:00:00
1788526648,14:57:28,14:57:28,8,132384,26968,cap-wifi3,-59,309700000,309700000,6160,6512,00:04:41,00:00:00
1788526650,14:57:30,14:57:30,30,196672,48240,cap-wifi3,-59,309700000,344100000,6160,6512,00:04:43,00:00:00
1788526652,14:57:32,14:57:32,12,131304,37448,cap-wifi3,-59,309700000,344100000,6160,6512,00:04:45,00:00:00
1788526654,14:57:34,14:57:34,11,92000,18872,cap-wifi3,-59,309700000,412900000,5600,5920,00:04:47,00:00:00
1788526656,14:57:36,14:57:36,12,130144,24840,cap-wifi3,-60,309700000,390000000,6048,6512,00:04:49,00:00:00
1788526658,14:57:38,14:57:38,9,105160,20800,cap-wifi3,-60,309700000,390000000,6048,6512,00:04:51,00:00:00
1788526660,14:57:40,14:57:40,14,177144,59112,cap-wifi3,-57,309700000,344100000,6048,6288,00:04:53,00:00:00
1788526662,14:57:42,14:57:42,11,136152,39360,cap-wifi3,-59,309700000,325000000,5600,5920,00:04:55,00:00:00
1788526664,14:57:44,14:57:44,7,132416,46304,cap-wifi3,-59,309700000,325000000,5600,5920,00:04:57,00:00:00
1788526666,14:57:46,14:57:46,8,462016,41704,cap-wifi3,-60,309700000,390000000,5600,6296,00:04:59,00:00:00
1788526668,14:57:48,14:57:48,11,129736,41416,cap-wifi3,-59,309700000,390000000,5600,5920,00:05:01,00:00:00
1788526670,14:57:50,14:57:51,14,401784,54464,cap-wifi3,-59,309700000,390000000,5600,5920,00:05:03,00:00:00
1788526672,14:57:52,14:57:53,8,146064,92728,cap-wifi3,-56,309700000,433300000,6640,7008,00:05:05,00:00:00
1788526674,14:57:54,14:57:55,14,111952,31488,cap-wifi3,-59,309700000,433300000,6160,6512,00:05:07,00:00:00
1788526677,14:57:57,14:57:57,9,123096,20552,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:09,00:00:00
1788526679,14:57:59,14:57:59,15,113008,17656,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:11,00:00:00
1788526681,14:58:01,14:58:01,16,172400,59040,cap-wifi3,-58,309700000,433300000,6160,6512,00:05:14,00:00:00
1788526683,14:58:03,14:58:03,10,190968,57448,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:16,00:00:00
1788526685,14:58:05,14:58:05,8,183848,56872,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:18,00:00:00
1788526687,14:58:07,14:58:07,9,305320,47576,cap-wifi3,-59,309700000,487500000,5600,5920,00:05:20,00:00:00
1788526689,14:58:09,14:58:09,20,331408,59856,cap-wifi3,-58,309700000,455800000,5600,5920,00:05:22,00:00:00
1788526691,14:58:11,14:58:11,10,322448,65576,cap-wifi3,-58,309700000,455800000,5600,5920,00:05:24,00:00:00
1788526692,14:58:12,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788526644 14:57:24 14:57:24 41 472232 195392 cap-wifi3 -57 309700000 325000000 2800 2960 00:04:37 00:00:00
3 1788526646 14:57:26 14:57:26 11 229864 36304 cap-wifi3 -57 309700000 325000000 2800 2960 00:04:39 00:00:00
4 1788526648 14:57:28 14:57:28 8 132384 26968 cap-wifi3 -59 309700000 309700000 6160 6512 00:04:41 00:00:00
5 1788526650 14:57:30 14:57:30 30 196672 48240 cap-wifi3 -59 309700000 344100000 6160 6512 00:04:43 00:00:00
6 1788526652 14:57:32 14:57:32 12 131304 37448 cap-wifi3 -59 309700000 344100000 6160 6512 00:04:45 00:00:00
7 1788526654 14:57:34 14:57:34 11 92000 18872 cap-wifi3 -59 309700000 412900000 5600 5920 00:04:47 00:00:00
8 1788526656 14:57:36 14:57:36 12 130144 24840 cap-wifi3 -60 309700000 390000000 6048 6512 00:04:49 00:00:00
9 1788526658 14:57:38 14:57:38 9 105160 20800 cap-wifi3 -60 309700000 390000000 6048 6512 00:04:51 00:00:00
10 1788526660 14:57:40 14:57:40 14 177144 59112 cap-wifi3 -57 309700000 344100000 6048 6288 00:04:53 00:00:00
11 1788526662 14:57:42 14:57:42 11 136152 39360 cap-wifi3 -59 309700000 325000000 5600 5920 00:04:55 00:00:00
12 1788526664 14:57:44 14:57:44 7 132416 46304 cap-wifi3 -59 309700000 325000000 5600 5920 00:04:57 00:00:00
13 1788526666 14:57:46 14:57:46 8 462016 41704 cap-wifi3 -60 309700000 390000000 5600 6296 00:04:59 00:00:00
14 1788526668 14:57:48 14:57:48 11 129736 41416 cap-wifi3 -59 309700000 390000000 5600 5920 00:05:01 00:00:00
15 1788526670 14:57:50 14:57:51 14 401784 54464 cap-wifi3 -59 309700000 390000000 5600 5920 00:05:03 00:00:00
16 1788526672 14:57:52 14:57:53 8 146064 92728 cap-wifi3 -56 309700000 433300000 6640 7008 00:05:05 00:00:00
17 1788526674 14:57:54 14:57:55 14 111952 31488 cap-wifi3 -59 309700000 433300000 6160 6512 00:05:07 00:00:00
18 1788526677 14:57:57 14:57:57 9 123096 20552 cap-wifi3 -57 309700000 433300000 6160 6512 00:05:09 00:00:00
19 1788526679 14:57:59 14:57:59 15 113008 17656 cap-wifi3 -57 309700000 433300000 6160 6512 00:05:11 00:00:00
20 1788526681 14:58:01 14:58:01 16 172400 59040 cap-wifi3 -58 309700000 433300000 6160 6512 00:05:14 00:00:00
21 1788526683 14:58:03 14:58:03 10 190968 57448 cap-wifi3 -59 309700000 433300000 5600 5920 00:05:16 00:00:00
22 1788526685 14:58:05 14:58:05 8 183848 56872 cap-wifi3 -59 309700000 433300000 5600 5920 00:05:18 00:00:00
23 1788526687 14:58:07 14:58:07 9 305320 47576 cap-wifi3 -59 309700000 487500000 5600 5920 00:05:20 00:00:00
24 1788526689 14:58:09 14:58:09 20 331408 59856 cap-wifi3 -58 309700000 455800000 5600 5920 00:05:22 00:00:00
25 1788526691 14:58:11 14:58:11 10 322448 65576 cap-wifi3 -58 309700000 455800000 5600 5920 00:05:24 00:00:00
26 1788526692 14:58:12 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-1er/sampler-iphone.csv (Takt 2s, Client F2:62:4C:E1:AF:09)

View File

@@ -0,0 +1 @@
14:58:12 Verbindung weg -- neuer Versuch in 2 s

View File

@@ -0,0 +1,26 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788526644,14:57:24,14:57:24,41,472232,195392,cap-wifi5,-61,137600000,229400000,2800,2960,01:04:55,00:00:00
1788526646,14:57:26,14:57:26,11,229864,36304,cap-wifi5,-59,172100000,229400000,2800,2960,01:04:57,00:00:00
1788526648,14:57:28,14:57:28,8,143088,22488,cap-wifi5,-60,172100000,229400000,2800,2368,01:04:59,00:00:00
1788526650,14:57:30,14:57:30,30,192288,49440,cap-wifi5,-60,172100000,229400000,2800,2368,01:05:01,00:00:00
1788526652,14:57:32,14:57:32,12,131304,37448,cap-wifi5,-60,172100000,229400000,3360,3552,01:05:03,00:00:00
1788526654,14:57:34,14:57:34,11,92000,18872,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:05,00:00:00
1788526656,14:57:36,14:57:36,12,130144,24840,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:07,00:00:00
1788526658,14:57:38,14:57:38,9,105160,20800,cap-wifi5,-59,129000000,258100000,3856,2960,01:05:09,00:00:00
1788526660,14:57:40,14:57:40,14,177144,59112,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:11,00:00:00
1788526662,14:57:42,14:57:42,11,136152,39360,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:13,00:00:00
1788526664,14:57:44,14:57:45,7,132416,46304,cap-wifi5,-57,114700000,206500000,3360,2960,01:05:15,00:00:00
1788526666,14:57:46,14:57:47,8,462016,41704,cap-wifi5,-57,114700000,206500000,2800,2960,01:05:17,00:00:00
1788526669,14:57:49,14:57:49,11,129736,41416,cap-wifi5,-57,154900000,172100000,3360,3552,01:05:19,00:00:00
1788526671,14:57:51,14:57:51,14,401784,54464,cap-wifi5,-57,154900000,172100000,3360,3552,01:05:21,00:00:00
1788526673,14:57:53,14:57:53,8,146064,92728,cap-wifi5,-58,154900000,206500000,2800,2960,01:05:23,00:00:00
1788526675,14:57:55,14:57:55,14,111952,31488,cap-wifi5,-58,154900000,229400000,2800,2960,01:05:26,00:00:00
1788526677,14:57:57,14:57:57,9,123096,20552,cap-wifi5,-58,154900000,229400000,2800,2960,01:05:28,00:00:00
1788526679,14:57:59,14:57:59,17,113008,17656,cap-wifi5,-58,103200000,229400000,2800,2960,01:05:30,00:00:00
1788526681,14:58:01,14:58:01,9,172400,59040,cap-wifi5,-58,103200000,206500000,3248,3328,01:05:32,00:00:00
1788526683,14:58:03,14:58:03,10,190968,57448,cap-wifi5,-58,103200000,206500000,3248,3328,01:05:34,00:00:00
1788526685,14:58:05,14:58:05,10,183848,56872,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:36,00:00:00
1788526687,14:58:07,14:58:07,9,305320,47576,cap-wifi5,-59,103200000,229400000,2800,2960,01:05:38,00:00:00
1788526689,14:58:09,14:58:09,20,331408,59856,cap-wifi5,-59,103200000,229400000,2800,2960,01:05:40,00:00:00
1788526691,14:58:11,14:58:11,10,322448,65576,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:42,00:00:00
1788526692,14:58:12,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788526644 14:57:24 14:57:24 41 472232 195392 cap-wifi5 -61 137600000 229400000 2800 2960 01:04:55 00:00:00
3 1788526646 14:57:26 14:57:26 11 229864 36304 cap-wifi5 -59 172100000 229400000 2800 2960 01:04:57 00:00:00
4 1788526648 14:57:28 14:57:28 8 143088 22488 cap-wifi5 -60 172100000 229400000 2800 2368 01:04:59 00:00:00
5 1788526650 14:57:30 14:57:30 30 192288 49440 cap-wifi5 -60 172100000 229400000 2800 2368 01:05:01 00:00:00
6 1788526652 14:57:32 14:57:32 12 131304 37448 cap-wifi5 -60 172100000 229400000 3360 3552 01:05:03 00:00:00
7 1788526654 14:57:34 14:57:34 11 92000 18872 cap-wifi5 -60 172100000 229400000 2800 2960 01:05:05 00:00:00
8 1788526656 14:57:36 14:57:36 12 130144 24840 cap-wifi5 -60 172100000 229400000 2800 2960 01:05:07 00:00:00
9 1788526658 14:57:38 14:57:38 9 105160 20800 cap-wifi5 -59 129000000 258100000 3856 2960 01:05:09 00:00:00
10 1788526660 14:57:40 14:57:40 14 177144 59112 cap-wifi5 -58 114700000 229400000 7888 15664 01:05:11 00:00:00
11 1788526662 14:57:42 14:57:42 11 136152 39360 cap-wifi5 -58 114700000 229400000 7888 15664 01:05:13 00:00:00
12 1788526664 14:57:44 14:57:45 7 132416 46304 cap-wifi5 -57 114700000 206500000 3360 2960 01:05:15 00:00:00
13 1788526666 14:57:46 14:57:47 8 462016 41704 cap-wifi5 -57 114700000 206500000 2800 2960 01:05:17 00:00:00
14 1788526669 14:57:49 14:57:49 11 129736 41416 cap-wifi5 -57 154900000 172100000 3360 3552 01:05:19 00:00:00
15 1788526671 14:57:51 14:57:51 14 401784 54464 cap-wifi5 -57 154900000 172100000 3360 3552 01:05:21 00:00:00
16 1788526673 14:57:53 14:57:53 8 146064 92728 cap-wifi5 -58 154900000 206500000 2800 2960 01:05:23 00:00:00
17 1788526675 14:57:55 14:57:55 14 111952 31488 cap-wifi5 -58 154900000 229400000 2800 2960 01:05:26 00:00:00
18 1788526677 14:57:57 14:57:57 9 123096 20552 cap-wifi5 -58 154900000 229400000 2800 2960 01:05:28 00:00:00
19 1788526679 14:57:59 14:57:59 17 113008 17656 cap-wifi5 -58 103200000 229400000 2800 2960 01:05:30 00:00:00
20 1788526681 14:58:01 14:58:01 9 172400 59040 cap-wifi5 -58 103200000 206500000 3248 3328 01:05:32 00:00:00
21 1788526683 14:58:03 14:58:03 10 190968 57448 cap-wifi5 -58 103200000 206500000 3248 3328 01:05:34 00:00:00
22 1788526685 14:58:05 14:58:05 10 183848 56872 cap-wifi5 -58 103200000 206500000 2800 2960 01:05:36 00:00:00
23 1788526687 14:58:07 14:58:07 9 305320 47576 cap-wifi5 -59 103200000 229400000 2800 2960 01:05:38 00:00:00
24 1788526689 14:58:09 14:58:09 20 331408 59856 cap-wifi5 -59 103200000 229400000 2800 2960 01:05:40 00:00:00
25 1788526691 14:58:11 14:58:11 10 322448 65576 cap-wifi5 -58 103200000 206500000 2800 2960 01:05:42 00:00:00
26 1788526692 14:58:12 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-1er/sampler-s22.csv (Takt 2s, Client 2A:0D:B0:5D:AD:A7)

View File

@@ -0,0 +1 @@
14:58:12 Verbindung weg -- neuer Versuch in 2 s

View File

@@ -0,0 +1,242 @@
ts_local,seq,ms
14:57:24,0,3ms102us
14:57:24,1,2ms682us
14:57:25,2,2ms739us
14:57:25,3,2ms889us
14:57:25,4,2ms955us
14:57:25,5,4ms434us
14:57:25,6,4ms59us
14:57:26,7,3ms540us
14:57:26,8,98ms220us
14:57:26,9,2ms841us
14:57:26,10,95ms173us
14:57:26,11,2ms688us
14:57:27,12,113ms888us
14:57:27,13,4ms866us
14:57:27,14,2ms909us
14:57:27,15,2ms776us
14:57:27,16,2ms572us
14:57:28,17,2ms931us
14:57:28,18,2ms663us
14:57:28,19,2ms796us
14:57:28,20,2ms736us
14:57:28,21,2ms826us
14:57:29,22,2ms778us
14:57:29,23,2ms741us
14:57:29,24,2ms904us
14:57:29,25,2ms744us
14:57:29,26,2ms845us
14:57:30,27,2ms850us
14:57:30,28,2ms746us
14:57:30,29,2ms973us
14:57:30,30,2ms907us
14:57:30,31,2ms771us
14:57:31,32,2ms778us
14:57:31,33,2ms793us
14:57:31,34,2ms823us
14:57:31,35,2ms717us
14:57:31,36,5ms311us
14:57:32,37,2ms752us
14:57:32,38,2ms799us
14:57:32,39,2ms964us
14:57:32,40,2ms760us
14:57:32,41,3ms53us
14:57:33,42,2ms775us
14:57:33,43,2ms793us
14:57:33,44,4ms125us
14:57:33,45,2ms696us
14:57:33,46,2ms686us
14:57:34,47,2ms738us
14:57:34,48,2ms824us
14:57:34,49,2ms607us
14:57:34,50,2ms944us
14:57:34,51,2ms854us
14:57:35,52,2ms724us
14:57:35,53,3ms453us
14:57:35,54,3ms417us
14:57:35,55,3ms535us
14:57:35,56,2ms719us
14:57:36,57,4ms498us
14:57:36,58,2ms706us
14:57:36,59,4ms279us
14:57:36,60,2ms836us
14:57:36,61,2ms646us
14:57:37,62,2ms873us
14:57:37,63,2ms782us
14:57:37,64,2ms624us
14:57:37,65,2ms881us
14:57:37,66,2ms716us
14:57:38,67,2ms763us
14:57:38,68,2ms833us
14:57:38,69,2ms879us
14:57:38,70,2ms851us
14:57:38,71,2ms777us
14:57:39,72,2ms937us
14:57:39,73,2ms821us
14:57:39,74,2ms729us
14:57:39,75,2ms892us
14:57:39,76,2ms729us
14:57:40,77,2ms755us
14:57:40,78,2ms932us
14:57:40,79,2ms701us
14:57:40,80,2ms662us
14:57:40,81,2ms651us
14:57:41,82,5ms991us
14:57:41,83,2ms728us
14:57:41,84,2ms756us
14:57:41,85,2ms716us
14:57:41,86,2ms707us
14:57:42,87,2ms785us
14:57:42,88,2ms594us
14:57:42,89,2ms747us
14:57:42,90,2ms712us
14:57:42,91,3ms258us
14:57:43,92,2ms727us
14:57:43,93,2ms623us
14:57:43,94,2ms723us
14:57:43,95,2ms749us
14:57:43,96,2ms700us
14:57:44,97,2ms723us
14:57:44,98,2ms735us
14:57:44,99,3ms646us
14:57:44,100,2ms718us
14:57:44,101,2ms740us
14:57:45,102,2ms768us
14:57:45,103,2ms663us
14:57:45,104,2ms639us
14:57:45,105,2ms731us
14:57:45,106,3ms290us
14:57:46,107,2ms822us
14:57:46,108,2ms844us
14:57:46,109,2ms617us
14:57:46,110,2ms734us
14:57:46,111,3ms447us
14:57:47,112,3ms169us
14:57:47,113,3ms247us
14:57:47,114,2ms564us
14:57:47,115,4ms516us
14:57:47,116,2ms623us
14:57:48,117,2ms675us
14:57:48,118,2ms877us
14:57:48,119,3ms310us
14:57:48,120,2ms851us
14:57:48,121,2ms803us
14:57:49,122,7ms998us
14:57:49,123,2ms887us
14:57:49,124,2ms852us
14:57:49,125,2ms846us
14:57:49,126,2ms899us
14:57:50,127,2ms913us
14:57:50,128,2ms680us
14:57:50,129,2ms715us
14:57:50,130,3ms374us
14:57:50,131,2ms670us
14:57:51,132,3ms148us
14:57:51,133,2ms932us
14:57:51,134,2ms831us
14:57:51,135,4ms780us
14:57:51,136,2ms911us
14:57:52,137,3ms85us
14:57:52,138,3ms589us
14:57:52,139,2ms697us
14:57:52,140,4ms876us
14:57:52,141,2ms867us
14:57:53,142,3ms283us
14:57:53,143,2ms710us
14:57:53,144,2ms801us
14:57:53,145,2ms928us
14:57:53,146,2ms640us
14:57:54,147,2ms678us
14:57:54,148,4ms976us
14:57:54,149,3ms408us
14:57:54,150,2ms706us
14:57:54,151,2ms827us
14:57:55,152,2ms884us
14:57:55,153,2ms855us
14:57:55,154,2ms787us
14:57:55,155,2ms695us
14:57:55,156,2ms902us
14:57:56,157,2ms749us
14:57:56,158,2ms838us
14:57:56,159,3ms937us
14:57:57,160,3ms43us
14:57:57,161,2ms870us
14:57:57,162,3ms357us
14:57:57,163,2ms756us
14:57:57,164,2ms679us
14:57:57,165,2ms863us
14:57:57,166,2ms768us
14:57:58,167,2ms858us
14:57:58,168,3ms30us
14:57:58,169,2ms677us
14:57:58,170,2ms725us
14:57:58,171,2ms919us
14:57:59,172,2ms688us
14:57:59,173,2ms821us
14:57:59,174,2ms805us
14:57:59,175,2ms709us
14:57:59,176,2ms989us
14:58:00,177,2ms589us
14:58:00,178,3ms835us
14:58:00,179,3ms194us
14:58:00,180,2ms662us
14:58:00,181,2ms686us
14:58:01,182,2ms704us
14:58:01,183,2ms752us
14:58:01,184,2ms656us
14:58:01,185,2ms904us
14:58:01,186,2ms823us
14:58:02,187,2ms656us
14:58:02,188,2ms813us
14:58:02,189,2ms644us
14:58:02,190,2ms782us
14:58:02,191,2ms722us
14:58:03,192,2ms674us
14:58:03,193,5ms657us
14:58:03,194,4ms701us
14:58:03,195,2ms772us
14:58:03,196,2ms661us
14:58:04,197,2ms660us
14:58:04,198,2ms859us
14:58:04,199,2ms800us
14:58:04,200,2ms706us
14:58:04,201,2ms847us
14:58:05,202,2ms625us
14:58:05,203,2ms816us
14:58:05,204,2ms703us
14:58:05,205,2ms818us
14:58:05,206,3ms162us
14:58:06,207,2ms673us
14:58:06,208,2ms781us
14:58:06,209,2ms607us
14:58:06,210,2ms990us
14:58:06,211,2ms602us
14:58:07,212,2ms711us
14:58:07,213,2ms819us
14:58:07,214,2ms757us
14:58:07,215,2ms605us
14:58:07,216,2ms770us
14:58:08,217,2ms682us
14:58:08,218,4ms824us
14:58:08,219,2ms623us
14:58:08,220,2ms566us
14:58:08,221,2ms724us
14:58:09,222,3ms737us
14:58:09,223,3ms273us
14:58:09,224,2ms809us
14:58:09,225,2ms619us
14:58:09,226,2ms709us
14:58:10,227,2ms909us
14:58:10,228,2ms707us
14:58:10,229,2ms909us
14:58:10,230,2ms610us
14:58:10,231,3ms251us
14:58:11,232,2ms689us
14:58:11,233,2ms714us
14:58:11,234,2ms680us
14:58:11,235,2ms644us
14:58:11,236,2ms665us
14:58:12,237,3ms326us
14:58:12,238,2ms749us
14:58:12,239,2ms713us
14:58:12,,RECONNECT
1 ts_local seq ms
2 14:57:24 0 3ms102us
3 14:57:24 1 2ms682us
4 14:57:25 2 2ms739us
5 14:57:25 3 2ms889us
6 14:57:25 4 2ms955us
7 14:57:25 5 4ms434us
8 14:57:25 6 4ms59us
9 14:57:26 7 3ms540us
10 14:57:26 8 98ms220us
11 14:57:26 9 2ms841us
12 14:57:26 10 95ms173us
13 14:57:26 11 2ms688us
14 14:57:27 12 113ms888us
15 14:57:27 13 4ms866us
16 14:57:27 14 2ms909us
17 14:57:27 15 2ms776us
18 14:57:27 16 2ms572us
19 14:57:28 17 2ms931us
20 14:57:28 18 2ms663us
21 14:57:28 19 2ms796us
22 14:57:28 20 2ms736us
23 14:57:28 21 2ms826us
24 14:57:29 22 2ms778us
25 14:57:29 23 2ms741us
26 14:57:29 24 2ms904us
27 14:57:29 25 2ms744us
28 14:57:29 26 2ms845us
29 14:57:30 27 2ms850us
30 14:57:30 28 2ms746us
31 14:57:30 29 2ms973us
32 14:57:30 30 2ms907us
33 14:57:30 31 2ms771us
34 14:57:31 32 2ms778us
35 14:57:31 33 2ms793us
36 14:57:31 34 2ms823us
37 14:57:31 35 2ms717us
38 14:57:31 36 5ms311us
39 14:57:32 37 2ms752us
40 14:57:32 38 2ms799us
41 14:57:32 39 2ms964us
42 14:57:32 40 2ms760us
43 14:57:32 41 3ms53us
44 14:57:33 42 2ms775us
45 14:57:33 43 2ms793us
46 14:57:33 44 4ms125us
47 14:57:33 45 2ms696us
48 14:57:33 46 2ms686us
49 14:57:34 47 2ms738us
50 14:57:34 48 2ms824us
51 14:57:34 49 2ms607us
52 14:57:34 50 2ms944us
53 14:57:34 51 2ms854us
54 14:57:35 52 2ms724us
55 14:57:35 53 3ms453us
56 14:57:35 54 3ms417us
57 14:57:35 55 3ms535us
58 14:57:35 56 2ms719us
59 14:57:36 57 4ms498us
60 14:57:36 58 2ms706us
61 14:57:36 59 4ms279us
62 14:57:36 60 2ms836us
63 14:57:36 61 2ms646us
64 14:57:37 62 2ms873us
65 14:57:37 63 2ms782us
66 14:57:37 64 2ms624us
67 14:57:37 65 2ms881us
68 14:57:37 66 2ms716us
69 14:57:38 67 2ms763us
70 14:57:38 68 2ms833us
71 14:57:38 69 2ms879us
72 14:57:38 70 2ms851us
73 14:57:38 71 2ms777us
74 14:57:39 72 2ms937us
75 14:57:39 73 2ms821us
76 14:57:39 74 2ms729us
77 14:57:39 75 2ms892us
78 14:57:39 76 2ms729us
79 14:57:40 77 2ms755us
80 14:57:40 78 2ms932us
81 14:57:40 79 2ms701us
82 14:57:40 80 2ms662us
83 14:57:40 81 2ms651us
84 14:57:41 82 5ms991us
85 14:57:41 83 2ms728us
86 14:57:41 84 2ms756us
87 14:57:41 85 2ms716us
88 14:57:41 86 2ms707us
89 14:57:42 87 2ms785us
90 14:57:42 88 2ms594us
91 14:57:42 89 2ms747us
92 14:57:42 90 2ms712us
93 14:57:42 91 3ms258us
94 14:57:43 92 2ms727us
95 14:57:43 93 2ms623us
96 14:57:43 94 2ms723us
97 14:57:43 95 2ms749us
98 14:57:43 96 2ms700us
99 14:57:44 97 2ms723us
100 14:57:44 98 2ms735us
101 14:57:44 99 3ms646us
102 14:57:44 100 2ms718us
103 14:57:44 101 2ms740us
104 14:57:45 102 2ms768us
105 14:57:45 103 2ms663us
106 14:57:45 104 2ms639us
107 14:57:45 105 2ms731us
108 14:57:45 106 3ms290us
109 14:57:46 107 2ms822us
110 14:57:46 108 2ms844us
111 14:57:46 109 2ms617us
112 14:57:46 110 2ms734us
113 14:57:46 111 3ms447us
114 14:57:47 112 3ms169us
115 14:57:47 113 3ms247us
116 14:57:47 114 2ms564us
117 14:57:47 115 4ms516us
118 14:57:47 116 2ms623us
119 14:57:48 117 2ms675us
120 14:57:48 118 2ms877us
121 14:57:48 119 3ms310us
122 14:57:48 120 2ms851us
123 14:57:48 121 2ms803us
124 14:57:49 122 7ms998us
125 14:57:49 123 2ms887us
126 14:57:49 124 2ms852us
127 14:57:49 125 2ms846us
128 14:57:49 126 2ms899us
129 14:57:50 127 2ms913us
130 14:57:50 128 2ms680us
131 14:57:50 129 2ms715us
132 14:57:50 130 3ms374us
133 14:57:50 131 2ms670us
134 14:57:51 132 3ms148us
135 14:57:51 133 2ms932us
136 14:57:51 134 2ms831us
137 14:57:51 135 4ms780us
138 14:57:51 136 2ms911us
139 14:57:52 137 3ms85us
140 14:57:52 138 3ms589us
141 14:57:52 139 2ms697us
142 14:57:52 140 4ms876us
143 14:57:52 141 2ms867us
144 14:57:53 142 3ms283us
145 14:57:53 143 2ms710us
146 14:57:53 144 2ms801us
147 14:57:53 145 2ms928us
148 14:57:53 146 2ms640us
149 14:57:54 147 2ms678us
150 14:57:54 148 4ms976us
151 14:57:54 149 3ms408us
152 14:57:54 150 2ms706us
153 14:57:54 151 2ms827us
154 14:57:55 152 2ms884us
155 14:57:55 153 2ms855us
156 14:57:55 154 2ms787us
157 14:57:55 155 2ms695us
158 14:57:55 156 2ms902us
159 14:57:56 157 2ms749us
160 14:57:56 158 2ms838us
161 14:57:56 159 3ms937us
162 14:57:57 160 3ms43us
163 14:57:57 161 2ms870us
164 14:57:57 162 3ms357us
165 14:57:57 163 2ms756us
166 14:57:57 164 2ms679us
167 14:57:57 165 2ms863us
168 14:57:57 166 2ms768us
169 14:57:58 167 2ms858us
170 14:57:58 168 3ms30us
171 14:57:58 169 2ms677us
172 14:57:58 170 2ms725us
173 14:57:58 171 2ms919us
174 14:57:59 172 2ms688us
175 14:57:59 173 2ms821us
176 14:57:59 174 2ms805us
177 14:57:59 175 2ms709us
178 14:57:59 176 2ms989us
179 14:58:00 177 2ms589us
180 14:58:00 178 3ms835us
181 14:58:00 179 3ms194us
182 14:58:00 180 2ms662us
183 14:58:00 181 2ms686us
184 14:58:01 182 2ms704us
185 14:58:01 183 2ms752us
186 14:58:01 184 2ms656us
187 14:58:01 185 2ms904us
188 14:58:01 186 2ms823us
189 14:58:02 187 2ms656us
190 14:58:02 188 2ms813us
191 14:58:02 189 2ms644us
192 14:58:02 190 2ms782us
193 14:58:02 191 2ms722us
194 14:58:03 192 2ms674us
195 14:58:03 193 5ms657us
196 14:58:03 194 4ms701us
197 14:58:03 195 2ms772us
198 14:58:03 196 2ms661us
199 14:58:04 197 2ms660us
200 14:58:04 198 2ms859us
201 14:58:04 199 2ms800us
202 14:58:04 200 2ms706us
203 14:58:04 201 2ms847us
204 14:58:05 202 2ms625us
205 14:58:05 203 2ms816us
206 14:58:05 204 2ms703us
207 14:58:05 205 2ms818us
208 14:58:05 206 3ms162us
209 14:58:06 207 2ms673us
210 14:58:06 208 2ms781us
211 14:58:06 209 2ms607us
212 14:58:06 210 2ms990us
213 14:58:06 211 2ms602us
214 14:58:07 212 2ms711us
215 14:58:07 213 2ms819us
216 14:58:07 214 2ms757us
217 14:58:07 215 2ms605us
218 14:58:07 216 2ms770us
219 14:58:08 217 2ms682us
220 14:58:08 218 4ms824us
221 14:58:08 219 2ms623us
222 14:58:08 220 2ms566us
223 14:58:08 221 2ms724us
224 14:58:09 222 3ms737us
225 14:58:09 223 3ms273us
226 14:58:09 224 2ms809us
227 14:58:09 225 2ms619us
228 14:58:09 226 2ms709us
229 14:58:10 227 2ms909us
230 14:58:10 228 2ms707us
231 14:58:10 229 2ms909us
232 14:58:10 230 2ms610us
233 14:58:10 231 3ms251us
234 14:58:11 232 2ms689us
235 14:58:11 233 2ms714us
236 14:58:11 234 2ms680us
237 14:58:11 235 2ms644us
238 14:58:11 236 2ms665us
239 14:58:12 237 3ms326us
240 14:58:12 238 2ms749us
241 14:58:12 239 2ms713us
242 14:58:12 RECONNECT

View File

@@ -0,0 +1,238 @@
ts_local,seq,ms
14:57:24,0,
14:57:25,1,
14:57:25,2,
14:57:25,3,
14:57:25,4,
14:57:25,5,
14:57:26,6,
14:57:26,7,
14:57:26,8,
14:57:26,9,
14:57:26,10,
14:57:27,11,
14:57:27,12,
14:57:27,13,
14:57:27,14,
14:57:27,15,unre...
14:57:28,16,
14:57:28,17,
14:57:28,18,
14:57:28,19,
14:57:28,20,
14:57:29,21,
14:57:29,22,
14:57:29,23,
14:57:29,24,
14:57:29,25,
14:57:30,26,
14:57:30,27,
14:57:30,28,
14:57:30,29,
14:57:30,30,
14:57:31,31,unre...
14:57:31,32,
14:57:31,33,
14:57:31,34,
14:57:31,35,
14:57:32,36,
14:57:32,37,
14:57:32,38,
14:57:32,39,
14:57:32,40,
14:57:33,41,
14:57:33,42,
14:57:33,43,
14:57:33,44,
14:57:33,45,
14:57:34,46,
14:57:34,47,unre...
14:57:34,48,
14:57:34,49,
14:57:34,50,
14:57:35,51,
14:57:35,52,
14:57:35,53,
14:57:35,54,
14:57:35,55,
14:57:36,56,
14:57:36,57,
14:57:36,58,
14:57:36,59,
14:57:37,60,
14:57:37,61,
14:57:37,62,
14:57:37,63,unre...
14:57:38,64,
14:57:38,65,
14:57:38,66,
14:57:38,67,
14:57:38,68,
14:57:38,69,
14:57:39,70,
14:57:39,71,
14:57:39,72,
14:57:39,73,
14:57:39,74,
14:57:40,75,
14:57:40,76,
14:57:40,77,
14:57:40,78,
14:57:40,79,unre...
14:57:41,80,
14:57:41,81,
14:57:41,82,
14:57:41,83,
14:57:41,84,
14:57:42,85,
14:57:42,86,
14:57:42,87,
14:57:42,88,
14:57:42,89,
14:57:43,90,
14:57:43,91,
14:57:43,92,
14:57:43,93,
14:57:43,94,
14:57:43,95,unre...
14:57:44,96,
14:57:44,97,
14:57:44,98,
14:57:44,99,
14:57:45,100,
14:57:45,101,
14:57:45,102,
14:57:45,103,
14:57:45,104,
14:57:46,105,
14:57:46,106,
14:57:46,107,
14:57:46,108,
14:57:46,109,
14:57:47,110,
14:57:47,111,unre...
14:57:47,112,
14:57:47,113,
14:57:47,114,
14:57:48,115,
14:57:48,116,
14:57:48,117,
14:57:48,118,
14:57:49,119,
14:57:49,120,
14:57:49,121,
14:57:49,122,
14:57:49,123,
14:57:50,124,
14:57:50,125,
14:57:50,126,
14:57:50,127,unre...
14:57:50,128,
14:57:51,129,
14:57:51,130,
14:57:51,131,
14:57:51,132,
14:57:51,133,
14:57:52,134,
14:57:52,135,
14:57:52,136,
14:57:52,137,
14:57:52,138,
14:57:53,139,
14:57:53,140,
14:57:53,141,
14:57:53,142,
14:57:53,143,unre...
14:57:54,144,
14:57:54,145,
14:57:54,146,
14:57:54,147,
14:57:54,148,
14:57:55,149,
14:57:55,150,
14:57:55,151,
14:57:55,152,
14:57:55,153,
14:57:56,154,
14:57:56,155,
14:57:56,156,
14:57:57,157,
14:57:57,158,
14:57:57,159,unre...
14:57:57,160,
14:57:57,161,
14:57:57,162,
14:57:57,163,
14:57:58,164,
14:57:58,165,
14:57:58,166,
14:57:58,167,
14:57:58,168,
14:57:59,169,
14:57:59,170,
14:57:59,171,
14:57:59,172,
14:57:59,173,
14:58:00,174,
14:58:00,175,unre...
14:58:00,176,
14:58:00,177,
14:58:00,178,
14:58:01,179,
14:58:01,180,
14:58:01,181,
14:58:01,182,
14:58:01,183,
14:58:02,184,
14:58:02,185,
14:58:02,186,
14:58:02,187,
14:58:02,188,
14:58:03,189,
14:58:03,190,
14:58:03,191,unre...
14:58:03,192,
14:58:03,193,
14:58:04,194,
14:58:04,195,
14:58:04,196,
14:58:04,197,
14:58:04,198,
14:58:05,199,
14:58:05,200,
14:58:05,201,
14:58:05,202,
14:58:05,203,
14:58:06,204,
14:58:06,205,
14:58:06,206,
14:58:06,207,unre...
14:58:07,208,
14:58:07,209,
14:58:07,210,
14:58:07,211,
14:58:07,212,
14:58:08,213,
14:58:08,214,
14:58:08,215,
14:58:08,216,
14:58:08,217,
14:58:09,218,
14:58:09,219,
14:58:09,220,
14:58:09,221,
14:58:09,222,
14:58:09,223,unre...
14:58:10,224,
14:58:10,225,
14:58:10,226,
14:58:10,227,
14:58:11,228,
14:58:11,229,
14:58:11,230,
14:58:11,231,
14:58:11,232,
14:58:12,233,
14:58:12,234,
14:58:12,235,
14:58:12,,RECONNECT
1 ts_local seq ms
2 14:57:24 0
3 14:57:25 1
4 14:57:25 2
5 14:57:25 3
6 14:57:25 4
7 14:57:25 5
8 14:57:26 6
9 14:57:26 7
10 14:57:26 8
11 14:57:26 9
12 14:57:26 10
13 14:57:27 11
14 14:57:27 12
15 14:57:27 13
16 14:57:27 14
17 14:57:27 15 unre...
18 14:57:28 16
19 14:57:28 17
20 14:57:28 18
21 14:57:28 19
22 14:57:28 20
23 14:57:29 21
24 14:57:29 22
25 14:57:29 23
26 14:57:29 24
27 14:57:29 25
28 14:57:30 26
29 14:57:30 27
30 14:57:30 28
31 14:57:30 29
32 14:57:30 30
33 14:57:31 31 unre...
34 14:57:31 32
35 14:57:31 33
36 14:57:31 34
37 14:57:31 35
38 14:57:32 36
39 14:57:32 37
40 14:57:32 38
41 14:57:32 39
42 14:57:32 40
43 14:57:33 41
44 14:57:33 42
45 14:57:33 43
46 14:57:33 44
47 14:57:33 45
48 14:57:34 46
49 14:57:34 47 unre...
50 14:57:34 48
51 14:57:34 49
52 14:57:34 50
53 14:57:35 51
54 14:57:35 52
55 14:57:35 53
56 14:57:35 54
57 14:57:35 55
58 14:57:36 56
59 14:57:36 57
60 14:57:36 58
61 14:57:36 59
62 14:57:37 60
63 14:57:37 61
64 14:57:37 62
65 14:57:37 63 unre...
66 14:57:38 64
67 14:57:38 65
68 14:57:38 66
69 14:57:38 67
70 14:57:38 68
71 14:57:38 69
72 14:57:39 70
73 14:57:39 71
74 14:57:39 72
75 14:57:39 73
76 14:57:39 74
77 14:57:40 75
78 14:57:40 76
79 14:57:40 77
80 14:57:40 78
81 14:57:40 79 unre...
82 14:57:41 80
83 14:57:41 81
84 14:57:41 82
85 14:57:41 83
86 14:57:41 84
87 14:57:42 85
88 14:57:42 86
89 14:57:42 87
90 14:57:42 88
91 14:57:42 89
92 14:57:43 90
93 14:57:43 91
94 14:57:43 92
95 14:57:43 93
96 14:57:43 94
97 14:57:43 95 unre...
98 14:57:44 96
99 14:57:44 97
100 14:57:44 98
101 14:57:44 99
102 14:57:45 100
103 14:57:45 101
104 14:57:45 102
105 14:57:45 103
106 14:57:45 104
107 14:57:46 105
108 14:57:46 106
109 14:57:46 107
110 14:57:46 108
111 14:57:46 109
112 14:57:47 110
113 14:57:47 111 unre...
114 14:57:47 112
115 14:57:47 113
116 14:57:47 114
117 14:57:48 115
118 14:57:48 116
119 14:57:48 117
120 14:57:48 118
121 14:57:49 119
122 14:57:49 120
123 14:57:49 121
124 14:57:49 122
125 14:57:49 123
126 14:57:50 124
127 14:57:50 125
128 14:57:50 126
129 14:57:50 127 unre...
130 14:57:50 128
131 14:57:51 129
132 14:57:51 130
133 14:57:51 131
134 14:57:51 132
135 14:57:51 133
136 14:57:52 134
137 14:57:52 135
138 14:57:52 136
139 14:57:52 137
140 14:57:52 138
141 14:57:53 139
142 14:57:53 140
143 14:57:53 141
144 14:57:53 142
145 14:57:53 143 unre...
146 14:57:54 144
147 14:57:54 145
148 14:57:54 146
149 14:57:54 147
150 14:57:54 148
151 14:57:55 149
152 14:57:55 150
153 14:57:55 151
154 14:57:55 152
155 14:57:55 153
156 14:57:56 154
157 14:57:56 155
158 14:57:56 156
159 14:57:57 157
160 14:57:57 158
161 14:57:57 159 unre...
162 14:57:57 160
163 14:57:57 161
164 14:57:57 162
165 14:57:57 163
166 14:57:58 164
167 14:57:58 165
168 14:57:58 166
169 14:57:58 167
170 14:57:58 168
171 14:57:59 169
172 14:57:59 170
173 14:57:59 171
174 14:57:59 172
175 14:57:59 173
176 14:58:00 174
177 14:58:00 175 unre...
178 14:58:00 176
179 14:58:00 177
180 14:58:00 178
181 14:58:01 179
182 14:58:01 180
183 14:58:01 181
184 14:58:01 182
185 14:58:01 183
186 14:58:02 184
187 14:58:02 185
188 14:58:02 186
189 14:58:02 187
190 14:58:02 188
191 14:58:03 189
192 14:58:03 190
193 14:58:03 191 unre...
194 14:58:03 192
195 14:58:03 193
196 14:58:04 194
197 14:58:04 195
198 14:58:04 196
199 14:58:04 197
200 14:58:04 198
201 14:58:05 199
202 14:58:05 200
203 14:58:05 201
204 14:58:05 202
205 14:58:05 203
206 14:58:06 204
207 14:58:06 205
208 14:58:06 206
209 14:58:06 207 unre...
210 14:58:07 208
211 14:58:07 209
212 14:58:07 210
213 14:58:07 211
214 14:58:07 212
215 14:58:08 213
216 14:58:08 214
217 14:58:08 215
218 14:58:08 216
219 14:58:08 217
220 14:58:09 218
221 14:58:09 219
222 14:58:09 220
223 14:58:09 221
224 14:58:09 222
225 14:58:09 223 unre...
226 14:58:10 224
227 14:58:10 225
228 14:58:10 226
229 14:58:10 227
230 14:58:11 228
231 14:58:11 229
232 14:58:11 230
233 14:58:11 231
234 14:58:11 232
235 14:58:12 233
236 14:58:12 234
237 14:58:12 235
238 14:58:12 RECONNECT

View File

@@ -0,0 +1,6 @@
cap-wifi1=ap2/5GHz
cap-wifi2=ap3/5GHz
cap-wifi3=ap1/5GHz
cap-wifi4=ap3/2,4GHz
cap-wifi5=ap1/2,4GHz
cap-wifi6=ap2/2,4GHz

View File

@@ -0,0 +1 @@
ts_epoch,ts_local,marker
1 ts_epoch ts_local marker

View File

@@ -0,0 +1,43 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788526610,14:56:50,14:56:50,50,160216,1109704,cap-wifi2,-69,137600000,275300000,45848,2240,01:04:23,00:00:00
1788526612,14:56:52,14:56:52,6,151312,62480,cap-wifi2,-69,137600000,275300000,45848,2240,01:04:25,00:00:00
1788526614,14:56:54,14:56:54,15,127416,44832,cap-wifi2,-69,137600000,309700000,36152,6320,01:04:27,00:00:00
1788526616,14:56:56,14:56:56,4,127712,21960,cap-wifi2,-69,103200000,325000000,42008,9736,01:04:29,00:00:00
1788526618,14:56:58,14:56:58,9,157888,29816,cap-wifi2,-69,103200000,325000000,42008,9736,01:04:31,00:00:00
1788526620,14:57:00,14:57:00,16,322208,124400,cap-wifi2,-69,103200000,344100000,123600,58608,01:04:33,00:00:00
1788526622,14:57:02,14:57:03,10,451416,4332552,cap-wifi2,-69,137600000,275300000,193568,29704,01:04:35,00:00:00
1788526624,14:57:04,14:57:05,9,398720,136640,cap-wifi2,-69,137600000,292500000,40792,7440,01:04:37,00:00:00
1788526627,14:57:07,14:57:07,15,947800,446984,cap-wifi2,-69,137600000,292500000,40792,7440,01:04:40,00:00:00
1788526629,14:57:09,14:57:09,12,7610296,3321592,cap-wifi2,-69,154900000,292500000,89400,14304,01:04:42,00:00:00
1788526631,14:57:11,14:57:11,18,2720136,2091232,cap-wifi2,-69,103200000,275300000,69264,10760,01:04:44,00:00:00
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi2,-69,103200000,275300000,69264,10760,01:04:46,00:00:00
1788526635,14:57:15,14:57:15,7,108584,42016,cap-wifi2,-69,103200000,309700000,78112,11920,01:04:48,00:00:00
1788526637,14:57:17,14:57:17,4,309312,51096,cap-wifi2,-68,103200000,309700000,117392,10152,01:04:50,00:00:00
1788526639,14:57:19,14:57:19,14,309864,66576,cap-wifi2,-68,103200000,309700000,117392,10152,01:04:52,00:00:00
1788526641,14:57:21,14:57:21,6,150056,22800,cap-wifi2,-68,103200000,309700000,53888,10272,01:04:54,00:00:00
1788526643,14:57:23,14:57:23,14,510016,213944,cap-wifi2,-68,103200000,309700000,61328,9088,01:04:56,00:00:00
1788526645,14:57:25,14:57:25,19,507656,169768,cap-wifi2,-68,103200000,309700000,61328,9088,01:04:58,00:00:00
1788526647,14:57:27,14:57:27,9,136752,33856,cap-wifi2,-69,103200000,309700000,41640,8560,01:05:00,00:00:00
1788526649,14:57:29,14:57:29,18,143088,22488,cap-wifi2,-69,103200000,292500000,61120,8192,01:05:02,00:00:00
1788526651,14:57:31,14:57:31,15,192288,49440,cap-wifi2,-69,103200000,292500000,61120,8192,01:05:04,00:00:00
1788526653,14:57:33,14:57:33,9,131304,37448,cap-wifi2,-69,137600000,309700000,57760,8136,01:05:06,00:00:00
1788526655,14:57:35,14:57:35,11,92000,18872,cap-wifi2,-69,137600000,344100000,56408,8592,01:05:08,00:00:00
1788526657,14:57:37,14:57:37,9,130144,24840,cap-wifi2,-69,137600000,344100000,56408,8592,01:05:10,00:00:00
1788526659,14:57:39,14:57:39,20,105160,20800,cap-wifi2,-69,137600000,325000000,19344,5200,01:05:12,00:00:00
1788526661,14:57:41,14:57:41,11,177144,59112,cap-wifi2,-71,154900000,275300000,111184,14496,01:05:14,00:00:00
1788526663,14:57:43,14:57:43,16,136152,39360,cap-wifi2,-71,154900000,275300000,111184,14496,01:05:16,00:00:00
1788526665,14:57:45,14:57:45,16,132416,46304,cap-wifi2,-70,154900000,309700000,44928,8560,01:05:18,00:00:00
1788526667,14:57:47,14:57:47,11,462016,41704,cap-wifi2,-70,154900000,309700000,397536,18704,01:05:20,00:00:00
1788526669,14:57:49,14:57:49,24,129736,41416,cap-wifi2,-70,154900000,309700000,397536,18704,01:05:22,00:00:00
1788526671,14:57:51,14:57:51,7,401784,54464,cap-wifi2,-76,103200000,206500000,44784,8560,01:05:24,00:00:00
1788526673,14:57:53,14:57:53,14,101992,21720,cap-wifi2,-69,103200000,292500000,55400,9120,01:05:26,00:00:00
1788526675,14:57:55,14:57:55,14,152504,61272,cap-wifi2,-69,103200000,292500000,55400,9120,01:05:28,00:00:00
1788526677,14:57:57,14:57:57,22,130520,26552,cap-wifi2,-70,103200000,260000000,55304,10816,01:05:30,00:00:00
1788526679,14:57:59,14:57:59,17,155408,24688,cap-wifi2,-69,103200000,275300000,58480,8720,01:05:32,00:00:00
1788526681,14:58:01,14:58:01,9,244456,41424,cap-wifi2,-69,103200000,275300000,58480,8720,01:05:34,00:00:00
1788526683,14:58:03,14:58:03,10,115640,26032,cap-wifi2,-69,103200000,260000000,38208,22096,01:05:36,00:00:00
1788526685,14:58:05,14:58:05,10,154824,24456,cap-wifi2,-70,137600000,260000000,65000,8000,01:05:38,00:00:00
1788526687,14:58:07,14:58:07,9,135144,25000,cap-wifi2,-70,137600000,260000000,65000,8000,01:05:40,00:00:00
1788526689,14:58:09,14:58:10,20,122800,29936,cap-wifi2,-68,137600000,275300000,18856,4048,01:05:42,00:00:00
1788526691,14:58:11,14:58:12,10,152160,65768,cap-wifi2,-68,137600000,206500000,40064,12024,01:05:44,00:00:00
1788526692,14:58:12,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788526610 14:56:50 14:56:50 50 160216 1109704 cap-wifi2 -69 137600000 275300000 45848 2240 01:04:23 00:00:00
3 1788526612 14:56:52 14:56:52 6 151312 62480 cap-wifi2 -69 137600000 275300000 45848 2240 01:04:25 00:00:00
4 1788526614 14:56:54 14:56:54 15 127416 44832 cap-wifi2 -69 137600000 309700000 36152 6320 01:04:27 00:00:00
5 1788526616 14:56:56 14:56:56 4 127712 21960 cap-wifi2 -69 103200000 325000000 42008 9736 01:04:29 00:00:00
6 1788526618 14:56:58 14:56:58 9 157888 29816 cap-wifi2 -69 103200000 325000000 42008 9736 01:04:31 00:00:00
7 1788526620 14:57:00 14:57:00 16 322208 124400 cap-wifi2 -69 103200000 344100000 123600 58608 01:04:33 00:00:00
8 1788526622 14:57:02 14:57:03 10 451416 4332552 cap-wifi2 -69 137600000 275300000 193568 29704 01:04:35 00:00:00
9 1788526624 14:57:04 14:57:05 9 398720 136640 cap-wifi2 -69 137600000 292500000 40792 7440 01:04:37 00:00:00
10 1788526627 14:57:07 14:57:07 15 947800 446984 cap-wifi2 -69 137600000 292500000 40792 7440 01:04:40 00:00:00
11 1788526629 14:57:09 14:57:09 12 7610296 3321592 cap-wifi2 -69 154900000 292500000 89400 14304 01:04:42 00:00:00
12 1788526631 14:57:11 14:57:11 18 2720136 2091232 cap-wifi2 -69 103200000 275300000 69264 10760 01:04:44 00:00:00
13 1788526633 14:57:13 14:57:13 9 2261568 2680088 cap-wifi2 -69 103200000 275300000 69264 10760 01:04:46 00:00:00
14 1788526635 14:57:15 14:57:15 7 108584 42016 cap-wifi2 -69 103200000 309700000 78112 11920 01:04:48 00:00:00
15 1788526637 14:57:17 14:57:17 4 309312 51096 cap-wifi2 -68 103200000 309700000 117392 10152 01:04:50 00:00:00
16 1788526639 14:57:19 14:57:19 14 309864 66576 cap-wifi2 -68 103200000 309700000 117392 10152 01:04:52 00:00:00
17 1788526641 14:57:21 14:57:21 6 150056 22800 cap-wifi2 -68 103200000 309700000 53888 10272 01:04:54 00:00:00
18 1788526643 14:57:23 14:57:23 14 510016 213944 cap-wifi2 -68 103200000 309700000 61328 9088 01:04:56 00:00:00
19 1788526645 14:57:25 14:57:25 19 507656 169768 cap-wifi2 -68 103200000 309700000 61328 9088 01:04:58 00:00:00
20 1788526647 14:57:27 14:57:27 9 136752 33856 cap-wifi2 -69 103200000 309700000 41640 8560 01:05:00 00:00:00
21 1788526649 14:57:29 14:57:29 18 143088 22488 cap-wifi2 -69 103200000 292500000 61120 8192 01:05:02 00:00:00
22 1788526651 14:57:31 14:57:31 15 192288 49440 cap-wifi2 -69 103200000 292500000 61120 8192 01:05:04 00:00:00
23 1788526653 14:57:33 14:57:33 9 131304 37448 cap-wifi2 -69 137600000 309700000 57760 8136 01:05:06 00:00:00
24 1788526655 14:57:35 14:57:35 11 92000 18872 cap-wifi2 -69 137600000 344100000 56408 8592 01:05:08 00:00:00
25 1788526657 14:57:37 14:57:37 9 130144 24840 cap-wifi2 -69 137600000 344100000 56408 8592 01:05:10 00:00:00
26 1788526659 14:57:39 14:57:39 20 105160 20800 cap-wifi2 -69 137600000 325000000 19344 5200 01:05:12 00:00:00
27 1788526661 14:57:41 14:57:41 11 177144 59112 cap-wifi2 -71 154900000 275300000 111184 14496 01:05:14 00:00:00
28 1788526663 14:57:43 14:57:43 16 136152 39360 cap-wifi2 -71 154900000 275300000 111184 14496 01:05:16 00:00:00
29 1788526665 14:57:45 14:57:45 16 132416 46304 cap-wifi2 -70 154900000 309700000 44928 8560 01:05:18 00:00:00
30 1788526667 14:57:47 14:57:47 11 462016 41704 cap-wifi2 -70 154900000 309700000 397536 18704 01:05:20 00:00:00
31 1788526669 14:57:49 14:57:49 24 129736 41416 cap-wifi2 -70 154900000 309700000 397536 18704 01:05:22 00:00:00
32 1788526671 14:57:51 14:57:51 7 401784 54464 cap-wifi2 -76 103200000 206500000 44784 8560 01:05:24 00:00:00
33 1788526673 14:57:53 14:57:53 14 101992 21720 cap-wifi2 -69 103200000 292500000 55400 9120 01:05:26 00:00:00
34 1788526675 14:57:55 14:57:55 14 152504 61272 cap-wifi2 -69 103200000 292500000 55400 9120 01:05:28 00:00:00
35 1788526677 14:57:57 14:57:57 22 130520 26552 cap-wifi2 -70 103200000 260000000 55304 10816 01:05:30 00:00:00
36 1788526679 14:57:59 14:57:59 17 155408 24688 cap-wifi2 -69 103200000 275300000 58480 8720 01:05:32 00:00:00
37 1788526681 14:58:01 14:58:01 9 244456 41424 cap-wifi2 -69 103200000 275300000 58480 8720 01:05:34 00:00:00
38 1788526683 14:58:03 14:58:03 10 115640 26032 cap-wifi2 -69 103200000 260000000 38208 22096 01:05:36 00:00:00
39 1788526685 14:58:05 14:58:05 10 154824 24456 cap-wifi2 -70 137600000 260000000 65000 8000 01:05:38 00:00:00
40 1788526687 14:58:07 14:58:07 9 135144 25000 cap-wifi2 -70 137600000 260000000 65000 8000 01:05:40 00:00:00
41 1788526689 14:58:09 14:58:10 20 122800 29936 cap-wifi2 -68 137600000 275300000 18856 4048 01:05:42 00:00:00
42 1788526691 14:58:11 14:58:12 10 152160 65768 cap-wifi2 -68 137600000 206500000 40064 12024 01:05:44 00:00:00
43 1788526692 14:58:12 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-ipad.csv (Takt 2s, Client CA:B8:D4:3F:8A:81)

View File

@@ -0,0 +1,43 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788526610,14:56:50,14:56:50,50,160216,1109704,cap-wifi3,-58,309700000,412900000,0,0,00:04:03,00:00:03.010
1788526612,14:56:52,14:56:52,6,151312,62480,cap-wifi3,-57,309700000,412900000,0,0,00:04:05,00:00:00
1788526614,14:56:54,14:56:54,15,127416,44832,cap-wifi3,-57,309700000,412900000,2800,2960,00:04:07,00:00:00
1788526616,14:56:56,14:56:56,4,127712,21960,cap-wifi3,-57,309700000,412900000,2800,2960,00:04:09,00:00:00
1788526618,14:56:58,14:56:58,9,157888,29816,cap-wifi3,-57,309700000,412900000,3248,3552,00:04:11,00:00:00
1788526620,14:57:00,14:57:00,16,322208,124400,cap-wifi3,-57,344100000,325000000,3360,3552,00:04:13,00:00:00
1788526622,14:57:02,14:57:03,10,451416,4332552,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:15,00:00:00
1788526624,14:57:04,14:57:05,9,398720,136640,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:17,00:00:00
1788526627,14:57:07,14:57:07,15,947800,446984,cap-wifi3,-59,344100000,325000000,3360,3552,00:04:20,00:00:00
1788526629,14:57:09,14:57:09,12,7610296,3321592,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:22,00:00:00
1788526631,14:57:11,14:57:11,18,2720136,2091232,cap-wifi3,-58,344100000,344100000,2800,2960,00:04:24,00:00:00
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi3,-57,344100000,325000000,3360,3552,00:04:26,00:00:00
1788526635,14:57:15,14:57:15,7,108584,42016,cap-wifi3,-57,344100000,344100000,2800,2960,00:04:28,00:00:00
1788526637,14:57:17,14:57:17,4,309312,51096,cap-wifi3,-57,344100000,344100000,2800,2960,00:04:30,00:00:00
1788526639,14:57:19,14:57:19,14,309864,66576,cap-wifi3,-58,344100000,325000000,2800,2960,00:04:32,00:00:00
1788526641,14:57:21,14:57:21,6,150056,22800,cap-wifi3,-57,309700000,344100000,3808,4000,00:04:34,00:00:00
1788526643,14:57:23,14:57:23,14,510016,213944,cap-wifi3,-57,309700000,344100000,3808,4000,00:04:36,00:00:00
1788526645,14:57:25,14:57:25,19,507656,169768,cap-wifi3,-57,309700000,325000000,2800,2960,00:04:38,00:00:00
1788526647,14:57:27,14:57:27,9,136752,33856,cap-wifi3,-59,309700000,309700000,6160,6512,00:04:40,00:00:00
1788526649,14:57:29,14:57:29,18,143088,22488,cap-wifi3,-59,309700000,309700000,6160,6512,00:04:42,00:00:00
1788526651,14:57:31,14:57:31,15,192288,49440,cap-wifi3,-59,309700000,344100000,6160,6512,00:04:44,00:00:00
1788526653,14:57:33,14:57:33,9,131304,37448,cap-wifi3,-59,309700000,412900000,5600,5920,00:04:46,00:00:00
1788526655,14:57:35,14:57:35,11,92000,18872,cap-wifi3,-59,309700000,412900000,5600,5920,00:04:48,00:00:00
1788526657,14:57:37,14:57:37,9,130144,24840,cap-wifi3,-60,309700000,390000000,6048,6512,00:04:50,00:00:00
1788526659,14:57:39,14:57:39,20,105160,20800,cap-wifi3,-57,309700000,344100000,6048,6288,00:04:52,00:00:00
1788526661,14:57:41,14:57:41,11,177144,59112,cap-wifi3,-57,309700000,344100000,6048,6288,00:04:54,00:00:00
1788526663,14:57:43,14:57:43,16,136152,39360,cap-wifi3,-59,309700000,325000000,5600,5920,00:04:56,00:00:00
1788526665,14:57:45,14:57:45,16,132416,46304,cap-wifi3,-60,309700000,390000000,5600,6296,00:04:58,00:00:00
1788526667,14:57:47,14:57:47,11,462016,41704,cap-wifi3,-60,309700000,390000000,5600,6296,00:05:00,00:00:00
1788526669,14:57:49,14:57:49,24,129736,41416,cap-wifi3,-59,309700000,390000000,5600,5920,00:05:02,00:00:00
1788526671,14:57:51,14:57:51,7,234376,122480,cap-wifi3,-56,309700000,433300000,6640,7008,00:05:04,00:00:00
1788526673,14:57:53,14:57:53,14,101992,21720,cap-wifi3,-56,309700000,433300000,6640,7008,00:05:06,00:00:00
1788526675,14:57:55,14:57:55,14,152504,61272,cap-wifi3,-59,309700000,433300000,6160,6512,00:05:08,00:00:00
1788526677,14:57:57,14:57:57,22,130520,26552,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:10,00:00:00
1788526679,14:57:59,14:57:59,17,155408,24688,cap-wifi3,-57,309700000,433300000,6160,6512,00:05:12,00:00:00
1788526681,14:58:01,14:58:01,9,244456,41424,cap-wifi3,-58,309700000,433300000,6160,6512,00:05:14,00:00:00
1788526683,14:58:03,14:58:03,10,115640,26032,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:16,00:00:00
1788526685,14:58:05,14:58:05,10,154824,24456,cap-wifi3,-59,309700000,433300000,5600,5920,00:05:18,00:00:00
1788526687,14:58:07,14:58:08,9,135144,25000,cap-wifi3,-59,309700000,487500000,5600,5920,00:05:20,00:00:00
1788526689,14:58:09,14:58:10,20,122800,29936,cap-wifi3,-58,309700000,455800000,5600,5920,00:05:22,00:00:00
1788526691,14:58:11,14:58:12,10,152160,65768,cap-wifi3,-58,309700000,455800000,6160,6512,00:05:24,00:00:00
1788526692,14:58:12,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788526610 14:56:50 14:56:50 50 160216 1109704 cap-wifi3 -58 309700000 412900000 0 0 00:04:03 00:00:03.010
3 1788526612 14:56:52 14:56:52 6 151312 62480 cap-wifi3 -57 309700000 412900000 0 0 00:04:05 00:00:00
4 1788526614 14:56:54 14:56:54 15 127416 44832 cap-wifi3 -57 309700000 412900000 2800 2960 00:04:07 00:00:00
5 1788526616 14:56:56 14:56:56 4 127712 21960 cap-wifi3 -57 309700000 412900000 2800 2960 00:04:09 00:00:00
6 1788526618 14:56:58 14:56:58 9 157888 29816 cap-wifi3 -57 309700000 412900000 3248 3552 00:04:11 00:00:00
7 1788526620 14:57:00 14:57:00 16 322208 124400 cap-wifi3 -57 344100000 325000000 3360 3552 00:04:13 00:00:00
8 1788526622 14:57:02 14:57:03 10 451416 4332552 cap-wifi3 -58 344100000 344100000 2800 2960 00:04:15 00:00:00
9 1788526624 14:57:04 14:57:05 9 398720 136640 cap-wifi3 -58 344100000 344100000 2800 2960 00:04:17 00:00:00
10 1788526627 14:57:07 14:57:07 15 947800 446984 cap-wifi3 -59 344100000 325000000 3360 3552 00:04:20 00:00:00
11 1788526629 14:57:09 14:57:09 12 7610296 3321592 cap-wifi3 -58 344100000 344100000 2800 2960 00:04:22 00:00:00
12 1788526631 14:57:11 14:57:11 18 2720136 2091232 cap-wifi3 -58 344100000 344100000 2800 2960 00:04:24 00:00:00
13 1788526633 14:57:13 14:57:13 9 2261568 2680088 cap-wifi3 -57 344100000 325000000 3360 3552 00:04:26 00:00:00
14 1788526635 14:57:15 14:57:15 7 108584 42016 cap-wifi3 -57 344100000 344100000 2800 2960 00:04:28 00:00:00
15 1788526637 14:57:17 14:57:17 4 309312 51096 cap-wifi3 -57 344100000 344100000 2800 2960 00:04:30 00:00:00
16 1788526639 14:57:19 14:57:19 14 309864 66576 cap-wifi3 -58 344100000 325000000 2800 2960 00:04:32 00:00:00
17 1788526641 14:57:21 14:57:21 6 150056 22800 cap-wifi3 -57 309700000 344100000 3808 4000 00:04:34 00:00:00
18 1788526643 14:57:23 14:57:23 14 510016 213944 cap-wifi3 -57 309700000 344100000 3808 4000 00:04:36 00:00:00
19 1788526645 14:57:25 14:57:25 19 507656 169768 cap-wifi3 -57 309700000 325000000 2800 2960 00:04:38 00:00:00
20 1788526647 14:57:27 14:57:27 9 136752 33856 cap-wifi3 -59 309700000 309700000 6160 6512 00:04:40 00:00:00
21 1788526649 14:57:29 14:57:29 18 143088 22488 cap-wifi3 -59 309700000 309700000 6160 6512 00:04:42 00:00:00
22 1788526651 14:57:31 14:57:31 15 192288 49440 cap-wifi3 -59 309700000 344100000 6160 6512 00:04:44 00:00:00
23 1788526653 14:57:33 14:57:33 9 131304 37448 cap-wifi3 -59 309700000 412900000 5600 5920 00:04:46 00:00:00
24 1788526655 14:57:35 14:57:35 11 92000 18872 cap-wifi3 -59 309700000 412900000 5600 5920 00:04:48 00:00:00
25 1788526657 14:57:37 14:57:37 9 130144 24840 cap-wifi3 -60 309700000 390000000 6048 6512 00:04:50 00:00:00
26 1788526659 14:57:39 14:57:39 20 105160 20800 cap-wifi3 -57 309700000 344100000 6048 6288 00:04:52 00:00:00
27 1788526661 14:57:41 14:57:41 11 177144 59112 cap-wifi3 -57 309700000 344100000 6048 6288 00:04:54 00:00:00
28 1788526663 14:57:43 14:57:43 16 136152 39360 cap-wifi3 -59 309700000 325000000 5600 5920 00:04:56 00:00:00
29 1788526665 14:57:45 14:57:45 16 132416 46304 cap-wifi3 -60 309700000 390000000 5600 6296 00:04:58 00:00:00
30 1788526667 14:57:47 14:57:47 11 462016 41704 cap-wifi3 -60 309700000 390000000 5600 6296 00:05:00 00:00:00
31 1788526669 14:57:49 14:57:49 24 129736 41416 cap-wifi3 -59 309700000 390000000 5600 5920 00:05:02 00:00:00
32 1788526671 14:57:51 14:57:51 7 234376 122480 cap-wifi3 -56 309700000 433300000 6640 7008 00:05:04 00:00:00
33 1788526673 14:57:53 14:57:53 14 101992 21720 cap-wifi3 -56 309700000 433300000 6640 7008 00:05:06 00:00:00
34 1788526675 14:57:55 14:57:55 14 152504 61272 cap-wifi3 -59 309700000 433300000 6160 6512 00:05:08 00:00:00
35 1788526677 14:57:57 14:57:57 22 130520 26552 cap-wifi3 -57 309700000 433300000 6160 6512 00:05:10 00:00:00
36 1788526679 14:57:59 14:57:59 17 155408 24688 cap-wifi3 -57 309700000 433300000 6160 6512 00:05:12 00:00:00
37 1788526681 14:58:01 14:58:01 9 244456 41424 cap-wifi3 -58 309700000 433300000 6160 6512 00:05:14 00:00:00
38 1788526683 14:58:03 14:58:03 10 115640 26032 cap-wifi3 -59 309700000 433300000 5600 5920 00:05:16 00:00:00
39 1788526685 14:58:05 14:58:05 10 154824 24456 cap-wifi3 -59 309700000 433300000 5600 5920 00:05:18 00:00:00
40 1788526687 14:58:07 14:58:08 9 135144 25000 cap-wifi3 -59 309700000 487500000 5600 5920 00:05:20 00:00:00
41 1788526689 14:58:09 14:58:10 20 122800 29936 cap-wifi3 -58 309700000 455800000 5600 5920 00:05:22 00:00:00
42 1788526691 14:58:11 14:58:12 10 152160 65768 cap-wifi3 -58 309700000 455800000 6160 6512 00:05:24 00:00:00
43 1788526692 14:58:12 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-iphone.csv (Takt 2s, Client F2:62:4C:E1:AF:09)

View File

@@ -0,0 +1,42 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788526611,14:56:51,14:56:51,38,120880,24032,cap-wifi6,-85,68800000,17200000,166280,4310536,01:04:25,00:00:00
1788526613,14:56:53,14:56:53,9,151312,62480,cap-wifi6,-85,103200000,17200000,550344,592824,01:04:27,00:00:00
1788526615,14:56:55,14:56:55,10,127416,44832,cap-wifi6,-86,68800000,25800000,413184,340240,01:04:29,00:00:00
1788526617,14:56:57,14:56:57,6,127712,21960,cap-wifi6,-86,68800000,25800000,413184,340240,01:04:31,00:00:00
1788526619,14:56:59,14:56:59,13,157888,29816,cap-wifi6,-85,103200000,34400000,1524128,1126592,01:04:33,00:00:00
1788526621,14:57:01,14:57:01,7,322208,124400,cap-wifi6,-86,68800000,34400000,1886112,547568,01:04:35,00:00:00
1788526623,14:57:03,14:57:03,13,451416,4332552,cap-wifi6,-86,68800000,34400000,1886112,547568,01:04:37,00:00:00
1788526625,14:57:05,14:57:05,10,398720,136640,cap-wifi6,-85,68800000,17200000,1079440,2625392,01:04:39,00:00:00
1788526627,14:57:07,14:57:07,12,947800,446984,cap-wifi6,-86,68800000,17200000,1108088,760040,01:04:42,00:00:00
1788526629,14:57:09,14:57:09,20,7610296,3321592,cap-wifi6,-86,68800000,17200000,1108088,760040,01:04:44,00:00:00
1788526631,14:57:11,14:57:11,8,2720136,2091232,cap-wifi6,-82,68800000,51600000,1684720,1013032,01:04:46,00:00:00
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi6,-87,103200000,25800000,324776,3447064,01:04:48,00:00:00
1788526636,14:57:16,14:57:15,7,108584,42016,cap-wifi6,-87,103200000,25800000,324776,3447064,01:04:50,00:00:00
1788526637,14:57:17,14:57:17,4,1478952,581848,cap-wifi6,-85,103200000,17200000,598680,602896,01:04:52,00:00:00
1788526639,14:57:19,14:57:19,14,229272,54576,cap-wifi6,-84,103200000,34400000,1017664,775360,01:04:54,00:00:00
1788526641,14:57:21,14:57:21,6,100688,29040,cap-wifi6,-84,103200000,34400000,1017664,775360,01:04:56,00:00:00
1788526644,14:57:24,14:57:23,14,472232,195392,cap-wifi6,-86,68800000,17200000,14752,6688,01:04:58,00:00:00
1788526645,14:57:25,14:57:25,19,229864,36304,cap-wifi6,-86,68800000,17200000,1094984,789880,01:05:00,00:00:00
1788526647,14:57:27,14:57:28,9,132384,26968,cap-wifi6,-86,68800000,17200000,1094984,789880,01:05:02,00:00:00
1788526649,14:57:29,14:57:30,18,196672,48240,cap-wifi6,-84,68800000,51600000,912296,563704,01:05:04,00:00:00
1788526652,14:57:32,14:57:32,15,237176,31328,cap-wifi6,-87,68800000,11000000,2448600,1495240,01:05:06,00:00:00
1788526654,14:57:34,14:57:34,9,147328,27456,cap-wifi6,-87,68800000,17200000,1326824,729536,01:05:08,00:00:00
1788526656,14:57:36,14:57:36,11,122784,22816,cap-wifi6,-87,68800000,17200000,1326824,729536,01:05:10,00:00:00
1788526658,14:57:38,14:57:38,9,122248,26192,cap-wifi6,-83,68800000,51600000,1292552,729408,01:05:12,00:00:00
1788526660,14:57:40,14:57:40,14,167632,49032,cap-wifi6,-87,103200000,17200000,2131488,1138888,01:05:14,00:00:00
1788526662,14:57:42,14:57:42,11,89248,17856,cap-wifi6,-87,103200000,17200000,2131488,1138888,01:05:16,00:00:00
1788526664,14:57:44,14:57:44,7,125232,33536,cap-wifi6,-86,103200000,17200000,1495112,774112,01:05:18,00:00:00
1788526666,14:57:46,14:57:46,8,1056872,260048,cap-wifi6,-86,103200000,17200000,773656,584032,01:05:20,00:00:00
1788526668,14:57:48,14:57:48,11,172776,252208,cap-wifi6,-86,103200000,17200000,773656,584032,01:05:22,00:00:00
1788526670,14:57:50,14:57:50,14,116656,22744,cap-wifi6,-87,51600000,17200000,256424,250360,01:05:24,00:00:00
1788526672,14:57:52,14:57:52,8,234376,122480,cap-wifi6,-83,51600000,51600000,771864,575120,01:05:26,00:00:00
1788526674,14:57:54,14:57:54,14,101992,21720,cap-wifi6,-83,51600000,51600000,771864,575120,01:05:28,00:00:00
1788526676,14:57:56,14:57:56,9,152504,61272,cap-wifi6,-84,68800000,17200000,944720,547864,01:05:31,00:00:00
1788526678,14:57:58,14:57:58,15,130520,26552,cap-wifi6,-88,51600000,17200000,1086104,614336,01:05:33,00:00:00
1788526680,14:58:00,14:58:00,16,155408,24688,cap-wifi6,-88,51600000,17200000,1086104,614336,01:05:35,00:00:00
1788526682,14:58:02,14:58:02,10,244456,41424,cap-wifi6,-85,68800000,17200000,1515776,563200,01:05:37,00:00:00
1788526684,14:58:04,14:58:04,8,183848,56872,cap-wifi6,-84,103200000,25800000,888888,696272,01:05:39,00:00:00
1788526686,14:58:06,14:58:06,9,305320,47576,cap-wifi6,-84,103200000,25800000,888888,696272,01:05:41,00:00:00
1788526688,14:58:08,14:58:08,14,331408,59856,cap-wifi6,-84,68800000,34400000,860480,583048,01:05:43,00:00:00
1788526690,14:58:10,14:58:10,17,322448,65576,cap-wifi6,-87,51600000,25800000,1068352,553088,01:05:45,00:00:00
1788526692,14:58:12,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788526611 14:56:51 14:56:51 38 120880 24032 cap-wifi6 -85 68800000 17200000 166280 4310536 01:04:25 00:00:00
3 1788526613 14:56:53 14:56:53 9 151312 62480 cap-wifi6 -85 103200000 17200000 550344 592824 01:04:27 00:00:00
4 1788526615 14:56:55 14:56:55 10 127416 44832 cap-wifi6 -86 68800000 25800000 413184 340240 01:04:29 00:00:00
5 1788526617 14:56:57 14:56:57 6 127712 21960 cap-wifi6 -86 68800000 25800000 413184 340240 01:04:31 00:00:00
6 1788526619 14:56:59 14:56:59 13 157888 29816 cap-wifi6 -85 103200000 34400000 1524128 1126592 01:04:33 00:00:00
7 1788526621 14:57:01 14:57:01 7 322208 124400 cap-wifi6 -86 68800000 34400000 1886112 547568 01:04:35 00:00:00
8 1788526623 14:57:03 14:57:03 13 451416 4332552 cap-wifi6 -86 68800000 34400000 1886112 547568 01:04:37 00:00:00
9 1788526625 14:57:05 14:57:05 10 398720 136640 cap-wifi6 -85 68800000 17200000 1079440 2625392 01:04:39 00:00:00
10 1788526627 14:57:07 14:57:07 12 947800 446984 cap-wifi6 -86 68800000 17200000 1108088 760040 01:04:42 00:00:00
11 1788526629 14:57:09 14:57:09 20 7610296 3321592 cap-wifi6 -86 68800000 17200000 1108088 760040 01:04:44 00:00:00
12 1788526631 14:57:11 14:57:11 8 2720136 2091232 cap-wifi6 -82 68800000 51600000 1684720 1013032 01:04:46 00:00:00
13 1788526633 14:57:13 14:57:13 9 2261568 2680088 cap-wifi6 -87 103200000 25800000 324776 3447064 01:04:48 00:00:00
14 1788526636 14:57:16 14:57:15 7 108584 42016 cap-wifi6 -87 103200000 25800000 324776 3447064 01:04:50 00:00:00
15 1788526637 14:57:17 14:57:17 4 1478952 581848 cap-wifi6 -85 103200000 17200000 598680 602896 01:04:52 00:00:00
16 1788526639 14:57:19 14:57:19 14 229272 54576 cap-wifi6 -84 103200000 34400000 1017664 775360 01:04:54 00:00:00
17 1788526641 14:57:21 14:57:21 6 100688 29040 cap-wifi6 -84 103200000 34400000 1017664 775360 01:04:56 00:00:00
18 1788526644 14:57:24 14:57:23 14 472232 195392 cap-wifi6 -86 68800000 17200000 14752 6688 01:04:58 00:00:00
19 1788526645 14:57:25 14:57:25 19 229864 36304 cap-wifi6 -86 68800000 17200000 1094984 789880 01:05:00 00:00:00
20 1788526647 14:57:27 14:57:28 9 132384 26968 cap-wifi6 -86 68800000 17200000 1094984 789880 01:05:02 00:00:00
21 1788526649 14:57:29 14:57:30 18 196672 48240 cap-wifi6 -84 68800000 51600000 912296 563704 01:05:04 00:00:00
22 1788526652 14:57:32 14:57:32 15 237176 31328 cap-wifi6 -87 68800000 11000000 2448600 1495240 01:05:06 00:00:00
23 1788526654 14:57:34 14:57:34 9 147328 27456 cap-wifi6 -87 68800000 17200000 1326824 729536 01:05:08 00:00:00
24 1788526656 14:57:36 14:57:36 11 122784 22816 cap-wifi6 -87 68800000 17200000 1326824 729536 01:05:10 00:00:00
25 1788526658 14:57:38 14:57:38 9 122248 26192 cap-wifi6 -83 68800000 51600000 1292552 729408 01:05:12 00:00:00
26 1788526660 14:57:40 14:57:40 14 167632 49032 cap-wifi6 -87 103200000 17200000 2131488 1138888 01:05:14 00:00:00
27 1788526662 14:57:42 14:57:42 11 89248 17856 cap-wifi6 -87 103200000 17200000 2131488 1138888 01:05:16 00:00:00
28 1788526664 14:57:44 14:57:44 7 125232 33536 cap-wifi6 -86 103200000 17200000 1495112 774112 01:05:18 00:00:00
29 1788526666 14:57:46 14:57:46 8 1056872 260048 cap-wifi6 -86 103200000 17200000 773656 584032 01:05:20 00:00:00
30 1788526668 14:57:48 14:57:48 11 172776 252208 cap-wifi6 -86 103200000 17200000 773656 584032 01:05:22 00:00:00
31 1788526670 14:57:50 14:57:50 14 116656 22744 cap-wifi6 -87 51600000 17200000 256424 250360 01:05:24 00:00:00
32 1788526672 14:57:52 14:57:52 8 234376 122480 cap-wifi6 -83 51600000 51600000 771864 575120 01:05:26 00:00:00
33 1788526674 14:57:54 14:57:54 14 101992 21720 cap-wifi6 -83 51600000 51600000 771864 575120 01:05:28 00:00:00
34 1788526676 14:57:56 14:57:56 9 152504 61272 cap-wifi6 -84 68800000 17200000 944720 547864 01:05:31 00:00:00
35 1788526678 14:57:58 14:57:58 15 130520 26552 cap-wifi6 -88 51600000 17200000 1086104 614336 01:05:33 00:00:00
36 1788526680 14:58:00 14:58:00 16 155408 24688 cap-wifi6 -88 51600000 17200000 1086104 614336 01:05:35 00:00:00
37 1788526682 14:58:02 14:58:02 10 244456 41424 cap-wifi6 -85 68800000 17200000 1515776 563200 01:05:37 00:00:00
38 1788526684 14:58:04 14:58:04 8 183848 56872 cap-wifi6 -84 103200000 25800000 888888 696272 01:05:39 00:00:00
39 1788526686 14:58:06 14:58:06 9 305320 47576 cap-wifi6 -84 103200000 25800000 888888 696272 01:05:41 00:00:00
40 1788526688 14:58:08 14:58:08 14 331408 59856 cap-wifi6 -84 68800000 34400000 860480 583048 01:05:43 00:00:00
41 1788526690 14:58:10 14:58:10 17 322448 65576 cap-wifi6 -87 51600000 25800000 1068352 553088 01:05:45 00:00:00
42 1788526692 14:58:12 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-macbook.csv (Takt 2s, Client 56:71:6C:22:E6:A9)

View File

@@ -0,0 +1,42 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788526611,14:56:51,14:56:51,38,120880,24032,cap-wifi5,-51,137600000,229400000,0,0,01:04:22,00:00:09
1788526613,14:56:53,14:56:53,9,151312,62480,cap-wifi5,-51,137600000,258100000,1680,1776,01:04:24,00:00:00
1788526615,14:56:55,14:56:55,10,127416,44832,cap-wifi5,-53,137600000,229400000,2800,2960,01:04:26,00:00:00
1788526617,14:56:57,14:56:57,6,127712,21960,cap-wifi5,-53,137600000,229400000,2800,2960,01:04:28,00:00:00
1788526619,14:56:59,14:56:59,13,157888,29816,cap-wifi5,-50,137600000,229400000,2800,2960,01:04:30,00:00:00
1788526621,14:57:01,14:57:01,7,322208,124400,cap-wifi5,-51,137600000,229400000,3248,3328,01:04:32,00:00:00
1788526623,14:57:03,14:57:03,13,451416,4332552,cap-wifi5,-51,137600000,229400000,3248,3328,01:04:34,00:00:00
1788526625,14:57:05,14:57:05,10,398720,136640,cap-wifi5,-51,137600000,229400000,2800,2960,01:04:36,00:00:00
1788526627,14:57:07,14:57:07,12,947800,446984,cap-wifi5,-51,137600000,229400000,2800,2960,01:04:38,00:00:00
1788526629,14:57:09,14:57:09,20,7610296,3321592,cap-wifi5,-51,137600000,229400000,2800,2960,01:04:40,00:00:00
1788526631,14:57:11,14:57:11,8,2720136,2091232,cap-wifi5,-52,137600000,229400000,3360,3552,01:04:42,00:00:00
1788526633,14:57:13,14:57:13,9,2261568,2680088,cap-wifi5,-52,137600000,229400000,3360,3552,01:04:44,00:00:00
1788526636,14:57:16,14:57:15,7,108584,42016,cap-wifi5,-52,137600000,229400000,3360,3552,01:04:46,00:00:00
1788526637,14:57:17,14:57:17,4,1478952,581848,cap-wifi5,-53,137600000,258100000,2800,2960,01:04:48,00:00:00
1788526639,14:57:19,14:57:19,14,229272,54576,cap-wifi5,-53,137600000,229400000,4184,4968,01:04:50,00:00:00
1788526641,14:57:21,14:57:21,6,100688,29040,cap-wifi5,-53,137600000,229400000,4184,4968,01:04:52,00:00:00
1788526644,14:57:24,14:57:23,14,472232,195392,cap-wifi5,-61,137600000,229400000,2800,2960,01:04:54,00:00:00
1788526645,14:57:25,14:57:25,19,229864,36304,cap-wifi5,-59,172100000,229400000,2800,2960,01:04:56,00:00:00
1788526647,14:57:27,14:57:28,9,132384,26968,cap-wifi5,-59,172100000,229400000,2800,2960,01:04:58,00:00:00
1788526649,14:57:29,14:57:30,18,196672,48240,cap-wifi5,-60,172100000,229400000,2800,2368,01:05:00,00:00:00
1788526652,14:57:32,14:57:32,15,237176,31328,cap-wifi5,-60,172100000,229400000,3360,3552,01:05:02,00:00:00
1788526654,14:57:34,14:57:34,9,147328,27456,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:04,00:00:00
1788526656,14:57:36,14:57:36,11,122784,22816,cap-wifi5,-60,172100000,229400000,2800,2960,01:05:07,00:00:00
1788526658,14:57:38,14:57:38,9,122248,26192,cap-wifi5,-59,129000000,258100000,3856,2960,01:05:09,00:00:00
1788526660,14:57:40,14:57:40,14,167632,49032,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:11,00:00:00
1788526662,14:57:42,14:57:42,11,89248,17856,cap-wifi5,-58,114700000,229400000,7888,15664,01:05:13,00:00:00
1788526664,14:57:44,14:57:44,7,125232,33536,cap-wifi5,-57,114700000,206500000,3360,2960,01:05:15,00:00:00
1788526666,14:57:46,14:57:46,8,1056872,260048,cap-wifi5,-57,114700000,206500000,2800,2960,01:05:17,00:00:00
1788526668,14:57:48,14:57:48,11,172776,252208,cap-wifi5,-57,114700000,206500000,2800,2960,01:05:19,00:00:00
1788526670,14:57:50,14:57:50,14,116656,22744,cap-wifi5,-57,154900000,172100000,3360,3552,01:05:21,00:00:00
1788526672,14:57:52,14:57:52,8,234376,122480,cap-wifi5,-58,154900000,206500000,2800,2960,01:05:23,00:00:00
1788526674,14:57:54,14:57:54,14,101992,21720,cap-wifi5,-58,154900000,206500000,2800,2960,01:05:25,00:00:00
1788526676,14:57:56,14:57:56,9,152504,61272,cap-wifi5,-58,154900000,229400000,2800,2960,01:05:27,00:00:00
1788526678,14:57:58,14:57:58,15,130520,26552,cap-wifi5,-58,103200000,229400000,2800,2960,01:05:29,00:00:00
1788526680,14:58:00,14:58:00,16,155408,24688,cap-wifi5,-58,103200000,229400000,2800,2960,01:05:31,00:00:00
1788526682,14:58:02,14:58:02,10,244456,41424,cap-wifi5,-58,103200000,206500000,3248,3328,01:05:33,00:00:00
1788526684,14:58:04,14:58:04,8,183848,56872,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:35,00:00:00
1788526686,14:58:06,14:58:06,9,305320,47576,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:37,00:00:00
1788526688,14:58:08,14:58:08,14,331408,59856,cap-wifi5,-59,103200000,229400000,2800,2960,01:05:39,00:00:00
1788526690,14:58:10,14:58:10,17,322448,65576,cap-wifi5,-58,103200000,206500000,2800,2960,01:05:41,00:00:00
1788526692,14:58:12,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788526611 14:56:51 14:56:51 38 120880 24032 cap-wifi5 -51 137600000 229400000 0 0 01:04:22 00:00:09
3 1788526613 14:56:53 14:56:53 9 151312 62480 cap-wifi5 -51 137600000 258100000 1680 1776 01:04:24 00:00:00
4 1788526615 14:56:55 14:56:55 10 127416 44832 cap-wifi5 -53 137600000 229400000 2800 2960 01:04:26 00:00:00
5 1788526617 14:56:57 14:56:57 6 127712 21960 cap-wifi5 -53 137600000 229400000 2800 2960 01:04:28 00:00:00
6 1788526619 14:56:59 14:56:59 13 157888 29816 cap-wifi5 -50 137600000 229400000 2800 2960 01:04:30 00:00:00
7 1788526621 14:57:01 14:57:01 7 322208 124400 cap-wifi5 -51 137600000 229400000 3248 3328 01:04:32 00:00:00
8 1788526623 14:57:03 14:57:03 13 451416 4332552 cap-wifi5 -51 137600000 229400000 3248 3328 01:04:34 00:00:00
9 1788526625 14:57:05 14:57:05 10 398720 136640 cap-wifi5 -51 137600000 229400000 2800 2960 01:04:36 00:00:00
10 1788526627 14:57:07 14:57:07 12 947800 446984 cap-wifi5 -51 137600000 229400000 2800 2960 01:04:38 00:00:00
11 1788526629 14:57:09 14:57:09 20 7610296 3321592 cap-wifi5 -51 137600000 229400000 2800 2960 01:04:40 00:00:00
12 1788526631 14:57:11 14:57:11 8 2720136 2091232 cap-wifi5 -52 137600000 229400000 3360 3552 01:04:42 00:00:00
13 1788526633 14:57:13 14:57:13 9 2261568 2680088 cap-wifi5 -52 137600000 229400000 3360 3552 01:04:44 00:00:00
14 1788526636 14:57:16 14:57:15 7 108584 42016 cap-wifi5 -52 137600000 229400000 3360 3552 01:04:46 00:00:00
15 1788526637 14:57:17 14:57:17 4 1478952 581848 cap-wifi5 -53 137600000 258100000 2800 2960 01:04:48 00:00:00
16 1788526639 14:57:19 14:57:19 14 229272 54576 cap-wifi5 -53 137600000 229400000 4184 4968 01:04:50 00:00:00
17 1788526641 14:57:21 14:57:21 6 100688 29040 cap-wifi5 -53 137600000 229400000 4184 4968 01:04:52 00:00:00
18 1788526644 14:57:24 14:57:23 14 472232 195392 cap-wifi5 -61 137600000 229400000 2800 2960 01:04:54 00:00:00
19 1788526645 14:57:25 14:57:25 19 229864 36304 cap-wifi5 -59 172100000 229400000 2800 2960 01:04:56 00:00:00
20 1788526647 14:57:27 14:57:28 9 132384 26968 cap-wifi5 -59 172100000 229400000 2800 2960 01:04:58 00:00:00
21 1788526649 14:57:29 14:57:30 18 196672 48240 cap-wifi5 -60 172100000 229400000 2800 2368 01:05:00 00:00:00
22 1788526652 14:57:32 14:57:32 15 237176 31328 cap-wifi5 -60 172100000 229400000 3360 3552 01:05:02 00:00:00
23 1788526654 14:57:34 14:57:34 9 147328 27456 cap-wifi5 -60 172100000 229400000 2800 2960 01:05:04 00:00:00
24 1788526656 14:57:36 14:57:36 11 122784 22816 cap-wifi5 -60 172100000 229400000 2800 2960 01:05:07 00:00:00
25 1788526658 14:57:38 14:57:38 9 122248 26192 cap-wifi5 -59 129000000 258100000 3856 2960 01:05:09 00:00:00
26 1788526660 14:57:40 14:57:40 14 167632 49032 cap-wifi5 -58 114700000 229400000 7888 15664 01:05:11 00:00:00
27 1788526662 14:57:42 14:57:42 11 89248 17856 cap-wifi5 -58 114700000 229400000 7888 15664 01:05:13 00:00:00
28 1788526664 14:57:44 14:57:44 7 125232 33536 cap-wifi5 -57 114700000 206500000 3360 2960 01:05:15 00:00:00
29 1788526666 14:57:46 14:57:46 8 1056872 260048 cap-wifi5 -57 114700000 206500000 2800 2960 01:05:17 00:00:00
30 1788526668 14:57:48 14:57:48 11 172776 252208 cap-wifi5 -57 114700000 206500000 2800 2960 01:05:19 00:00:00
31 1788526670 14:57:50 14:57:50 14 116656 22744 cap-wifi5 -57 154900000 172100000 3360 3552 01:05:21 00:00:00
32 1788526672 14:57:52 14:57:52 8 234376 122480 cap-wifi5 -58 154900000 206500000 2800 2960 01:05:23 00:00:00
33 1788526674 14:57:54 14:57:54 14 101992 21720 cap-wifi5 -58 154900000 206500000 2800 2960 01:05:25 00:00:00
34 1788526676 14:57:56 14:57:56 9 152504 61272 cap-wifi5 -58 154900000 229400000 2800 2960 01:05:27 00:00:00
35 1788526678 14:57:58 14:57:58 15 130520 26552 cap-wifi5 -58 103200000 229400000 2800 2960 01:05:29 00:00:00
36 1788526680 14:58:00 14:58:00 16 155408 24688 cap-wifi5 -58 103200000 229400000 2800 2960 01:05:31 00:00:00
37 1788526682 14:58:02 14:58:02 10 244456 41424 cap-wifi5 -58 103200000 206500000 3248 3328 01:05:33 00:00:00
38 1788526684 14:58:04 14:58:04 8 183848 56872 cap-wifi5 -58 103200000 206500000 2800 2960 01:05:35 00:00:00
39 1788526686 14:58:06 14:58:06 9 305320 47576 cap-wifi5 -58 103200000 206500000 2800 2960 01:05:37 00:00:00
40 1788526688 14:58:08 14:58:08 14 331408 59856 cap-wifi5 -59 103200000 229400000 2800 2960 01:05:39 00:00:00
41 1788526690 14:58:10 14:58:10 17 322448 65576 cap-wifi5 -58 103200000 206500000 2800 2960 01:05:41 00:00:00
42 1788526692 14:58:12 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-s22.csv (Takt 2s, Client 2A:0D:B0:5D:AD:A7)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
iphone|10.40.10.196|F2:62:4C:E1:AF:09
s22|10.40.10.179|2A:0D:B0:5D:AD:A7
ipad|10.40.10.180|CA:B8:D4:3F:8A:81
macbook|10.40.10.82|56:71:6C:22:E6:A9

View File

@@ -0,0 +1,6 @@
ts_epoch,ts_local,marker
1788527256,15:07:36,PINM=off
1788527283,15:08:03,PINM=off
1788527311,15:08:31,PINM=off
1788527320,15:08:40,PINM=off
1788527414,15:10:14,STOP
1 ts_epoch ts_local marker
2 1788527256 15:07:36 PINM=off
3 1788527283 15:08:03 PINM=off
4 1788527311 15:08:31 PINM=off
5 1788527320 15:08:40 PINM=off
6 1788527414 15:10:14 STOP

View File

@@ -0,0 +1 @@
{"mode": "langzeit", "phase": "GEHWEG", "title": "Roaming-Messung l\u00e4uft", "instruction": "Aufzeichnung gestoppt.", "step": 0, "steps": 0, "ends": 0}

View File

@@ -0,0 +1,131 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788527155,15:05:55,15:05:55,26,110192,66624,cap-wifi3,-58,6000000,216700000,0,0,00:07:03,00:00:00
1788527157,15:05:57,15:05:57,10,248200,181784,cap-wifi3,-58,6000000,216700000,0,0,00:07:05,00:00:00
1788527159,15:05:59,15:05:59,27,895392,176224,cap-wifi3,-54,309700000,455800000,100936,106200,00:07:07,00:00:00
1788527161,15:06:01,15:06:01,5,271768,3546664,cap-wifi3,-55,309700000,309700000,4800,18208,00:07:09,00:00:00
1788527163,15:06:03,15:06:03,7,212384,57592,cap-wifi3,-55,309700000,309700000,4800,18208,00:07:11,00:00:00
1788527165,15:06:05,15:06:05,6,119880,34152,cap-wifi3,-52,309700000,455800000,62952,10824,00:07:13,00:00:00
1788527167,15:06:07,15:06:07,6,285512,62760,cap-wifi3,-48,309700000,412900000,2800,2960,00:07:15,00:00:00
1788527169,15:06:09,15:06:09,18,135200,33432,cap-wifi3,-48,309700000,412900000,2800,2960,00:07:17,00:00:00
1788527171,15:06:11,15:06:11,2,80168,35552,cap-wifi3,-50,309700000,433300000,2800,3360,00:07:19,00:00:00
1788527173,15:06:13,15:06:13,6,263824,45616,cap-wifi3,-49,309700000,455800000,2800,2960,00:07:21,00:00:00
1788527175,15:06:15,15:06:15,4,139448,79056,cap-wifi3,-49,309700000,455800000,2800,2960,00:07:23,00:00:00
1788527177,15:06:17,15:06:17,7,125944,34792,cap-wifi3,-51,309700000,487500000,2800,2960,00:07:25,00:00:00
1788527179,15:06:19,15:06:19,21,228896,34848,cap-wifi3,-51,309700000,516200000,3360,3552,00:07:27,00:00:00
1788527181,15:06:21,15:06:21,6,91344,100616,cap-wifi3,-51,309700000,516200000,3360,3552,00:07:29,00:00:00
1788527183,15:06:23,15:06:23,8,1161368,460544,cap-wifi3,-52,309700000,541700000,2800,3520,00:07:31,00:00:00
1788527185,15:06:25,15:06:25,9,669424,189984,cap-wifi3,-51,309700000,433300000,2800,2960,00:07:33,00:00:00
1788527187,15:06:27,15:06:27,8,220472,72928,cap-wifi3,-51,309700000,433300000,2800,2960,00:07:35,00:00:00
1788527189,15:06:29,15:06:29,19,85696,19672,cap-wifi3,-50,309700000,455800000,11872,3328,00:07:37,00:00:00
1788527191,15:06:31,15:06:31,7,88056,17368,cap-wifi3,-52,309700000,516200000,3360,3552,00:07:39,00:00:00
1788527193,15:06:33,15:06:33,7,78232,15688,cap-wifi3,-52,309700000,516200000,3360,3552,00:07:41,00:00:00
1788527195,15:06:35,15:06:35,7,77824,19488,cap-wifi3,-50,309700000,433300000,2800,2960,00:07:43,00:00:00
1788527197,15:06:37,15:06:37,11,91648,29960,cap-wifi3,-56,309700000,455800000,2800,2960,00:07:45,00:00:00
1788527199,15:06:39,15:06:39,19,479584,403096,cap-wifi3,-54,309700000,325000000,2800,2960,00:07:47,00:00:00
1788527201,15:06:41,15:06:41,6,83504,18032,cap-wifi3,-54,309700000,325000000,2800,2960,00:07:49,00:00:00
1788527203,15:06:43,15:06:43,8,94312,27480,cap-wifi3,-53,309700000,344100000,3248,2960,00:07:51,00:00:00
1788527205,15:06:45,15:06:45,7,139816,113728,cap-wifi3,-52,309700000,390000000,2800,2960,00:07:53,00:00:00
1788527207,15:06:47,15:06:47,8,77512,23304,cap-wifi3,-52,309700000,390000000,2800,2960,00:07:55,00:00:00
1788527209,15:06:49,15:06:49,22,135424,86176,cap-wifi3,-53,309700000,412900000,2800,3360,00:07:57,00:00:00
1788527211,15:06:51,15:06:52,6,80072,20128,cap-wifi3,-52,309700000,433300000,2800,2960,00:07:59,00:00:00
1788527213,15:06:53,15:06:54,7,81544,23592,cap-wifi3,-52,309700000,433300000,2800,2960,00:08:01,00:00:00
1788527216,15:06:56,15:06:56,8,118248,77704,cap-wifi3,-52,309700000,455800000,3808,3552,00:08:03,00:00:00
1788527218,15:06:58,15:06:58,6,115296,40584,cap-wifi3,-54,309700000,487500000,2800,2960,00:08:05,00:00:00
1788527220,15:07:00,15:07:00,36,72144,17920,cap-wifi3,-54,309700000,487500000,2800,2960,00:08:07,00:00:00
1788527222,15:07:02,15:07:02,6,87272,19464,cap-wifi3,-53,309700000,516200000,3808,3920,00:08:09,00:00:00
1788527224,15:07:04,15:07:04,7,341584,177744,cap-wifi3,-54,309700000,487500000,3488,2960,00:08:11,00:00:00
1788527226,15:07:06,15:07:06,5,96008,29072,cap-wifi3,-54,309700000,487500000,3488,2960,00:08:14,00:00:00
1788527228,15:07:08,15:07:08,9,88184,20760,cap-wifi3,-54,309700000,516200000,2800,2960,00:08:16,00:00:00
1788527230,15:07:10,15:07:10,19,245616,37632,cap-wifi3,-54,309700000,541700000,3424,2960,00:08:18,00:00:00
1788527232,15:07:12,15:07:12,7,136904,41680,cap-wifi3,-54,309700000,541700000,3424,2960,00:08:20,00:00:00
1788527234,15:07:14,15:07:14,5,176432,193240,cap-wifi3,-54,309700000,573500000,3360,2960,00:08:22,00:00:00
1788527236,15:07:16,15:07:16,5,668616,412672,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:24,00:00:00
1788527238,15:07:18,15:07:18,12,10040200,401976,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:26,00:00:00
1788527240,15:07:20,15:07:20,21,6694840,181608,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:28,00:00:00
1788527242,15:07:22,15:07:22,8,269904,95904,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:30,00:00:00
1788527244,15:07:24,15:07:24,10,97040,38768,cap-wifi3,-52,309700000,573500000,2800,2960,00:08:32,00:00:00
1788527246,15:07:26,15:07:26,8,265536,57040,cap-wifi3,-51,309700000,573500000,2800,2960,00:08:34,00:00:00
1788527248,15:07:28,15:07:28,8,79496,17712,cap-wifi3,-52,309700000,573500000,3360,8208,00:08:36,00:00:00
1788527250,15:07:30,15:07:30,5,82824,26656,cap-wifi3,-52,309700000,573500000,3360,8208,00:08:38,00:00:00
1788527252,15:07:32,15:07:32,8,79440,24984,cap-wifi3,-52,309700000,573500000,3360,7808,00:08:40,00:00:00
1788527254,15:07:34,15:07:34,7,84240,17432,cap-wifi3,-52,309700000,573500000,5248,2960,00:08:42,00:00:00
1788527256,15:07:36,15:07:36,15,74928,18888,cap-wifi3,-52,309700000,573500000,5248,2960,00:08:44,00:00:00
1788527258,15:07:38,15:07:38,6,79856,17376,cap-wifi3,-51,309700000,573500000,3328,3520,00:08:46,00:00:00
1788527260,15:07:40,15:07:40,5,91680,31720,cap-wifi3,-52,275300000,573500000,2800,2960,00:08:48,00:00:00
1788527262,15:07:42,15:07:42,6,82760,21192,cap-wifi3,-52,275300000,573500000,2800,2960,00:08:50,00:00:00
1788527264,15:07:44,15:07:44,7,91960,31680,cap-wifi3,-51,275300000,573500000,2800,2960,00:08:52,00:00:00
1788527266,15:07:46,15:07:46,6,986832,256184,cap-wifi3,-51,275300000,573500000,3920,4144,00:08:54,00:00:00
1788527268,15:07:48,15:07:48,7,204344,305984,cap-wifi3,-51,275300000,573500000,3920,4144,00:08:56,00:00:00
1788527270,15:07:50,15:07:50,9,90376,25984,cap-wifi3,-52,258100000,573500000,2240,2368,00:08:58,00:00:00
1788527272,15:07:52,15:07:52,5,106024,28632,cap-wifi3,-52,258100000,286800000,2800,2960,00:09:00,00:00:00
1788527274,15:07:54,15:07:54,8,90816,27368,cap-wifi3,-52,258100000,286800000,2800,2960,00:09:02,00:00:00
1788527276,15:07:56,15:07:56,9,80656,22520,cap-wifi3,-52,258100000,573500000,2800,2960,00:09:04,00:00:00
1788527278,15:07:58,15:07:58,8,74792,15952,cap-wifi3,-54,258100000,412900000,2800,2960,00:09:06,00:00:00
1788527280,15:08:00,15:08:00,9,97280,32008,cap-wifi3,-54,258100000,412900000,2800,2960,00:09:08,00:00:00
1788527282,15:08:02,15:08:02,22,405584,131400,cap-wifi3,-55,258100000,412900000,2800,2960,00:09:10,00:00:00
1788527284,15:08:04,15:08:04,15,99616,29344,cap-wifi3,-53,258100000,433300000,2800,2960,00:09:12,00:00:00
1788527286,15:08:06,15:08:06,3,116040,34784,cap-wifi3,-53,258100000,433300000,2800,2960,00:09:14,00:00:00
1788527288,15:08:08,15:08:08,6,263752,46256,cap-wifi3,-54,258100000,455800000,2800,3360,00:09:16,00:00:00
1788527290,15:08:10,15:08:10,5,154688,74104,cap-wifi3,-54,258100000,487500000,2800,2960,00:09:18,00:00:00
1788527292,15:08:12,15:08:13,4,437800,144600,cap-wifi3,-54,258100000,487500000,2800,2960,00:09:20,00:00:00
1788527294,15:08:14,15:08:15,5,273784,69248,cap-wifi3,-56,258100000,390000000,3808,3552,00:09:22,00:00:00
1788527297,15:08:17,15:08:17,4,110840,33232,cap-wifi3,-56,258100000,433300000,2800,2960,00:09:24,00:00:00
1788527299,15:08:19,15:08:19,5,80584,34112,cap-wifi3,-55,258100000,455800000,3360,3552,00:09:26,00:00:00
1788527301,15:08:21,15:08:21,5,89992,25208,cap-wifi3,-55,258100000,455800000,3360,3552,00:09:28,00:00:00
1788527303,15:08:23,15:08:23,5,258520,122376,cap-wifi3,-56,258100000,433300000,2800,2960,00:09:30,00:00:00
1788527305,15:08:25,15:08:25,8,484544,159104,cap-wifi3,-55,258100000,455800000,2800,2960,00:09:33,00:00:00
1788527307,15:08:27,15:08:27,5,85832,21400,cap-wifi3,-55,258100000,455800000,2800,2960,00:09:35,00:00:00
1788527309,15:08:29,15:08:29,7,86968,23984,cap-wifi3,-56,258100000,433300000,2800,2960,00:09:37,00:00:00
1788527311,15:08:31,15:08:31,4,92848,27216,cap-wifi3,-57,258100000,455800000,2800,2960,00:09:39,00:00:00
1788527313,15:08:33,15:08:33,13,88112,30272,cap-wifi3,-57,258100000,455800000,2800,2960,00:09:41,00:00:00
1788527315,15:08:35,15:08:35,6,97568,38688,cap-wifi3,-57,258100000,433300000,2800,2960,00:09:43,00:00:00
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-58,258100000,455800000,3360,3552,00:09:45,00:00:00
1788527319,15:08:39,15:08:39,22,95672,27872,cap-wifi3,-58,258100000,455800000,3360,3552,00:09:47,00:00:00
1788527321,15:08:41,15:08:41,20,81008,14064,cap-wifi3,-58,258100000,433300000,2800,2960,00:09:49,00:00:00
1788527323,15:08:43,15:08:43,9,79480,19824,cap-wifi3,-59,258100000,325000000,3328,2960,00:09:51,00:00:00
1788527325,15:08:45,15:08:45,11,83080,28888,cap-wifi3,-59,258100000,325000000,3328,2960,00:09:53,00:00:00
1788527327,15:08:47,15:08:47,7,77224,19568,cap-wifi3,-59,258100000,390000000,3360,3952,00:09:55,00:00:00
1788527329,15:08:49,15:08:49,20,87976,23544,cap-wifi3,-58,258100000,412900000,2800,2960,00:09:57,00:00:00
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-58,258100000,412900000,2800,2960,00:09:59,00:00:00
1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-58,258100000,390000000,3808,3552,00:10:01,00:00:00
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-52,6000000,412900000,3360,3552,00:10:03,00:00:00
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-52,6000000,412900000,3360,3552,00:10:05,00:00:00
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-52,258100000,433300000,2800,3360,00:10:07,00:00:00
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-53,258100000,455800000,2800,2960,00:10:09,00:00:00
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-53,258100000,455800000,2800,2960,00:10:11,00:00:00
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-56,258100000,433300000,2800,2960,00:10:13,00:00:00
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-55,258100000,390000000,2800,2960,00:10:15,00:00:00
1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-55,258100000,390000000,2800,2960,00:10:17,00:00:00
1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-52,6000000,309700000,2800,2960,00:10:19,00:00:00
1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-54,258100000,344100000,3360,3552,00:10:21,00:00:00
1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-54,258100000,344100000,3360,3552,00:10:23,00:00:00
1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-55,258100000,390000000,4080,6912,00:10:25,00:00:00
1788527359,15:09:19,15:09:20,19,108000,26560,cap-wifi3,-56,258100000,412900000,3360,3552,00:10:27,00:00:00
1788527361,15:09:21,15:09:22,10,2754208,213840,cap-wifi3,-56,258100000,412900000,3360,3552,00:10:29,00:00:00
1788527364,15:09:24,15:09:24,7,314040,73608,cap-wifi3,-55,258100000,216700000,15040,7600,00:10:31,00:00:00
1788527366,15:09:26,15:09:26,5,485488,100744,cap-wifi3,-54,258100000,229400000,3304,6992,00:10:33,00:00:00
1788527368,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-54,258100000,229400000,3304,6992,00:10:35,00:00:00
1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-56,258100000,433300000,2800,2960,00:10:37,00:00:00
1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-54,258100000,433300000,4928,0,00:10:39,00:00:00
1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-54,6000000,433300000,2800,0,00:10:42,00:00:00
1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-54,6000000,433300000,2800,0,00:10:44,00:00:00
1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-55,258100000,433300000,2800,6496,00:10:46,00:00:00
1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-54,258100000,433300000,2240,0,00:10:48,00:00:00
1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-54,258100000,433300000,2240,0,00:10:50,00:00:00
1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-54,6000000,433300000,13464,368,00:10:52,00:00:00
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-54,258100000,455800000,2800,2960,00:10:54,00:00:00
1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-54,258100000,455800000,2800,2960,00:10:56,00:00:00
1788527390,15:09:50,15:09:50,9,74488,14496,cap-wifi3,-54,258100000,390000000,2928,0,00:10:58,00:00:00
1788527392,15:09:52,15:09:52,9,81688,114120,cap-wifi3,-54,258100000,390000000,2240,0,00:11:00,00:00:00
1788527394,15:09:54,15:09:54,11,139472,94312,cap-wifi3,-54,258100000,390000000,2240,0,00:11:02,00:00:00
1788527396,15:09:56,15:09:56,8,99376,34800,cap-wifi3,-54,258100000,390000000,2240,0,00:11:04,00:00:00
1788527398,15:09:58,15:09:58,7,95624,20936,cap-wifi3,-54,258100000,390000000,2800,0,00:11:06,00:00:00
1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-54,258100000,390000000,2800,0,00:11:08,00:00:00
1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-54,258100000,390000000,2240,0,00:11:10,00:00:00
1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-54,258100000,390000000,5040,0,00:11:12,00:00:00
1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-54,258100000,390000000,5040,0,00:11:14,00:00:00
1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-54,258100000,390000000,2800,0,00:11:16,00:00:00
1788527410,15:10:10,15:10:10,20,81216,18128,cap-wifi3,-53,258100000,390000000,2688,0,00:11:18,00:00:00
1788527412,15:10:12,15:10:12,8,223088,23248,cap-wifi3,-53,258100000,390000000,2688,0,00:11:20,00:00:00
1788527414,15:10:14,15:10:14,7,139784,51840,cap-wifi3,-54,258100000,390000000,2240,0,00:11:22,00:00:00
1788527415,15:10:15,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788527155 15:05:55 15:05:55 26 110192 66624 cap-wifi3 -58 6000000 216700000 0 0 00:07:03 00:00:00
3 1788527157 15:05:57 15:05:57 10 248200 181784 cap-wifi3 -58 6000000 216700000 0 0 00:07:05 00:00:00
4 1788527159 15:05:59 15:05:59 27 895392 176224 cap-wifi3 -54 309700000 455800000 100936 106200 00:07:07 00:00:00
5 1788527161 15:06:01 15:06:01 5 271768 3546664 cap-wifi3 -55 309700000 309700000 4800 18208 00:07:09 00:00:00
6 1788527163 15:06:03 15:06:03 7 212384 57592 cap-wifi3 -55 309700000 309700000 4800 18208 00:07:11 00:00:00
7 1788527165 15:06:05 15:06:05 6 119880 34152 cap-wifi3 -52 309700000 455800000 62952 10824 00:07:13 00:00:00
8 1788527167 15:06:07 15:06:07 6 285512 62760 cap-wifi3 -48 309700000 412900000 2800 2960 00:07:15 00:00:00
9 1788527169 15:06:09 15:06:09 18 135200 33432 cap-wifi3 -48 309700000 412900000 2800 2960 00:07:17 00:00:00
10 1788527171 15:06:11 15:06:11 2 80168 35552 cap-wifi3 -50 309700000 433300000 2800 3360 00:07:19 00:00:00
11 1788527173 15:06:13 15:06:13 6 263824 45616 cap-wifi3 -49 309700000 455800000 2800 2960 00:07:21 00:00:00
12 1788527175 15:06:15 15:06:15 4 139448 79056 cap-wifi3 -49 309700000 455800000 2800 2960 00:07:23 00:00:00
13 1788527177 15:06:17 15:06:17 7 125944 34792 cap-wifi3 -51 309700000 487500000 2800 2960 00:07:25 00:00:00
14 1788527179 15:06:19 15:06:19 21 228896 34848 cap-wifi3 -51 309700000 516200000 3360 3552 00:07:27 00:00:00
15 1788527181 15:06:21 15:06:21 6 91344 100616 cap-wifi3 -51 309700000 516200000 3360 3552 00:07:29 00:00:00
16 1788527183 15:06:23 15:06:23 8 1161368 460544 cap-wifi3 -52 309700000 541700000 2800 3520 00:07:31 00:00:00
17 1788527185 15:06:25 15:06:25 9 669424 189984 cap-wifi3 -51 309700000 433300000 2800 2960 00:07:33 00:00:00
18 1788527187 15:06:27 15:06:27 8 220472 72928 cap-wifi3 -51 309700000 433300000 2800 2960 00:07:35 00:00:00
19 1788527189 15:06:29 15:06:29 19 85696 19672 cap-wifi3 -50 309700000 455800000 11872 3328 00:07:37 00:00:00
20 1788527191 15:06:31 15:06:31 7 88056 17368 cap-wifi3 -52 309700000 516200000 3360 3552 00:07:39 00:00:00
21 1788527193 15:06:33 15:06:33 7 78232 15688 cap-wifi3 -52 309700000 516200000 3360 3552 00:07:41 00:00:00
22 1788527195 15:06:35 15:06:35 7 77824 19488 cap-wifi3 -50 309700000 433300000 2800 2960 00:07:43 00:00:00
23 1788527197 15:06:37 15:06:37 11 91648 29960 cap-wifi3 -56 309700000 455800000 2800 2960 00:07:45 00:00:00
24 1788527199 15:06:39 15:06:39 19 479584 403096 cap-wifi3 -54 309700000 325000000 2800 2960 00:07:47 00:00:00
25 1788527201 15:06:41 15:06:41 6 83504 18032 cap-wifi3 -54 309700000 325000000 2800 2960 00:07:49 00:00:00
26 1788527203 15:06:43 15:06:43 8 94312 27480 cap-wifi3 -53 309700000 344100000 3248 2960 00:07:51 00:00:00
27 1788527205 15:06:45 15:06:45 7 139816 113728 cap-wifi3 -52 309700000 390000000 2800 2960 00:07:53 00:00:00
28 1788527207 15:06:47 15:06:47 8 77512 23304 cap-wifi3 -52 309700000 390000000 2800 2960 00:07:55 00:00:00
29 1788527209 15:06:49 15:06:49 22 135424 86176 cap-wifi3 -53 309700000 412900000 2800 3360 00:07:57 00:00:00
30 1788527211 15:06:51 15:06:52 6 80072 20128 cap-wifi3 -52 309700000 433300000 2800 2960 00:07:59 00:00:00
31 1788527213 15:06:53 15:06:54 7 81544 23592 cap-wifi3 -52 309700000 433300000 2800 2960 00:08:01 00:00:00
32 1788527216 15:06:56 15:06:56 8 118248 77704 cap-wifi3 -52 309700000 455800000 3808 3552 00:08:03 00:00:00
33 1788527218 15:06:58 15:06:58 6 115296 40584 cap-wifi3 -54 309700000 487500000 2800 2960 00:08:05 00:00:00
34 1788527220 15:07:00 15:07:00 36 72144 17920 cap-wifi3 -54 309700000 487500000 2800 2960 00:08:07 00:00:00
35 1788527222 15:07:02 15:07:02 6 87272 19464 cap-wifi3 -53 309700000 516200000 3808 3920 00:08:09 00:00:00
36 1788527224 15:07:04 15:07:04 7 341584 177744 cap-wifi3 -54 309700000 487500000 3488 2960 00:08:11 00:00:00
37 1788527226 15:07:06 15:07:06 5 96008 29072 cap-wifi3 -54 309700000 487500000 3488 2960 00:08:14 00:00:00
38 1788527228 15:07:08 15:07:08 9 88184 20760 cap-wifi3 -54 309700000 516200000 2800 2960 00:08:16 00:00:00
39 1788527230 15:07:10 15:07:10 19 245616 37632 cap-wifi3 -54 309700000 541700000 3424 2960 00:08:18 00:00:00
40 1788527232 15:07:12 15:07:12 7 136904 41680 cap-wifi3 -54 309700000 541700000 3424 2960 00:08:20 00:00:00
41 1788527234 15:07:14 15:07:14 5 176432 193240 cap-wifi3 -54 309700000 573500000 3360 2960 00:08:22 00:00:00
42 1788527236 15:07:16 15:07:16 5 668616 412672 cap-wifi3 -52 309700000 573500000 2800 2960 00:08:24 00:00:00
43 1788527238 15:07:18 15:07:18 12 10040200 401976 cap-wifi3 -52 309700000 573500000 2800 2960 00:08:26 00:00:00
44 1788527240 15:07:20 15:07:20 21 6694840 181608 cap-wifi3 -52 309700000 573500000 2800 2960 00:08:28 00:00:00
45 1788527242 15:07:22 15:07:22 8 269904 95904 cap-wifi3 -52 309700000 573500000 2800 2960 00:08:30 00:00:00
46 1788527244 15:07:24 15:07:24 10 97040 38768 cap-wifi3 -52 309700000 573500000 2800 2960 00:08:32 00:00:00
47 1788527246 15:07:26 15:07:26 8 265536 57040 cap-wifi3 -51 309700000 573500000 2800 2960 00:08:34 00:00:00
48 1788527248 15:07:28 15:07:28 8 79496 17712 cap-wifi3 -52 309700000 573500000 3360 8208 00:08:36 00:00:00
49 1788527250 15:07:30 15:07:30 5 82824 26656 cap-wifi3 -52 309700000 573500000 3360 8208 00:08:38 00:00:00
50 1788527252 15:07:32 15:07:32 8 79440 24984 cap-wifi3 -52 309700000 573500000 3360 7808 00:08:40 00:00:00
51 1788527254 15:07:34 15:07:34 7 84240 17432 cap-wifi3 -52 309700000 573500000 5248 2960 00:08:42 00:00:00
52 1788527256 15:07:36 15:07:36 15 74928 18888 cap-wifi3 -52 309700000 573500000 5248 2960 00:08:44 00:00:00
53 1788527258 15:07:38 15:07:38 6 79856 17376 cap-wifi3 -51 309700000 573500000 3328 3520 00:08:46 00:00:00
54 1788527260 15:07:40 15:07:40 5 91680 31720 cap-wifi3 -52 275300000 573500000 2800 2960 00:08:48 00:00:00
55 1788527262 15:07:42 15:07:42 6 82760 21192 cap-wifi3 -52 275300000 573500000 2800 2960 00:08:50 00:00:00
56 1788527264 15:07:44 15:07:44 7 91960 31680 cap-wifi3 -51 275300000 573500000 2800 2960 00:08:52 00:00:00
57 1788527266 15:07:46 15:07:46 6 986832 256184 cap-wifi3 -51 275300000 573500000 3920 4144 00:08:54 00:00:00
58 1788527268 15:07:48 15:07:48 7 204344 305984 cap-wifi3 -51 275300000 573500000 3920 4144 00:08:56 00:00:00
59 1788527270 15:07:50 15:07:50 9 90376 25984 cap-wifi3 -52 258100000 573500000 2240 2368 00:08:58 00:00:00
60 1788527272 15:07:52 15:07:52 5 106024 28632 cap-wifi3 -52 258100000 286800000 2800 2960 00:09:00 00:00:00
61 1788527274 15:07:54 15:07:54 8 90816 27368 cap-wifi3 -52 258100000 286800000 2800 2960 00:09:02 00:00:00
62 1788527276 15:07:56 15:07:56 9 80656 22520 cap-wifi3 -52 258100000 573500000 2800 2960 00:09:04 00:00:00
63 1788527278 15:07:58 15:07:58 8 74792 15952 cap-wifi3 -54 258100000 412900000 2800 2960 00:09:06 00:00:00
64 1788527280 15:08:00 15:08:00 9 97280 32008 cap-wifi3 -54 258100000 412900000 2800 2960 00:09:08 00:00:00
65 1788527282 15:08:02 15:08:02 22 405584 131400 cap-wifi3 -55 258100000 412900000 2800 2960 00:09:10 00:00:00
66 1788527284 15:08:04 15:08:04 15 99616 29344 cap-wifi3 -53 258100000 433300000 2800 2960 00:09:12 00:00:00
67 1788527286 15:08:06 15:08:06 3 116040 34784 cap-wifi3 -53 258100000 433300000 2800 2960 00:09:14 00:00:00
68 1788527288 15:08:08 15:08:08 6 263752 46256 cap-wifi3 -54 258100000 455800000 2800 3360 00:09:16 00:00:00
69 1788527290 15:08:10 15:08:10 5 154688 74104 cap-wifi3 -54 258100000 487500000 2800 2960 00:09:18 00:00:00
70 1788527292 15:08:12 15:08:13 4 437800 144600 cap-wifi3 -54 258100000 487500000 2800 2960 00:09:20 00:00:00
71 1788527294 15:08:14 15:08:15 5 273784 69248 cap-wifi3 -56 258100000 390000000 3808 3552 00:09:22 00:00:00
72 1788527297 15:08:17 15:08:17 4 110840 33232 cap-wifi3 -56 258100000 433300000 2800 2960 00:09:24 00:00:00
73 1788527299 15:08:19 15:08:19 5 80584 34112 cap-wifi3 -55 258100000 455800000 3360 3552 00:09:26 00:00:00
74 1788527301 15:08:21 15:08:21 5 89992 25208 cap-wifi3 -55 258100000 455800000 3360 3552 00:09:28 00:00:00
75 1788527303 15:08:23 15:08:23 5 258520 122376 cap-wifi3 -56 258100000 433300000 2800 2960 00:09:30 00:00:00
76 1788527305 15:08:25 15:08:25 8 484544 159104 cap-wifi3 -55 258100000 455800000 2800 2960 00:09:33 00:00:00
77 1788527307 15:08:27 15:08:27 5 85832 21400 cap-wifi3 -55 258100000 455800000 2800 2960 00:09:35 00:00:00
78 1788527309 15:08:29 15:08:29 7 86968 23984 cap-wifi3 -56 258100000 433300000 2800 2960 00:09:37 00:00:00
79 1788527311 15:08:31 15:08:31 4 92848 27216 cap-wifi3 -57 258100000 455800000 2800 2960 00:09:39 00:00:00
80 1788527313 15:08:33 15:08:33 13 88112 30272 cap-wifi3 -57 258100000 455800000 2800 2960 00:09:41 00:00:00
81 1788527315 15:08:35 15:08:35 6 97568 38688 cap-wifi3 -57 258100000 433300000 2800 2960 00:09:43 00:00:00
82 1788527317 15:08:37 15:08:37 7 69376 15424 cap-wifi3 -58 258100000 455800000 3360 3552 00:09:45 00:00:00
83 1788527319 15:08:39 15:08:39 22 95672 27872 cap-wifi3 -58 258100000 455800000 3360 3552 00:09:47 00:00:00
84 1788527321 15:08:41 15:08:41 20 81008 14064 cap-wifi3 -58 258100000 433300000 2800 2960 00:09:49 00:00:00
85 1788527323 15:08:43 15:08:43 9 79480 19824 cap-wifi3 -59 258100000 325000000 3328 2960 00:09:51 00:00:00
86 1788527325 15:08:45 15:08:45 11 83080 28888 cap-wifi3 -59 258100000 325000000 3328 2960 00:09:53 00:00:00
87 1788527327 15:08:47 15:08:47 7 77224 19568 cap-wifi3 -59 258100000 390000000 3360 3952 00:09:55 00:00:00
88 1788527329 15:08:49 15:08:49 20 87976 23544 cap-wifi3 -58 258100000 412900000 2800 2960 00:09:57 00:00:00
89 1788527331 15:08:51 15:08:51 6 99288 43960 cap-wifi3 -58 258100000 412900000 2800 2960 00:09:59 00:00:00
90 1788527333 15:08:53 15:08:53 4 78784 16504 cap-wifi3 -58 258100000 390000000 3808 3552 00:10:01 00:00:00
91 1788527335 15:08:55 15:08:55 8 100664 43024 cap-wifi3 -52 6000000 412900000 3360 3552 00:10:03 00:00:00
92 1788527337 15:08:57 15:08:57 6 75392 68792 cap-wifi3 -52 6000000 412900000 3360 3552 00:10:05 00:00:00
93 1788527339 15:08:59 15:08:59 18 84648 23296 cap-wifi3 -52 258100000 433300000 2800 3360 00:10:07 00:00:00
94 1788527341 15:09:01 15:09:01 5 146608 49608 cap-wifi3 -53 258100000 455800000 2800 2960 00:10:09 00:00:00
95 1788527343 15:09:03 15:09:03 6 271512 52760 cap-wifi3 -53 258100000 455800000 2800 2960 00:10:11 00:00:00
96 1788527345 15:09:05 15:09:05 6 400696 3660640 cap-wifi3 -56 258100000 433300000 2800 2960 00:10:13 00:00:00
97 1788527347 15:09:07 15:09:07 6 131696 25096 cap-wifi3 -55 258100000 390000000 2800 2960 00:10:15 00:00:00
98 1788527349 15:09:09 15:09:09 19 213416 92736 cap-wifi3 -55 258100000 390000000 2800 2960 00:10:17 00:00:00
99 1788527351 15:09:11 15:09:11 6 319104 63216 cap-wifi3 -52 6000000 309700000 2800 2960 00:10:19 00:00:00
100 1788527353 15:09:13 15:09:13 8 153896 48144 cap-wifi3 -54 258100000 344100000 3360 3552 00:10:21 00:00:00
101 1788527355 15:09:15 15:09:15 5 190952 58360 cap-wifi3 -54 258100000 344100000 3360 3552 00:10:23 00:00:00
102 1788527357 15:09:17 15:09:17 7 232928 149512 cap-wifi3 -55 258100000 390000000 4080 6912 00:10:25 00:00:00
103 1788527359 15:09:19 15:09:20 19 108000 26560 cap-wifi3 -56 258100000 412900000 3360 3552 00:10:27 00:00:00
104 1788527361 15:09:21 15:09:22 10 2754208 213840 cap-wifi3 -56 258100000 412900000 3360 3552 00:10:29 00:00:00
105 1788527364 15:09:24 15:09:24 7 314040 73608 cap-wifi3 -55 258100000 216700000 15040 7600 00:10:31 00:00:00
106 1788527366 15:09:26 15:09:26 5 485488 100744 cap-wifi3 -54 258100000 229400000 3304 6992 00:10:33 00:00:00
107 1788527368 15:09:28 15:09:28 6 123816 28072 cap-wifi3 -54 258100000 229400000 3304 6992 00:10:35 00:00:00
108 1788527370 15:09:30 15:09:30 19 124944 35616 cap-wifi3 -56 258100000 433300000 2800 2960 00:10:37 00:00:00
109 1788527372 15:09:32 15:09:32 5 171352 44496 cap-wifi3 -54 258100000 433300000 4928 0 00:10:39 00:00:00
110 1788527374 15:09:34 15:09:34 6 166240 43784 cap-wifi3 -54 6000000 433300000 2800 0 00:10:42 00:00:00
111 1788527376 15:09:36 15:09:36 6 150760 49464 cap-wifi3 -54 6000000 433300000 2800 0 00:10:44 00:00:00
112 1788527378 15:09:38 15:09:38 10 185768 47120 cap-wifi3 -55 258100000 433300000 2800 6496 00:10:46 00:00:00
113 1788527380 15:09:40 15:09:40 18 190032 49512 cap-wifi3 -54 258100000 433300000 2240 0 00:10:48 00:00:00
114 1788527382 15:09:42 15:09:42 8 97808 22304 cap-wifi3 -54 258100000 433300000 2240 0 00:10:50 00:00:00
115 1788527384 15:09:44 15:09:44 8 148400 53672 cap-wifi3 -54 6000000 433300000 13464 368 00:10:52 00:00:00
116 1788527386 15:09:46 15:09:46 2 97568 37160 cap-wifi3 -54 258100000 455800000 2800 2960 00:10:54 00:00:00
117 1788527388 15:09:48 15:09:48 4 76456 19280 cap-wifi3 -54 258100000 455800000 2800 2960 00:10:56 00:00:00
118 1788527390 15:09:50 15:09:50 9 74488 14496 cap-wifi3 -54 258100000 390000000 2928 0 00:10:58 00:00:00
119 1788527392 15:09:52 15:09:52 9 81688 114120 cap-wifi3 -54 258100000 390000000 2240 0 00:11:00 00:00:00
120 1788527394 15:09:54 15:09:54 11 139472 94312 cap-wifi3 -54 258100000 390000000 2240 0 00:11:02 00:00:00
121 1788527396 15:09:56 15:09:56 8 99376 34800 cap-wifi3 -54 258100000 390000000 2240 0 00:11:04 00:00:00
122 1788527398 15:09:58 15:09:58 7 95624 20936 cap-wifi3 -54 258100000 390000000 2800 0 00:11:06 00:00:00
123 1788527400 15:10:00 15:10:00 11 75688 17080 cap-wifi3 -54 258100000 390000000 2800 0 00:11:08 00:00:00
124 1788527402 15:10:02 15:10:02 8 194448 59984 cap-wifi3 -54 258100000 390000000 2240 0 00:11:10 00:00:00
125 1788527404 15:10:04 15:10:04 5 87848 23392 cap-wifi3 -54 258100000 390000000 5040 0 00:11:12 00:00:00
126 1788527406 15:10:06 15:10:06 4 102440 31824 cap-wifi3 -54 258100000 390000000 5040 0 00:11:14 00:00:00
127 1788527408 15:10:08 15:10:08 7 140352 49312 cap-wifi3 -54 258100000 390000000 2800 0 00:11:16 00:00:00
128 1788527410 15:10:10 15:10:10 20 81216 18128 cap-wifi3 -53 258100000 390000000 2688 0 00:11:18 00:00:00
129 1788527412 15:10:12 15:10:12 8 223088 23248 cap-wifi3 -53 258100000 390000000 2688 0 00:11:20 00:00:00
130 1788527414 15:10:14 15:10:14 7 139784 51840 cap-wifi3 -54 258100000 390000000 2240 0 00:11:22 00:00:00
131 1788527415 15:10:15 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-ipad.csv (Takt 2s, Client CA:B8:D4:3F:8A:81)

View File

@@ -0,0 +1,2 @@
14:58:12 Verbindung weg -- neuer Versuch in 2 s
15:10:15 Verbindung weg -- neuer Versuch in 2 s

View File

@@ -0,0 +1,130 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788527155,15:05:55,RECONNECT
1788527159,15:05:59,15:05:59,26,895392,176224,cap-wifi3,-63,154900000,309700000,15624,7104,00:13:12,00:00:00
1788527161,15:06:01,15:06:01,12,271768,3546664,cap-wifi3,-61,154900000,325000000,4576,3552,00:13:14,00:00:00
1788527163,15:06:03,15:06:03,11,212384,57592,cap-wifi3,-61,154900000,325000000,4576,3552,00:13:16,00:00:00
1788527165,15:06:05,15:06:05,6,119880,34152,cap-wifi3,-59,154900000,325000000,2240,0,00:13:18,00:00:00
1788527167,15:06:07,15:06:07,6,285512,62760,cap-wifi3,-58,154900000,325000000,3360,0,00:13:20,00:00:00
1788527169,15:06:09,15:06:09,18,135200,33432,cap-wifi3,-58,154900000,325000000,3360,0,00:13:22,00:00:00
1788527171,15:06:11,15:06:11,2,80168,35552,cap-wifi3,-58,154900000,325000000,2240,0,00:13:24,00:00:00
1788527173,15:06:13,15:06:13,6,263824,45616,cap-wifi3,-57,154900000,325000000,3360,0,00:13:26,00:00:00
1788527175,15:06:15,15:06:15,4,139448,79056,cap-wifi3,-57,154900000,325000000,3360,0,00:13:28,00:00:00
1788527177,15:06:17,15:06:17,7,125944,34792,cap-wifi3,-58,154900000,325000000,1680,0,00:13:30,00:00:00
1788527179,15:06:19,15:06:19,21,228896,34848,cap-wifi3,-60,154900000,325000000,0,0,00:13:32,00:00:00
1788527181,15:06:21,15:06:21,6,91344,100616,cap-wifi3,-60,154900000,325000000,0,0,00:13:34,00:00:00
1788527183,15:06:23,15:06:23,8,1161368,460544,cap-wifi3,-62,154900000,325000000,4368,4592,00:13:36,00:00:00
1788527185,15:06:25,15:06:25,9,669424,189984,cap-wifi3,-56,154900000,344100000,2800,3712,00:13:38,00:00:00
1788527187,15:06:27,15:06:27,8,220472,72928,cap-wifi3,-56,154900000,344100000,2800,3712,00:13:40,00:00:00
1788527189,15:06:29,15:06:29,19,85696,19672,cap-wifi3,-60,154900000,325000000,4880,10808,00:13:42,00:00:00
1788527191,15:06:31,15:06:31,7,80008,30360,cap-wifi3,-48,154900000,309700000,4080,4992,00:13:44,00:00:00
1788527193,15:06:33,15:06:33,7,85392,35808,cap-wifi3,-48,154900000,309700000,4080,4992,00:13:46,00:00:00
1788527195,15:06:35,15:06:35,7,81000,33304,cap-wifi3,-52,154900000,325000000,2800,2960,00:13:48,00:00:00
1788527197,15:06:37,15:06:37,11,80840,16392,cap-wifi3,-60,154900000,344100000,2800,2960,00:13:50,00:00:00
1788527199,15:06:39,15:06:39,19,479584,403096,cap-wifi3,-60,154900000,344100000,2800,2960,00:13:52,00:00:00
1788527201,15:06:41,15:06:41,6,83504,18032,cap-wifi3,-54,154900000,390000000,2800,2960,00:13:54,00:00:00
1788527203,15:06:43,15:06:43,8,94312,27480,cap-wifi3,-52,154900000,412900000,3776,3552,00:13:56,00:00:00
1788527205,15:06:45,15:06:45,7,139816,113728,cap-wifi3,-54,154900000,455800000,3360,3552,00:13:58,00:00:00
1788527207,15:06:47,15:06:47,8,77512,23304,cap-wifi3,-54,154900000,455800000,3360,3552,00:14:00,00:00:00
1788527209,15:06:49,15:06:49,22,135424,86176,cap-wifi3,-53,206500000,455800000,2800,2960,00:14:02,00:00:00
1788527211,15:06:51,15:06:51,6,80072,20128,cap-wifi3,-53,12000000,516200000,2800,2960,00:14:04,00:00:00
1788527213,15:06:53,15:06:53,7,81544,23592,cap-wifi3,-53,12000000,516200000,2800,2960,00:14:06,00:00:00
1788527215,15:06:55,15:06:55,8,118248,77704,cap-wifi3,-54,206500000,573500000,3248,3552,00:14:08,00:00:00
1788527217,15:06:57,15:06:58,6,115296,40584,cap-wifi3,-53,206500000,573500000,3360,3552,00:14:10,00:00:00
1788527219,15:06:59,15:07:00,36,72144,17920,cap-wifi3,-53,206500000,573500000,3360,3552,00:14:12,00:00:00
1788527221,15:07:01,15:07:02,6,87272,19464,cap-wifi3,-55,206500000,412900000,2800,2960,00:14:14,00:00:00
1788527224,15:07:04,15:07:04,7,341584,177744,cap-wifi3,-55,206500000,455800000,2800,2960,00:14:16,00:00:00
1788527226,15:07:06,15:07:06,5,96008,29072,cap-wifi3,-55,206500000,455800000,2800,2960,00:14:18,00:00:00
1788527228,15:07:08,15:07:08,9,88184,20760,cap-wifi3,-54,206500000,455800000,2800,2960,00:14:21,00:00:00
1788527230,15:07:10,15:07:10,19,245616,37632,cap-wifi3,-55,206500000,433300000,2800,2960,00:14:23,00:00:00
1788527232,15:07:12,15:07:12,7,136904,41680,cap-wifi3,-55,206500000,433300000,2800,2960,00:14:25,00:00:00
1788527234,15:07:14,15:07:14,5,176432,193240,cap-wifi3,-54,206500000,455800000,2800,2960,00:14:27,00:00:00
1788527236,15:07:16,15:07:16,5,668616,412672,cap-wifi3,-53,206500000,487500000,3360,3552,00:14:29,00:00:00
1788527238,15:07:18,15:07:18,12,10040200,401976,cap-wifi3,-53,206500000,487500000,3360,3552,00:14:31,00:00:00
1788527240,15:07:20,15:07:20,21,6694840,181608,cap-wifi3,-53,6000000,516200000,2800,3336,00:14:33,00:00:00
1788527242,15:07:22,15:07:22,7,269904,95904,cap-wifi3,-53,206500000,487500000,2800,2960,00:14:35,00:00:00
1788527244,15:07:24,15:07:24,6,97040,38768,cap-wifi3,-53,206500000,487500000,2800,2960,00:14:37,00:00:00
1788527246,15:07:26,15:07:26,6,265536,57040,cap-wifi3,-53,206500000,516200000,3360,3552,00:14:39,00:00:00
1788527248,15:07:28,15:07:28,8,79496,17712,cap-wifi3,-52,206500000,487500000,2800,2960,00:14:41,00:00:00
1788527250,15:07:30,15:07:30,20,82824,26656,cap-wifi3,-52,206500000,487500000,2800,2960,00:14:43,00:00:00
1788527252,15:07:32,15:07:32,8,79440,24984,cap-wifi3,-53,206500000,516200000,2800,2960,00:14:45,00:00:00
1788527254,15:07:34,15:07:34,7,84240,17432,cap-wifi3,-51,206500000,541700000,4560,3552,00:14:47,00:00:00
1788527256,15:07:36,15:07:36,15,74928,18888,cap-wifi3,-51,206500000,541700000,4560,3552,00:14:49,00:00:00
1788527258,15:07:38,15:07:38,6,79856,17376,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:51,00:00:00
1788527260,15:07:40,15:07:40,5,91680,31720,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:53,00:00:00
1788527262,15:07:42,15:07:42,6,82760,21192,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:55,00:00:00
1788527264,15:07:44,15:07:44,7,91960,31680,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:57,00:00:00
1788527266,15:07:46,15:07:46,6,986832,256184,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:59,00:00:00
1788527268,15:07:48,15:07:48,7,204344,305984,cap-wifi3,-51,206500000,573500000,2800,2960,00:15:01,00:00:00
1788527270,15:07:50,15:07:50,9,90376,25984,cap-wifi3,-51,206500000,516200000,3248,3328,00:15:03,00:00:00
1788527272,15:07:52,15:07:52,5,106024,28632,cap-wifi3,-50,12000000,516200000,3808,3920,00:15:05,00:00:00
1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-50,12000000,516200000,3808,3920,00:15:07,00:00:00
1788527276,15:07:56,15:07:56,9,68568,17040,cap-wifi3,-51,206500000,541700000,2800,2960,00:15:09,00:00:00
1788527278,15:07:58,15:07:58,8,104792,53200,cap-wifi3,-51,206500000,390000000,3360,3552,00:15:11,00:00:00
1788527280,15:08:00,15:08:00,9,304368,102592,cap-wifi3,-51,206500000,390000000,3360,3552,00:15:13,00:00:00
1788527282,15:08:02,15:08:02,22,74432,14824,cap-wifi3,-50,24000000,412900000,2800,2960,00:15:15,00:00:00
1788527284,15:08:04,15:08:04,15,99616,29344,cap-wifi3,-51,154900000,433300000,3360,3552,00:15:17,00:00:00
1788527286,15:08:06,15:08:06,3,116040,34784,cap-wifi3,-51,154900000,433300000,3360,3552,00:15:19,00:00:00
1788527288,15:08:08,15:08:08,6,263752,46256,cap-wifi3,-50,24000000,455800000,2800,2960,00:15:21,00:00:00
1788527290,15:08:10,15:08:10,5,154688,74104,cap-wifi3,-51,154900000,487500000,2800,2960,00:15:23,00:00:00
1788527292,15:08:12,15:08:12,4,437800,144600,cap-wifi3,-51,154900000,487500000,2800,2960,00:15:25,00:00:00
1788527294,15:08:14,15:08:14,5,273784,69248,cap-wifi3,-50,154900000,516200000,3248,3552,00:15:27,00:00:00
1788527296,15:08:16,15:08:16,4,110840,33232,cap-wifi3,-50,154900000,541700000,2800,2960,00:15:29,00:00:00
1788527298,15:08:18,15:08:18,5,80584,34112,cap-wifi3,-50,154900000,541700000,2800,2960,00:15:31,00:00:00
1788527300,15:08:20,15:08:20,5,89992,25208,cap-wifi3,-51,206500000,573500000,3360,3928,00:15:33,00:00:00
1788527302,15:08:22,15:08:23,5,258520,122376,cap-wifi3,-50,206500000,573500000,2800,2960,00:15:35,00:00:00
1788527304,15:08:24,15:08:25,8,484544,159104,cap-wifi3,-50,206500000,573500000,2800,2960,00:15:37,00:00:00
1788527306,15:08:26,15:08:27,5,85832,21400,cap-wifi3,-52,206500000,573500000,6336,6536,00:15:39,00:00:00
1788527309,15:08:29,15:08:29,7,86968,23984,cap-wifi3,-51,206500000,573500000,4384,5704,00:15:41,00:00:00
1788527311,15:08:31,15:08:31,4,92848,27216,cap-wifi3,-50,24000000,573500000,3360,2960,00:15:44,00:00:00
1788527313,15:08:33,15:08:33,13,88112,30272,cap-wifi3,-50,24000000,573500000,3360,2960,00:15:46,00:00:00
1788527315,15:08:35,15:08:35,6,97568,38688,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:48,00:00:00
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:50,00:00:00
1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:52,00:00:00
1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-52,172100000,573500000,5648,5744,00:15:54,00:00:00
1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-51,172100000,573500000,3360,3552,00:15:56,00:00:00
1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-51,172100000,573500000,3360,3552,00:15:58,00:00:00
1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-52,172100000,573500000,2800,2960,00:16:00,00:00:00
1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-53,172100000,573500000,2800,2960,00:16:02,00:00:00
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-53,172100000,573500000,2800,2960,00:16:04,00:00:00
1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-56,172100000,455800000,4416,4840,00:16:06,00:00:00
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-56,154900000,344100000,3408,3656,00:16:08,00:00:00
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-56,154900000,344100000,3408,3656,00:16:10,00:00:00
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-53,154900000,344100000,3936,4496,00:16:12,00:00:00
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-53,154900000,325000000,3408,3656,00:16:14,00:00:00
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-53,154900000,325000000,3408,3656,00:16:16,00:00:00
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-51,154900000,344100000,3408,2960,00:16:18,00:00:00
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-58,154900000,325000000,4896,5048,00:16:20,00:00:00
1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-58,154900000,325000000,4896,5048,00:16:22,00:00:00
1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-50,206500000,344100000,3408,3656,00:16:24,00:00:00
1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-46,206500000,412900000,3968,4248,00:16:26,00:00:00
1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-46,206500000,412900000,3968,4248,00:16:28,00:00:00
1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-59,206500000,433300000,3408,3656,00:16:30,00:00:00
1788527359,15:09:19,15:09:19,19,108000,26560,cap-wifi3,-60,206500000,344100000,3856,4032,00:16:32,00:00:00
1788527361,15:09:21,15:09:21,10,2754208,213840,cap-wifi3,-60,206500000,344100000,3856,4032,00:16:34,00:00:00
1788527363,15:09:23,15:09:24,7,314040,73608,cap-wifi3,-60,206500000,325000000,5488,11504,00:16:36,00:00:00
1788527365,15:09:25,15:09:26,5,485488,100744,cap-wifi3,-60,206500000,344100000,4736,5096,00:16:38,00:00:00
1788527367,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-60,206500000,344100000,4736,5096,00:16:40,00:00:00
1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-61,154900000,292500000,2800,0,00:16:42,00:00:00
1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-60,137600000,325000000,3136,368,00:16:44,00:00:00
1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-60,137600000,325000000,3136,368,00:16:47,00:00:00
1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-55,172100000,309700000,15056,42256,00:16:49,00:00:00
1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-62,172100000,325000000,3408,3656,00:16:51,00:00:00
1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-62,172100000,344100000,3408,3656,00:16:53,00:00:00
1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-62,172100000,344100000,3408,3656,00:16:55,00:00:00
1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-63,12000000,412900000,3856,10808,00:16:57,00:00:00
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-62,172100000,412900000,2800,2960,00:16:59,00:00:00
1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-62,172100000,412900000,2800,2960,00:17:01,00:00:00
1788527390,15:09:50,15:09:50,17,74488,14496,cap-wifi3,-64,172100000,325000000,7688,7440,00:17:03,00:00:00
1788527392,15:09:52,15:09:52,4,81688,114120,cap-wifi3,-62,172100000,344100000,3888,4768,00:17:05,00:00:00
1788527394,15:09:54,15:09:54,8,139472,94312,cap-wifi3,-62,172100000,344100000,3888,4768,00:17:07,00:00:00
1788527396,15:09:56,15:09:56,4,99376,34800,cap-wifi3,-63,172100000,412900000,3328,3424,00:17:09,00:00:00
1788527398,15:09:58,15:09:58,5,95624,20936,cap-wifi3,-62,172100000,412900000,3360,3552,00:17:11,00:00:00
1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-62,172100000,412900000,3360,3552,00:17:13,00:00:00
1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-61,172100000,390000000,2800,0,00:17:15,00:00:00
1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-60,172100000,390000000,2128,368,00:17:17,00:00:00
1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-60,172100000,390000000,2128,368,00:17:19,00:00:00
1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-61,172100000,390000000,2240,0,00:17:21,00:00:00
1788527410,15:10:10,15:10:10,20,88352,30376,cap-wifi3,-61,137600000,390000000,3248,0,00:17:23,00:00:00
1788527412,15:10:12,15:10:12,8,124328,46808,cap-wifi3,-61,137600000,390000000,3248,0,00:17:25,00:00:00
1788527414,15:10:14,15:10:14,7,84784,23040,cap-wifi3,-61,137600000,390000000,2800,0,00:17:27,00:00:00
1788527415,15:10:15,RECONNECT
1 ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
2 1788527155,15:05:55,RECONNECT
3 1788527159,15:05:59,15:05:59,26,895392,176224,cap-wifi3,-63,154900000,309700000,15624,7104,00:13:12,00:00:00
4 1788527161,15:06:01,15:06:01,12,271768,3546664,cap-wifi3,-61,154900000,325000000,4576,3552,00:13:14,00:00:00
5 1788527163,15:06:03,15:06:03,11,212384,57592,cap-wifi3,-61,154900000,325000000,4576,3552,00:13:16,00:00:00
6 1788527165,15:06:05,15:06:05,6,119880,34152,cap-wifi3,-59,154900000,325000000,2240,0,00:13:18,00:00:00
7 1788527167,15:06:07,15:06:07,6,285512,62760,cap-wifi3,-58,154900000,325000000,3360,0,00:13:20,00:00:00
8 1788527169,15:06:09,15:06:09,18,135200,33432,cap-wifi3,-58,154900000,325000000,3360,0,00:13:22,00:00:00
9 1788527171,15:06:11,15:06:11,2,80168,35552,cap-wifi3,-58,154900000,325000000,2240,0,00:13:24,00:00:00
10 1788527173,15:06:13,15:06:13,6,263824,45616,cap-wifi3,-57,154900000,325000000,3360,0,00:13:26,00:00:00
11 1788527175,15:06:15,15:06:15,4,139448,79056,cap-wifi3,-57,154900000,325000000,3360,0,00:13:28,00:00:00
12 1788527177,15:06:17,15:06:17,7,125944,34792,cap-wifi3,-58,154900000,325000000,1680,0,00:13:30,00:00:00
13 1788527179,15:06:19,15:06:19,21,228896,34848,cap-wifi3,-60,154900000,325000000,0,0,00:13:32,00:00:00
14 1788527181,15:06:21,15:06:21,6,91344,100616,cap-wifi3,-60,154900000,325000000,0,0,00:13:34,00:00:00
15 1788527183,15:06:23,15:06:23,8,1161368,460544,cap-wifi3,-62,154900000,325000000,4368,4592,00:13:36,00:00:00
16 1788527185,15:06:25,15:06:25,9,669424,189984,cap-wifi3,-56,154900000,344100000,2800,3712,00:13:38,00:00:00
17 1788527187,15:06:27,15:06:27,8,220472,72928,cap-wifi3,-56,154900000,344100000,2800,3712,00:13:40,00:00:00
18 1788527189,15:06:29,15:06:29,19,85696,19672,cap-wifi3,-60,154900000,325000000,4880,10808,00:13:42,00:00:00
19 1788527191,15:06:31,15:06:31,7,80008,30360,cap-wifi3,-48,154900000,309700000,4080,4992,00:13:44,00:00:00
20 1788527193,15:06:33,15:06:33,7,85392,35808,cap-wifi3,-48,154900000,309700000,4080,4992,00:13:46,00:00:00
21 1788527195,15:06:35,15:06:35,7,81000,33304,cap-wifi3,-52,154900000,325000000,2800,2960,00:13:48,00:00:00
22 1788527197,15:06:37,15:06:37,11,80840,16392,cap-wifi3,-60,154900000,344100000,2800,2960,00:13:50,00:00:00
23 1788527199,15:06:39,15:06:39,19,479584,403096,cap-wifi3,-60,154900000,344100000,2800,2960,00:13:52,00:00:00
24 1788527201,15:06:41,15:06:41,6,83504,18032,cap-wifi3,-54,154900000,390000000,2800,2960,00:13:54,00:00:00
25 1788527203,15:06:43,15:06:43,8,94312,27480,cap-wifi3,-52,154900000,412900000,3776,3552,00:13:56,00:00:00
26 1788527205,15:06:45,15:06:45,7,139816,113728,cap-wifi3,-54,154900000,455800000,3360,3552,00:13:58,00:00:00
27 1788527207,15:06:47,15:06:47,8,77512,23304,cap-wifi3,-54,154900000,455800000,3360,3552,00:14:00,00:00:00
28 1788527209,15:06:49,15:06:49,22,135424,86176,cap-wifi3,-53,206500000,455800000,2800,2960,00:14:02,00:00:00
29 1788527211,15:06:51,15:06:51,6,80072,20128,cap-wifi3,-53,12000000,516200000,2800,2960,00:14:04,00:00:00
30 1788527213,15:06:53,15:06:53,7,81544,23592,cap-wifi3,-53,12000000,516200000,2800,2960,00:14:06,00:00:00
31 1788527215,15:06:55,15:06:55,8,118248,77704,cap-wifi3,-54,206500000,573500000,3248,3552,00:14:08,00:00:00
32 1788527217,15:06:57,15:06:58,6,115296,40584,cap-wifi3,-53,206500000,573500000,3360,3552,00:14:10,00:00:00
33 1788527219,15:06:59,15:07:00,36,72144,17920,cap-wifi3,-53,206500000,573500000,3360,3552,00:14:12,00:00:00
34 1788527221,15:07:01,15:07:02,6,87272,19464,cap-wifi3,-55,206500000,412900000,2800,2960,00:14:14,00:00:00
35 1788527224,15:07:04,15:07:04,7,341584,177744,cap-wifi3,-55,206500000,455800000,2800,2960,00:14:16,00:00:00
36 1788527226,15:07:06,15:07:06,5,96008,29072,cap-wifi3,-55,206500000,455800000,2800,2960,00:14:18,00:00:00
37 1788527228,15:07:08,15:07:08,9,88184,20760,cap-wifi3,-54,206500000,455800000,2800,2960,00:14:21,00:00:00
38 1788527230,15:07:10,15:07:10,19,245616,37632,cap-wifi3,-55,206500000,433300000,2800,2960,00:14:23,00:00:00
39 1788527232,15:07:12,15:07:12,7,136904,41680,cap-wifi3,-55,206500000,433300000,2800,2960,00:14:25,00:00:00
40 1788527234,15:07:14,15:07:14,5,176432,193240,cap-wifi3,-54,206500000,455800000,2800,2960,00:14:27,00:00:00
41 1788527236,15:07:16,15:07:16,5,668616,412672,cap-wifi3,-53,206500000,487500000,3360,3552,00:14:29,00:00:00
42 1788527238,15:07:18,15:07:18,12,10040200,401976,cap-wifi3,-53,206500000,487500000,3360,3552,00:14:31,00:00:00
43 1788527240,15:07:20,15:07:20,21,6694840,181608,cap-wifi3,-53,6000000,516200000,2800,3336,00:14:33,00:00:00
44 1788527242,15:07:22,15:07:22,7,269904,95904,cap-wifi3,-53,206500000,487500000,2800,2960,00:14:35,00:00:00
45 1788527244,15:07:24,15:07:24,6,97040,38768,cap-wifi3,-53,206500000,487500000,2800,2960,00:14:37,00:00:00
46 1788527246,15:07:26,15:07:26,6,265536,57040,cap-wifi3,-53,206500000,516200000,3360,3552,00:14:39,00:00:00
47 1788527248,15:07:28,15:07:28,8,79496,17712,cap-wifi3,-52,206500000,487500000,2800,2960,00:14:41,00:00:00
48 1788527250,15:07:30,15:07:30,20,82824,26656,cap-wifi3,-52,206500000,487500000,2800,2960,00:14:43,00:00:00
49 1788527252,15:07:32,15:07:32,8,79440,24984,cap-wifi3,-53,206500000,516200000,2800,2960,00:14:45,00:00:00
50 1788527254,15:07:34,15:07:34,7,84240,17432,cap-wifi3,-51,206500000,541700000,4560,3552,00:14:47,00:00:00
51 1788527256,15:07:36,15:07:36,15,74928,18888,cap-wifi3,-51,206500000,541700000,4560,3552,00:14:49,00:00:00
52 1788527258,15:07:38,15:07:38,6,79856,17376,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:51,00:00:00
53 1788527260,15:07:40,15:07:40,5,91680,31720,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:53,00:00:00
54 1788527262,15:07:42,15:07:42,6,82760,21192,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:55,00:00:00
55 1788527264,15:07:44,15:07:44,7,91960,31680,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:57,00:00:00
56 1788527266,15:07:46,15:07:46,6,986832,256184,cap-wifi3,-51,206500000,573500000,2800,2960,00:14:59,00:00:00
57 1788527268,15:07:48,15:07:48,7,204344,305984,cap-wifi3,-51,206500000,573500000,2800,2960,00:15:01,00:00:00
58 1788527270,15:07:50,15:07:50,9,90376,25984,cap-wifi3,-51,206500000,516200000,3248,3328,00:15:03,00:00:00
59 1788527272,15:07:52,15:07:52,5,106024,28632,cap-wifi3,-50,12000000,516200000,3808,3920,00:15:05,00:00:00
60 1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-50,12000000,516200000,3808,3920,00:15:07,00:00:00
61 1788527276,15:07:56,15:07:56,9,68568,17040,cap-wifi3,-51,206500000,541700000,2800,2960,00:15:09,00:00:00
62 1788527278,15:07:58,15:07:58,8,104792,53200,cap-wifi3,-51,206500000,390000000,3360,3552,00:15:11,00:00:00
63 1788527280,15:08:00,15:08:00,9,304368,102592,cap-wifi3,-51,206500000,390000000,3360,3552,00:15:13,00:00:00
64 1788527282,15:08:02,15:08:02,22,74432,14824,cap-wifi3,-50,24000000,412900000,2800,2960,00:15:15,00:00:00
65 1788527284,15:08:04,15:08:04,15,99616,29344,cap-wifi3,-51,154900000,433300000,3360,3552,00:15:17,00:00:00
66 1788527286,15:08:06,15:08:06,3,116040,34784,cap-wifi3,-51,154900000,433300000,3360,3552,00:15:19,00:00:00
67 1788527288,15:08:08,15:08:08,6,263752,46256,cap-wifi3,-50,24000000,455800000,2800,2960,00:15:21,00:00:00
68 1788527290,15:08:10,15:08:10,5,154688,74104,cap-wifi3,-51,154900000,487500000,2800,2960,00:15:23,00:00:00
69 1788527292,15:08:12,15:08:12,4,437800,144600,cap-wifi3,-51,154900000,487500000,2800,2960,00:15:25,00:00:00
70 1788527294,15:08:14,15:08:14,5,273784,69248,cap-wifi3,-50,154900000,516200000,3248,3552,00:15:27,00:00:00
71 1788527296,15:08:16,15:08:16,4,110840,33232,cap-wifi3,-50,154900000,541700000,2800,2960,00:15:29,00:00:00
72 1788527298,15:08:18,15:08:18,5,80584,34112,cap-wifi3,-50,154900000,541700000,2800,2960,00:15:31,00:00:00
73 1788527300,15:08:20,15:08:20,5,89992,25208,cap-wifi3,-51,206500000,573500000,3360,3928,00:15:33,00:00:00
74 1788527302,15:08:22,15:08:23,5,258520,122376,cap-wifi3,-50,206500000,573500000,2800,2960,00:15:35,00:00:00
75 1788527304,15:08:24,15:08:25,8,484544,159104,cap-wifi3,-50,206500000,573500000,2800,2960,00:15:37,00:00:00
76 1788527306,15:08:26,15:08:27,5,85832,21400,cap-wifi3,-52,206500000,573500000,6336,6536,00:15:39,00:00:00
77 1788527309,15:08:29,15:08:29,7,86968,23984,cap-wifi3,-51,206500000,573500000,4384,5704,00:15:41,00:00:00
78 1788527311,15:08:31,15:08:31,4,92848,27216,cap-wifi3,-50,24000000,573500000,3360,2960,00:15:44,00:00:00
79 1788527313,15:08:33,15:08:33,13,88112,30272,cap-wifi3,-50,24000000,573500000,3360,2960,00:15:46,00:00:00
80 1788527315,15:08:35,15:08:35,6,97568,38688,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:48,00:00:00
81 1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:50,00:00:00
82 1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-51,172100000,573500000,2800,2960,00:15:52,00:00:00
83 1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-52,172100000,573500000,5648,5744,00:15:54,00:00:00
84 1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-51,172100000,573500000,3360,3552,00:15:56,00:00:00
85 1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-51,172100000,573500000,3360,3552,00:15:58,00:00:00
86 1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-52,172100000,573500000,2800,2960,00:16:00,00:00:00
87 1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-53,172100000,573500000,2800,2960,00:16:02,00:00:00
88 1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-53,172100000,573500000,2800,2960,00:16:04,00:00:00
89 1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-56,172100000,455800000,4416,4840,00:16:06,00:00:00
90 1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-56,154900000,344100000,3408,3656,00:16:08,00:00:00
91 1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-56,154900000,344100000,3408,3656,00:16:10,00:00:00
92 1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-53,154900000,344100000,3936,4496,00:16:12,00:00:00
93 1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-53,154900000,325000000,3408,3656,00:16:14,00:00:00
94 1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-53,154900000,325000000,3408,3656,00:16:16,00:00:00
95 1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-51,154900000,344100000,3408,2960,00:16:18,00:00:00
96 1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-58,154900000,325000000,4896,5048,00:16:20,00:00:00
97 1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-58,154900000,325000000,4896,5048,00:16:22,00:00:00
98 1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-50,206500000,344100000,3408,3656,00:16:24,00:00:00
99 1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-46,206500000,412900000,3968,4248,00:16:26,00:00:00
100 1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-46,206500000,412900000,3968,4248,00:16:28,00:00:00
101 1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-59,206500000,433300000,3408,3656,00:16:30,00:00:00
102 1788527359,15:09:19,15:09:19,19,108000,26560,cap-wifi3,-60,206500000,344100000,3856,4032,00:16:32,00:00:00
103 1788527361,15:09:21,15:09:21,10,2754208,213840,cap-wifi3,-60,206500000,344100000,3856,4032,00:16:34,00:00:00
104 1788527363,15:09:23,15:09:24,7,314040,73608,cap-wifi3,-60,206500000,325000000,5488,11504,00:16:36,00:00:00
105 1788527365,15:09:25,15:09:26,5,485488,100744,cap-wifi3,-60,206500000,344100000,4736,5096,00:16:38,00:00:00
106 1788527367,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-60,206500000,344100000,4736,5096,00:16:40,00:00:00
107 1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-61,154900000,292500000,2800,0,00:16:42,00:00:00
108 1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-60,137600000,325000000,3136,368,00:16:44,00:00:00
109 1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-60,137600000,325000000,3136,368,00:16:47,00:00:00
110 1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-55,172100000,309700000,15056,42256,00:16:49,00:00:00
111 1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-62,172100000,325000000,3408,3656,00:16:51,00:00:00
112 1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-62,172100000,344100000,3408,3656,00:16:53,00:00:00
113 1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-62,172100000,344100000,3408,3656,00:16:55,00:00:00
114 1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-63,12000000,412900000,3856,10808,00:16:57,00:00:00
115 1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-62,172100000,412900000,2800,2960,00:16:59,00:00:00
116 1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-62,172100000,412900000,2800,2960,00:17:01,00:00:00
117 1788527390,15:09:50,15:09:50,17,74488,14496,cap-wifi3,-64,172100000,325000000,7688,7440,00:17:03,00:00:00
118 1788527392,15:09:52,15:09:52,4,81688,114120,cap-wifi3,-62,172100000,344100000,3888,4768,00:17:05,00:00:00
119 1788527394,15:09:54,15:09:54,8,139472,94312,cap-wifi3,-62,172100000,344100000,3888,4768,00:17:07,00:00:00
120 1788527396,15:09:56,15:09:56,4,99376,34800,cap-wifi3,-63,172100000,412900000,3328,3424,00:17:09,00:00:00
121 1788527398,15:09:58,15:09:58,5,95624,20936,cap-wifi3,-62,172100000,412900000,3360,3552,00:17:11,00:00:00
122 1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-62,172100000,412900000,3360,3552,00:17:13,00:00:00
123 1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-61,172100000,390000000,2800,0,00:17:15,00:00:00
124 1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-60,172100000,390000000,2128,368,00:17:17,00:00:00
125 1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-60,172100000,390000000,2128,368,00:17:19,00:00:00
126 1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-61,172100000,390000000,2240,0,00:17:21,00:00:00
127 1788527410,15:10:10,15:10:10,20,88352,30376,cap-wifi3,-61,137600000,390000000,3248,0,00:17:23,00:00:00
128 1788527412,15:10:12,15:10:12,8,124328,46808,cap-wifi3,-61,137600000,390000000,3248,0,00:17:25,00:00:00
129 1788527414,15:10:14,15:10:14,7,84784,23040,cap-wifi3,-61,137600000,390000000,2800,0,00:17:27,00:00:00
130 1788527415,15:10:15,RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-iphone.csv (Takt 2s, Client F2:62:4C:E1:AF:09)

View File

@@ -0,0 +1,9 @@
14:58:12 Verbindung weg -- neuer Versuch in 2 s
ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory
admin@10.40.99.1: Permission denied (publickey,password).
15:05:55 Verbindung weg -- neuer Versuch in 2 s
15:10:15 Verbindung weg -- neuer Versuch in 2 s

View File

@@ -0,0 +1,130 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788527155,15:05:55,15:05:55,26,215104,164208,cap-wifi3,-59,344100000,455800000,1108432,1179376,00:06:21,00:00:00
1788527157,15:05:57,15:05:57,10,230144,103104,cap-wifi3,-58,412900000,455800000,376304,298808,00:06:23,00:00:00
1788527159,15:05:59,15:05:59,27,997352,175928,cap-wifi3,-58,412900000,455800000,376304,298808,00:06:25,00:00:00
1788527161,15:06:01,15:06:01,5,496624,179032,cap-wifi3,-60,455800000,455800000,2283840,1594024,00:06:27,00:00:00
1788527163,15:06:03,15:06:03,7,112272,25664,cap-wifi3,-61,455800000,344100000,71224,20160,00:06:30,00:00:00
1788527165,15:06:05,15:06:06,6,353280,101384,cap-wifi3,-61,455800000,344100000,71224,20160,00:06:32,00:00:00
1788527167,15:06:08,15:06:08,6,137256,37360,cap-wifi3,-63,344100000,344100000,1205496,674488,00:06:34,00:00:00
1788527170,15:06:10,15:06:10,18,373144,1851168,cap-wifi3,-62,344100000,455800000,625632,2151904,00:06:36,00:00:00
1788527172,15:06:12,15:06:12,2,79504,15688,cap-wifi3,-62,344100000,455800000,625632,2151904,00:06:38,00:00:00
1788527174,15:06:14,15:06:14,6,215576,3512448,cap-wifi3,-61,412900000,412900000,720568,420128,00:06:40,00:00:00
1788527176,15:06:16,15:06:16,4,170440,37144,cap-wifi3,-63,344100000,309700000,1040816,801272,00:06:42,00:00:00
1788527178,15:06:18,15:06:18,7,187488,1860720,cap-wifi3,-63,344100000,309700000,1040816,801272,00:06:44,00:00:00
1788527180,15:06:20,15:06:20,21,418584,3563696,cap-wifi3,-63,412900000,275300000,496424,2170904,00:06:46,00:00:00
1788527182,15:06:22,15:06:22,6,91920,32648,cap-wifi3,-64,412900000,275300000,539264,491728,00:06:48,00:00:00
1788527184,15:06:24,15:06:24,8,229720,340576,cap-wifi3,-64,412900000,275300000,539264,491728,00:06:50,00:00:00
1788527186,15:06:26,15:06:26,11,324680,63616,cap-wifi3,-63,412900000,344100000,768576,455936,00:06:52,00:00:00
1788527188,15:06:28,15:06:28,7,323944,57120,cap-wifi3,-67,344100000,309700000,515712,335688,00:06:54,00:00:00
1788527190,15:06:30,15:06:30,7,89536,26840,cap-wifi3,-67,344100000,309700000,515712,335688,00:06:56,00:00:00
1788527192,15:06:32,15:06:32,6,88056,17368,cap-wifi3,-62,344100000,344100000,546008,422232,00:06:58,00:00:00
1788527194,15:06:34,15:06:34,6,78232,15688,cap-wifi3,-62,412900000,344100000,403184,296104,00:07:00,00:00:00
1788527196,15:06:36,15:06:36,6,77824,19488,cap-wifi3,-62,412900000,344100000,403184,296104,00:07:02,00:00:00
1788527198,15:06:38,15:06:38,8,91648,29960,cap-wifi3,-62,412900000,344100000,665616,416832,00:07:04,00:00:00
1788527200,15:06:40,15:06:40,6,479584,403096,cap-wifi3,-63,344100000,275300000,1141120,678936,00:07:06,00:00:00
1788527202,15:06:42,15:06:42,5,83504,18032,cap-wifi3,-63,344100000,275300000,1141120,678936,00:07:08,00:00:00
1788527204,15:06:44,15:06:44,12,94312,27480,cap-wifi3,-64,344100000,344100000,511368,235632,00:07:10,00:00:00
1788527206,15:06:46,15:06:46,11,104592,25288,cap-wifi3,-65,412900000,309700000,882160,555064,00:07:12,00:00:00
1788527208,15:06:48,15:06:48,9,77672,15824,cap-wifi3,-65,344100000,275300000,71864,300800,00:07:14,00:00:00
1788527210,15:06:50,15:06:50,8,130536,65520,cap-wifi3,-65,344100000,275300000,71864,300800,00:07:16,00:00:00
1788527212,15:06:52,15:06:52,6,179704,71320,cap-wifi3,-65,309700000,344100000,612752,430056,00:07:19,00:00:00
1788527214,15:06:54,15:06:54,7,150376,135320,cap-wifi3,-64,309700000,309700000,556768,426072,00:07:21,00:00:00
1788527216,15:06:56,15:06:57,7,180576,117008,cap-wifi3,-64,309700000,309700000,556768,426072,00:07:23,00:00:00
1788527219,15:06:59,15:06:59,9,81080,17128,cap-wifi3,-65,344100000,412900000,687448,312096,00:07:25,00:00:00
1788527221,15:07:01,15:07:01,6,267072,71760,cap-wifi3,-64,412900000,309700000,1456168,436368,00:07:27,00:00:00
1788527223,15:07:03,15:07:03,7,229720,79648,cap-wifi3,-64,412900000,309700000,1456168,436368,00:07:29,00:00:00
1788527225,15:07:05,15:07:05,12,613656,242376,cap-wifi3,-65,412900000,344100000,643504,429016,00:07:31,00:00:00
1788527227,15:07:07,15:07:07,9,136256,40080,cap-wifi3,-64,412900000,344100000,619904,419664,00:07:33,00:00:00
1788527229,15:07:09,15:07:09,11,113040,49536,cap-wifi3,-64,412900000,344100000,619904,419664,00:07:35,00:00:00
1788527231,15:07:11,15:07:11,7,85432,17976,cap-wifi3,-64,412900000,309700000,1090376,738848,00:07:37,00:00:00
1788527233,15:07:13,15:07:13,5,81944,26128,cap-wifi3,-65,412900000,344100000,947112,611480,00:07:39,00:00:00
1788527235,15:07:15,15:07:15,5,954264,397144,cap-wifi3,-65,412900000,344100000,947112,611480,00:07:41,00:00:00
1788527237,15:07:17,15:07:17,12,3430312,274976,cap-wifi3,-64,412900000,344100000,1132848,732040,00:07:43,00:00:00
1788527239,15:07:19,15:07:19,21,5774264,240088,cap-wifi3,-63,412900000,344100000,886256,615784,00:07:45,00:00:00
1788527241,15:07:21,15:07:21,7,419688,124632,cap-wifi3,-63,412900000,344100000,886256,615784,00:07:47,00:00:00
1788527243,15:07:23,15:07:23,6,146872,47152,cap-wifi3,-64,412900000,344100000,588616,494568,00:07:49,00:00:00
1788527245,15:07:25,15:07:25,6,469520,144920,cap-wifi3,-62,412900000,344100000,576512,462856,00:07:51,00:00:00
1788527247,15:07:27,15:07:27,8,87480,21512,cap-wifi3,-62,412900000,344100000,576512,462856,00:07:53,00:00:00
1788527249,15:07:29,15:07:29,20,89592,20496,cap-wifi3,-63,455800000,344100000,256840,24640,00:07:55,00:00:00
1788527251,15:07:31,15:07:31,9,77304,18144,cap-wifi3,-63,455800000,309700000,883728,710608,00:07:57,00:00:00
1788527253,15:07:33,15:07:33,7,84240,17432,cap-wifi3,-63,455800000,309700000,883728,710608,00:07:59,00:00:00
1788527255,15:07:35,15:07:35,9,74928,18888,cap-wifi3,-62,455800000,412900000,33632,15216,00:08:01,00:00:00
1788527257,15:07:37,15:07:37,12,79856,17376,cap-wifi3,-63,455800000,412900000,859640,23024,00:08:03,00:00:00
1788527259,15:07:39,15:07:39,19,91680,31720,cap-wifi3,-62,455800000,412900000,1005448,689888,00:08:06,00:00:00
1788527261,15:07:41,15:07:41,7,82760,21192,cap-wifi3,-62,455800000,412900000,1005448,689888,00:08:08,00:00:00
1788527263,15:07:43,15:07:44,6,91960,31680,cap-wifi3,-63,516200000,412900000,393768,296624,00:08:10,00:00:00
1788527266,15:07:46,15:07:46,12,986832,256184,cap-wifi3,-63,516200000,412900000,558880,414936,00:08:12,00:00:00
1788527268,15:07:48,15:07:48,8,204344,305984,cap-wifi3,-63,516200000,412900000,558880,414936,00:08:14,00:00:00
1788527270,15:07:50,15:07:50,21,90376,25984,cap-wifi3,-63,455800000,344100000,423096,346496,00:08:16,00:00:00
1788527272,15:07:52,15:07:52,9,106024,28632,cap-wifi3,-63,455800000,412900000,549712,433200,00:08:18,00:00:00
1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-63,455800000,412900000,549712,433200,00:08:20,00:00:00
1788527276,15:07:56,15:07:56,8,68568,17040,cap-wifi3,-63,455800000,344100000,391568,303576,00:08:22,00:00:00
1788527278,15:07:58,15:07:58,7,104792,53200,cap-wifi3,-62,455800000,344100000,715856,336320,00:08:24,00:00:00
1788527280,15:08:00,15:08:00,17,304368,102592,cap-wifi3,-62,455800000,344100000,715856,336320,00:08:26,00:00:00
1788527282,15:08:02,15:08:02,10,74432,14824,cap-wifi3,-62,455800000,344100000,1540504,579064,00:08:28,00:00:00
1788527284,15:08:04,15:08:04,15,84656,54904,cap-wifi3,-62,455800000,412900000,241664,55784,00:08:30,00:00:00
1788527286,15:08:06,15:08:06,3,157752,48776,cap-wifi3,-62,455800000,412900000,241664,55784,00:08:32,00:00:00
1788527288,15:08:08,15:08:08,6,93880,28544,cap-wifi3,-61,455800000,344100000,662200,323008,00:08:34,00:00:00
1788527290,15:08:10,15:08:10,5,92704,21680,cap-wifi3,-62,455800000,412900000,1547016,993208,00:08:36,00:00:00
1788527292,15:08:12,15:08:12,4,1096952,456376,cap-wifi3,-62,455800000,412900000,1547016,993208,00:08:38,00:00:00
1788527294,15:08:14,15:08:14,5,96296,34168,cap-wifi3,-62,455800000,412900000,658464,380200,00:08:40,00:00:00
1788527296,15:08:16,15:08:16,4,323536,108008,cap-wifi3,-62,516200000,412900000,1653400,1083248,00:08:42,00:00:00
1788527298,15:08:18,15:08:18,5,106776,31872,cap-wifi3,-62,516200000,412900000,1653400,1083248,00:08:44,00:00:00
1788527300,15:08:20,15:08:20,5,180440,70648,cap-wifi3,-62,516200000,412900000,601784,323352,00:08:46,00:00:00
1788527302,15:08:22,15:08:22,5,258520,122376,cap-wifi3,-63,516200000,344100000,1414784,982048,00:08:48,00:00:00
1788527304,15:08:24,15:08:24,8,484544,159104,cap-wifi3,-63,516200000,344100000,1414784,982048,00:08:50,00:00:00
1788527306,15:08:26,15:08:26,5,85832,21400,cap-wifi3,-62,516200000,412900000,594728,332184,00:08:52,00:00:00
1788527308,15:08:28,15:08:28,7,86968,23984,cap-wifi3,-62,455800000,412900000,1676496,1014016,00:08:54,00:00:00
1788527310,15:08:30,15:08:30,4,92848,27216,cap-wifi3,-62,455800000,412900000,1676496,1014016,00:08:57,00:00:00
1788527312,15:08:32,15:08:32,13,88112,30272,cap-wifi3,-61,455800000,412900000,862336,707464,00:08:59,00:00:00
1788527314,15:08:34,15:08:35,6,97568,38688,cap-wifi3,-62,455800000,412900000,802192,493640,00:09:01,00:00:00
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-63,455800000,412900000,410264,299608,00:09:03,00:00:00
1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-63,455800000,412900000,410264,299608,00:09:05,00:00:00
1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-62,516200000,412900000,1058008,922664,00:09:07,00:00:00
1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-62,516200000,412900000,396520,170800,00:09:09,00:00:00
1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-62,516200000,412900000,396520,170800,00:09:11,00:00:00
1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-62,516200000,455800000,899408,689584,00:09:13,00:00:00
1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-62,516200000,412900000,44600,15184,00:09:15,00:00:00
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-62,516200000,412900000,44600,15184,00:09:17,00:00:00
1788527333,15:08:53,15:08:53,4,78784,16504,cap-wifi3,-62,516200000,344100000,903552,691192,00:09:19,00:00:00
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-64,412900000,309700000,69328,39008,00:09:21,00:00:00
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-64,412900000,309700000,69328,39008,00:09:23,00:00:00
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-63,344100000,309700000,1149696,710336,00:09:25,00:00:00
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-62,412900000,344100000,2232624,903848,00:09:27,00:00:00
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-62,412900000,344100000,2232624,903848,00:09:29,00:00:00
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-61,344100000,412900000,756464,448360,00:09:31,00:00:00
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-63,344100000,344100000,1392608,910264,00:09:33,00:00:00
1788527349,15:09:09,15:09:09,19,213416,92736,cap-wifi3,-63,344100000,344100000,1392608,910264,00:09:35,00:00:00
1788527351,15:09:11,15:09:11,6,319104,63216,cap-wifi3,-62,412900000,309700000,1209392,477456,00:09:37,00:00:00
1788527353,15:09:13,15:09:13,8,153896,48144,cap-wifi3,-62,412900000,344100000,1506680,898696,00:09:39,00:00:00
1788527355,15:09:15,15:09:15,5,190952,58360,cap-wifi3,-62,412900000,344100000,1506680,898696,00:09:41,00:00:00
1788527357,15:09:17,15:09:17,7,232928,149512,cap-wifi3,-64,412900000,344100000,1033704,613072,00:09:44,00:00:00
1788527359,15:09:19,15:09:19,19,108000,26560,cap-wifi3,-64,309700000,344100000,1108648,735944,00:09:46,00:00:00
1788527361,15:09:21,15:09:22,10,2754208,213840,cap-wifi3,-64,309700000,344100000,1108648,735944,00:09:48,00:00:00
1788527363,15:09:23,15:09:24,7,314040,73608,cap-wifi3,-63,344100000,275300000,981328,613912,00:09:50,00:00:00
1788527366,15:09:26,15:09:26,5,485488,100744,cap-wifi3,-58,309700000,309700000,1262008,690008,00:09:52,00:00:00
1788527368,15:09:28,15:09:28,6,123816,28072,cap-wifi3,-58,309700000,309700000,1262008,690008,00:09:54,00:00:00
1788527370,15:09:30,15:09:30,19,124944,35616,cap-wifi3,-63,309700000,206500000,260104,31680,00:09:56,00:00:00
1788527372,15:09:32,15:09:32,5,171352,44496,cap-wifi3,-61,344100000,309700000,1238528,574776,00:09:58,00:00:00
1788527374,15:09:34,15:09:34,6,166240,43784,cap-wifi3,-64,344100000,344100000,531000,227904,00:10:00,00:00:00
1788527376,15:09:36,15:09:36,6,150760,49464,cap-wifi3,-64,344100000,344100000,531000,227904,00:10:02,00:00:00
1788527378,15:09:38,15:09:38,10,185768,47120,cap-wifi3,-64,344100000,309700000,929200,634112,00:10:04,00:00:00
1788527380,15:09:40,15:09:40,18,190032,49512,cap-wifi3,-64,344100000,309700000,666528,183736,00:10:06,00:00:00
1788527382,15:09:42,15:09:42,8,97808,22304,cap-wifi3,-64,344100000,309700000,666528,183736,00:10:08,00:00:00
1788527384,15:09:44,15:09:44,8,148400,53672,cap-wifi3,-63,412900000,344100000,981232,603784,00:10:10,00:00:00
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-62,412900000,309700000,225464,141192,00:10:12,00:00:00
1788527388,15:09:48,15:09:48,4,76456,19280,cap-wifi3,-62,412900000,309700000,225464,141192,00:10:14,00:00:00
1788527390,15:09:50,15:09:50,17,74488,14496,cap-wifi3,-63,344100000,275300000,731840,568104,00:10:16,00:00:00
1788527392,15:09:52,15:09:52,9,81688,114120,cap-wifi3,-64,412900000,309700000,217144,287216,00:10:18,00:00:00
1788527394,15:09:54,15:09:54,11,139472,94312,cap-wifi3,-64,412900000,309700000,217144,287216,00:10:20,00:00:00
1788527396,15:09:56,15:09:56,8,99376,34800,cap-wifi3,-63,412900000,344100000,522856,417128,00:10:22,00:00:00
1788527398,15:09:58,15:09:58,7,95624,20936,cap-wifi3,-64,412900000,344100000,1177520,673088,00:10:24,00:00:00
1788527400,15:10:00,15:10:00,11,75688,17080,cap-wifi3,-64,412900000,344100000,1177520,673088,00:10:26,00:00:00
1788527402,15:10:02,15:10:02,8,194448,59984,cap-wifi3,-62,412900000,412900000,1678424,596296,00:10:28,00:00:00
1788527404,15:10:04,15:10:04,5,87848,23392,cap-wifi3,-62,412900000,412900000,1099136,718696,00:10:30,00:00:00
1788527406,15:10:06,15:10:06,4,102440,31824,cap-wifi3,-62,412900000,412900000,1099136,718696,00:10:32,00:00:00
1788527408,15:10:08,15:10:08,7,140352,49312,cap-wifi3,-65,412900000,309700000,944912,595928,00:10:34,00:00:00
1788527410,15:10:10,15:10:10,20,81216,18128,cap-wifi3,-64,455800000,344100000,1466688,782256,00:10:36,00:00:00
1788527412,15:10:12,15:10:12,8,223088,23248,cap-wifi3,-64,455800000,344100000,1466688,782256,00:10:38,00:00:00
1788527414,15:10:14,15:10:14,7,139784,51840,cap-wifi3,-63,412900000,344100000,1572056,878688,00:10:40,00:00:00
1788527415,15:10:15,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788527155 15:05:55 15:05:55 26 215104 164208 cap-wifi3 -59 344100000 455800000 1108432 1179376 00:06:21 00:00:00
3 1788527157 15:05:57 15:05:57 10 230144 103104 cap-wifi3 -58 412900000 455800000 376304 298808 00:06:23 00:00:00
4 1788527159 15:05:59 15:05:59 27 997352 175928 cap-wifi3 -58 412900000 455800000 376304 298808 00:06:25 00:00:00
5 1788527161 15:06:01 15:06:01 5 496624 179032 cap-wifi3 -60 455800000 455800000 2283840 1594024 00:06:27 00:00:00
6 1788527163 15:06:03 15:06:03 7 112272 25664 cap-wifi3 -61 455800000 344100000 71224 20160 00:06:30 00:00:00
7 1788527165 15:06:05 15:06:06 6 353280 101384 cap-wifi3 -61 455800000 344100000 71224 20160 00:06:32 00:00:00
8 1788527167 15:06:08 15:06:08 6 137256 37360 cap-wifi3 -63 344100000 344100000 1205496 674488 00:06:34 00:00:00
9 1788527170 15:06:10 15:06:10 18 373144 1851168 cap-wifi3 -62 344100000 455800000 625632 2151904 00:06:36 00:00:00
10 1788527172 15:06:12 15:06:12 2 79504 15688 cap-wifi3 -62 344100000 455800000 625632 2151904 00:06:38 00:00:00
11 1788527174 15:06:14 15:06:14 6 215576 3512448 cap-wifi3 -61 412900000 412900000 720568 420128 00:06:40 00:00:00
12 1788527176 15:06:16 15:06:16 4 170440 37144 cap-wifi3 -63 344100000 309700000 1040816 801272 00:06:42 00:00:00
13 1788527178 15:06:18 15:06:18 7 187488 1860720 cap-wifi3 -63 344100000 309700000 1040816 801272 00:06:44 00:00:00
14 1788527180 15:06:20 15:06:20 21 418584 3563696 cap-wifi3 -63 412900000 275300000 496424 2170904 00:06:46 00:00:00
15 1788527182 15:06:22 15:06:22 6 91920 32648 cap-wifi3 -64 412900000 275300000 539264 491728 00:06:48 00:00:00
16 1788527184 15:06:24 15:06:24 8 229720 340576 cap-wifi3 -64 412900000 275300000 539264 491728 00:06:50 00:00:00
17 1788527186 15:06:26 15:06:26 11 324680 63616 cap-wifi3 -63 412900000 344100000 768576 455936 00:06:52 00:00:00
18 1788527188 15:06:28 15:06:28 7 323944 57120 cap-wifi3 -67 344100000 309700000 515712 335688 00:06:54 00:00:00
19 1788527190 15:06:30 15:06:30 7 89536 26840 cap-wifi3 -67 344100000 309700000 515712 335688 00:06:56 00:00:00
20 1788527192 15:06:32 15:06:32 6 88056 17368 cap-wifi3 -62 344100000 344100000 546008 422232 00:06:58 00:00:00
21 1788527194 15:06:34 15:06:34 6 78232 15688 cap-wifi3 -62 412900000 344100000 403184 296104 00:07:00 00:00:00
22 1788527196 15:06:36 15:06:36 6 77824 19488 cap-wifi3 -62 412900000 344100000 403184 296104 00:07:02 00:00:00
23 1788527198 15:06:38 15:06:38 8 91648 29960 cap-wifi3 -62 412900000 344100000 665616 416832 00:07:04 00:00:00
24 1788527200 15:06:40 15:06:40 6 479584 403096 cap-wifi3 -63 344100000 275300000 1141120 678936 00:07:06 00:00:00
25 1788527202 15:06:42 15:06:42 5 83504 18032 cap-wifi3 -63 344100000 275300000 1141120 678936 00:07:08 00:00:00
26 1788527204 15:06:44 15:06:44 12 94312 27480 cap-wifi3 -64 344100000 344100000 511368 235632 00:07:10 00:00:00
27 1788527206 15:06:46 15:06:46 11 104592 25288 cap-wifi3 -65 412900000 309700000 882160 555064 00:07:12 00:00:00
28 1788527208 15:06:48 15:06:48 9 77672 15824 cap-wifi3 -65 344100000 275300000 71864 300800 00:07:14 00:00:00
29 1788527210 15:06:50 15:06:50 8 130536 65520 cap-wifi3 -65 344100000 275300000 71864 300800 00:07:16 00:00:00
30 1788527212 15:06:52 15:06:52 6 179704 71320 cap-wifi3 -65 309700000 344100000 612752 430056 00:07:19 00:00:00
31 1788527214 15:06:54 15:06:54 7 150376 135320 cap-wifi3 -64 309700000 309700000 556768 426072 00:07:21 00:00:00
32 1788527216 15:06:56 15:06:57 7 180576 117008 cap-wifi3 -64 309700000 309700000 556768 426072 00:07:23 00:00:00
33 1788527219 15:06:59 15:06:59 9 81080 17128 cap-wifi3 -65 344100000 412900000 687448 312096 00:07:25 00:00:00
34 1788527221 15:07:01 15:07:01 6 267072 71760 cap-wifi3 -64 412900000 309700000 1456168 436368 00:07:27 00:00:00
35 1788527223 15:07:03 15:07:03 7 229720 79648 cap-wifi3 -64 412900000 309700000 1456168 436368 00:07:29 00:00:00
36 1788527225 15:07:05 15:07:05 12 613656 242376 cap-wifi3 -65 412900000 344100000 643504 429016 00:07:31 00:00:00
37 1788527227 15:07:07 15:07:07 9 136256 40080 cap-wifi3 -64 412900000 344100000 619904 419664 00:07:33 00:00:00
38 1788527229 15:07:09 15:07:09 11 113040 49536 cap-wifi3 -64 412900000 344100000 619904 419664 00:07:35 00:00:00
39 1788527231 15:07:11 15:07:11 7 85432 17976 cap-wifi3 -64 412900000 309700000 1090376 738848 00:07:37 00:00:00
40 1788527233 15:07:13 15:07:13 5 81944 26128 cap-wifi3 -65 412900000 344100000 947112 611480 00:07:39 00:00:00
41 1788527235 15:07:15 15:07:15 5 954264 397144 cap-wifi3 -65 412900000 344100000 947112 611480 00:07:41 00:00:00
42 1788527237 15:07:17 15:07:17 12 3430312 274976 cap-wifi3 -64 412900000 344100000 1132848 732040 00:07:43 00:00:00
43 1788527239 15:07:19 15:07:19 21 5774264 240088 cap-wifi3 -63 412900000 344100000 886256 615784 00:07:45 00:00:00
44 1788527241 15:07:21 15:07:21 7 419688 124632 cap-wifi3 -63 412900000 344100000 886256 615784 00:07:47 00:00:00
45 1788527243 15:07:23 15:07:23 6 146872 47152 cap-wifi3 -64 412900000 344100000 588616 494568 00:07:49 00:00:00
46 1788527245 15:07:25 15:07:25 6 469520 144920 cap-wifi3 -62 412900000 344100000 576512 462856 00:07:51 00:00:00
47 1788527247 15:07:27 15:07:27 8 87480 21512 cap-wifi3 -62 412900000 344100000 576512 462856 00:07:53 00:00:00
48 1788527249 15:07:29 15:07:29 20 89592 20496 cap-wifi3 -63 455800000 344100000 256840 24640 00:07:55 00:00:00
49 1788527251 15:07:31 15:07:31 9 77304 18144 cap-wifi3 -63 455800000 309700000 883728 710608 00:07:57 00:00:00
50 1788527253 15:07:33 15:07:33 7 84240 17432 cap-wifi3 -63 455800000 309700000 883728 710608 00:07:59 00:00:00
51 1788527255 15:07:35 15:07:35 9 74928 18888 cap-wifi3 -62 455800000 412900000 33632 15216 00:08:01 00:00:00
52 1788527257 15:07:37 15:07:37 12 79856 17376 cap-wifi3 -63 455800000 412900000 859640 23024 00:08:03 00:00:00
53 1788527259 15:07:39 15:07:39 19 91680 31720 cap-wifi3 -62 455800000 412900000 1005448 689888 00:08:06 00:00:00
54 1788527261 15:07:41 15:07:41 7 82760 21192 cap-wifi3 -62 455800000 412900000 1005448 689888 00:08:08 00:00:00
55 1788527263 15:07:43 15:07:44 6 91960 31680 cap-wifi3 -63 516200000 412900000 393768 296624 00:08:10 00:00:00
56 1788527266 15:07:46 15:07:46 12 986832 256184 cap-wifi3 -63 516200000 412900000 558880 414936 00:08:12 00:00:00
57 1788527268 15:07:48 15:07:48 8 204344 305984 cap-wifi3 -63 516200000 412900000 558880 414936 00:08:14 00:00:00
58 1788527270 15:07:50 15:07:50 21 90376 25984 cap-wifi3 -63 455800000 344100000 423096 346496 00:08:16 00:00:00
59 1788527272 15:07:52 15:07:52 9 106024 28632 cap-wifi3 -63 455800000 412900000 549712 433200 00:08:18 00:00:00
60 1788527274 15:07:54 15:07:54 8 86752 24568 cap-wifi3 -63 455800000 412900000 549712 433200 00:08:20 00:00:00
61 1788527276 15:07:56 15:07:56 8 68568 17040 cap-wifi3 -63 455800000 344100000 391568 303576 00:08:22 00:00:00
62 1788527278 15:07:58 15:07:58 7 104792 53200 cap-wifi3 -62 455800000 344100000 715856 336320 00:08:24 00:00:00
63 1788527280 15:08:00 15:08:00 17 304368 102592 cap-wifi3 -62 455800000 344100000 715856 336320 00:08:26 00:00:00
64 1788527282 15:08:02 15:08:02 10 74432 14824 cap-wifi3 -62 455800000 344100000 1540504 579064 00:08:28 00:00:00
65 1788527284 15:08:04 15:08:04 15 84656 54904 cap-wifi3 -62 455800000 412900000 241664 55784 00:08:30 00:00:00
66 1788527286 15:08:06 15:08:06 3 157752 48776 cap-wifi3 -62 455800000 412900000 241664 55784 00:08:32 00:00:00
67 1788527288 15:08:08 15:08:08 6 93880 28544 cap-wifi3 -61 455800000 344100000 662200 323008 00:08:34 00:00:00
68 1788527290 15:08:10 15:08:10 5 92704 21680 cap-wifi3 -62 455800000 412900000 1547016 993208 00:08:36 00:00:00
69 1788527292 15:08:12 15:08:12 4 1096952 456376 cap-wifi3 -62 455800000 412900000 1547016 993208 00:08:38 00:00:00
70 1788527294 15:08:14 15:08:14 5 96296 34168 cap-wifi3 -62 455800000 412900000 658464 380200 00:08:40 00:00:00
71 1788527296 15:08:16 15:08:16 4 323536 108008 cap-wifi3 -62 516200000 412900000 1653400 1083248 00:08:42 00:00:00
72 1788527298 15:08:18 15:08:18 5 106776 31872 cap-wifi3 -62 516200000 412900000 1653400 1083248 00:08:44 00:00:00
73 1788527300 15:08:20 15:08:20 5 180440 70648 cap-wifi3 -62 516200000 412900000 601784 323352 00:08:46 00:00:00
74 1788527302 15:08:22 15:08:22 5 258520 122376 cap-wifi3 -63 516200000 344100000 1414784 982048 00:08:48 00:00:00
75 1788527304 15:08:24 15:08:24 8 484544 159104 cap-wifi3 -63 516200000 344100000 1414784 982048 00:08:50 00:00:00
76 1788527306 15:08:26 15:08:26 5 85832 21400 cap-wifi3 -62 516200000 412900000 594728 332184 00:08:52 00:00:00
77 1788527308 15:08:28 15:08:28 7 86968 23984 cap-wifi3 -62 455800000 412900000 1676496 1014016 00:08:54 00:00:00
78 1788527310 15:08:30 15:08:30 4 92848 27216 cap-wifi3 -62 455800000 412900000 1676496 1014016 00:08:57 00:00:00
79 1788527312 15:08:32 15:08:32 13 88112 30272 cap-wifi3 -61 455800000 412900000 862336 707464 00:08:59 00:00:00
80 1788527314 15:08:34 15:08:35 6 97568 38688 cap-wifi3 -62 455800000 412900000 802192 493640 00:09:01 00:00:00
81 1788527317 15:08:37 15:08:37 7 69376 15424 cap-wifi3 -63 455800000 412900000 410264 299608 00:09:03 00:00:00
82 1788527319 15:08:39 15:08:39 7 95672 27872 cap-wifi3 -63 455800000 412900000 410264 299608 00:09:05 00:00:00
83 1788527321 15:08:41 15:08:41 8 81008 14064 cap-wifi3 -62 516200000 412900000 1058008 922664 00:09:07 00:00:00
84 1788527323 15:08:43 15:08:43 8 79480 19824 cap-wifi3 -62 516200000 412900000 396520 170800 00:09:09 00:00:00
85 1788527325 15:08:45 15:08:45 6 83080 28888 cap-wifi3 -62 516200000 412900000 396520 170800 00:09:11 00:00:00
86 1788527327 15:08:47 15:08:47 9 77224 19568 cap-wifi3 -62 516200000 455800000 899408 689584 00:09:13 00:00:00
87 1788527329 15:08:49 15:08:49 7 87976 23544 cap-wifi3 -62 516200000 412900000 44600 15184 00:09:15 00:00:00
88 1788527331 15:08:51 15:08:51 6 99288 43960 cap-wifi3 -62 516200000 412900000 44600 15184 00:09:17 00:00:00
89 1788527333 15:08:53 15:08:53 4 78784 16504 cap-wifi3 -62 516200000 344100000 903552 691192 00:09:19 00:00:00
90 1788527335 15:08:55 15:08:55 8 100664 43024 cap-wifi3 -64 412900000 309700000 69328 39008 00:09:21 00:00:00
91 1788527337 15:08:57 15:08:57 6 75392 68792 cap-wifi3 -64 412900000 309700000 69328 39008 00:09:23 00:00:00
92 1788527339 15:08:59 15:08:59 18 84648 23296 cap-wifi3 -63 344100000 309700000 1149696 710336 00:09:25 00:00:00
93 1788527341 15:09:01 15:09:01 5 146608 49608 cap-wifi3 -62 412900000 344100000 2232624 903848 00:09:27 00:00:00
94 1788527343 15:09:03 15:09:03 6 271512 52760 cap-wifi3 -62 412900000 344100000 2232624 903848 00:09:29 00:00:00
95 1788527345 15:09:05 15:09:05 6 400696 3660640 cap-wifi3 -61 344100000 412900000 756464 448360 00:09:31 00:00:00
96 1788527347 15:09:07 15:09:07 6 131696 25096 cap-wifi3 -63 344100000 344100000 1392608 910264 00:09:33 00:00:00
97 1788527349 15:09:09 15:09:09 19 213416 92736 cap-wifi3 -63 344100000 344100000 1392608 910264 00:09:35 00:00:00
98 1788527351 15:09:11 15:09:11 6 319104 63216 cap-wifi3 -62 412900000 309700000 1209392 477456 00:09:37 00:00:00
99 1788527353 15:09:13 15:09:13 8 153896 48144 cap-wifi3 -62 412900000 344100000 1506680 898696 00:09:39 00:00:00
100 1788527355 15:09:15 15:09:15 5 190952 58360 cap-wifi3 -62 412900000 344100000 1506680 898696 00:09:41 00:00:00
101 1788527357 15:09:17 15:09:17 7 232928 149512 cap-wifi3 -64 412900000 344100000 1033704 613072 00:09:44 00:00:00
102 1788527359 15:09:19 15:09:19 19 108000 26560 cap-wifi3 -64 309700000 344100000 1108648 735944 00:09:46 00:00:00
103 1788527361 15:09:21 15:09:22 10 2754208 213840 cap-wifi3 -64 309700000 344100000 1108648 735944 00:09:48 00:00:00
104 1788527363 15:09:23 15:09:24 7 314040 73608 cap-wifi3 -63 344100000 275300000 981328 613912 00:09:50 00:00:00
105 1788527366 15:09:26 15:09:26 5 485488 100744 cap-wifi3 -58 309700000 309700000 1262008 690008 00:09:52 00:00:00
106 1788527368 15:09:28 15:09:28 6 123816 28072 cap-wifi3 -58 309700000 309700000 1262008 690008 00:09:54 00:00:00
107 1788527370 15:09:30 15:09:30 19 124944 35616 cap-wifi3 -63 309700000 206500000 260104 31680 00:09:56 00:00:00
108 1788527372 15:09:32 15:09:32 5 171352 44496 cap-wifi3 -61 344100000 309700000 1238528 574776 00:09:58 00:00:00
109 1788527374 15:09:34 15:09:34 6 166240 43784 cap-wifi3 -64 344100000 344100000 531000 227904 00:10:00 00:00:00
110 1788527376 15:09:36 15:09:36 6 150760 49464 cap-wifi3 -64 344100000 344100000 531000 227904 00:10:02 00:00:00
111 1788527378 15:09:38 15:09:38 10 185768 47120 cap-wifi3 -64 344100000 309700000 929200 634112 00:10:04 00:00:00
112 1788527380 15:09:40 15:09:40 18 190032 49512 cap-wifi3 -64 344100000 309700000 666528 183736 00:10:06 00:00:00
113 1788527382 15:09:42 15:09:42 8 97808 22304 cap-wifi3 -64 344100000 309700000 666528 183736 00:10:08 00:00:00
114 1788527384 15:09:44 15:09:44 8 148400 53672 cap-wifi3 -63 412900000 344100000 981232 603784 00:10:10 00:00:00
115 1788527386 15:09:46 15:09:46 2 97568 37160 cap-wifi3 -62 412900000 309700000 225464 141192 00:10:12 00:00:00
116 1788527388 15:09:48 15:09:48 4 76456 19280 cap-wifi3 -62 412900000 309700000 225464 141192 00:10:14 00:00:00
117 1788527390 15:09:50 15:09:50 17 74488 14496 cap-wifi3 -63 344100000 275300000 731840 568104 00:10:16 00:00:00
118 1788527392 15:09:52 15:09:52 9 81688 114120 cap-wifi3 -64 412900000 309700000 217144 287216 00:10:18 00:00:00
119 1788527394 15:09:54 15:09:54 11 139472 94312 cap-wifi3 -64 412900000 309700000 217144 287216 00:10:20 00:00:00
120 1788527396 15:09:56 15:09:56 8 99376 34800 cap-wifi3 -63 412900000 344100000 522856 417128 00:10:22 00:00:00
121 1788527398 15:09:58 15:09:58 7 95624 20936 cap-wifi3 -64 412900000 344100000 1177520 673088 00:10:24 00:00:00
122 1788527400 15:10:00 15:10:00 11 75688 17080 cap-wifi3 -64 412900000 344100000 1177520 673088 00:10:26 00:00:00
123 1788527402 15:10:02 15:10:02 8 194448 59984 cap-wifi3 -62 412900000 412900000 1678424 596296 00:10:28 00:00:00
124 1788527404 15:10:04 15:10:04 5 87848 23392 cap-wifi3 -62 412900000 412900000 1099136 718696 00:10:30 00:00:00
125 1788527406 15:10:06 15:10:06 4 102440 31824 cap-wifi3 -62 412900000 412900000 1099136 718696 00:10:32 00:00:00
126 1788527408 15:10:08 15:10:08 7 140352 49312 cap-wifi3 -65 412900000 309700000 944912 595928 00:10:34 00:00:00
127 1788527410 15:10:10 15:10:10 20 81216 18128 cap-wifi3 -64 455800000 344100000 1466688 782256 00:10:36 00:00:00
128 1788527412 15:10:12 15:10:12 8 223088 23248 cap-wifi3 -64 455800000 344100000 1466688 782256 00:10:38 00:00:00
129 1788527414 15:10:14 15:10:14 7 139784 51840 cap-wifi3 -63 412900000 344100000 1572056 878688 00:10:40 00:00:00
130 1788527415 15:10:15 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-macbook.csv (Takt 2s, Client 56:71:6C:22:E6:A9)

View File

@@ -0,0 +1,2 @@
14:58:12 Verbindung weg -- neuer Versuch in 2 s
15:10:15 Verbindung weg -- neuer Versuch in 2 s

View File

@@ -0,0 +1,130 @@
ts_epoch,ts_local,ros_time,cpu,wan_rx_bps,wan_tx_bps,sta_iface,sta_signal,sta_tx_rate,sta_rx_rate,sta_tx_bps,sta_rx_bps,sta_uptime,sta_last_activity
1788527155,15:05:55,15:05:55,26,215104,164208,cap-wifi3,-50,6000000,6000000,0,0,00:00:50,00:00:18.020
1788527157,15:05:57,15:05:57,10,230144,103104,cap-wifi3,-49,309700000,344100000,63424,67648,00:00:52,00:00:00
1788527159,15:05:59,15:05:59,27,997352,175928,cap-wifi3,-49,309700000,344100000,63424,67648,00:00:55,00:00:00
1788527161,15:06:01,15:06:01,5,496624,179032,cap-wifi3,-49,309700000,344100000,2800,2960,00:00:57,00:00:00
1788527163,15:06:03,15:06:03,7,112272,25664,cap-wifi3,-49,309700000,344100000,2800,2960,00:00:59,00:00:00
1788527165,15:06:05,15:06:06,6,353280,101384,cap-wifi3,-49,309700000,344100000,2800,2960,00:01:01,00:00:00
1788527168,15:06:08,15:06:08,6,137256,37360,cap-wifi3,-53,309700000,344100000,5472,4672,00:01:03,00:00:00
1788527170,15:06:10,15:06:10,18,373144,1851168,cap-wifi3,-61,275300000,206500000,2800,2960,00:01:05,00:00:00
1788527172,15:06:12,15:06:12,2,79504,15688,cap-wifi3,-61,275300000,206500000,2800,2960,00:01:07,00:00:00
1788527174,15:06:14,15:06:14,6,215576,3512448,cap-wifi3,-56,154900000,258100000,3592,4872,00:01:09,00:00:00
1788527176,15:06:16,15:06:16,4,170440,37144,cap-wifi3,-51,24000000,229400000,2800,10960,00:01:11,00:00:00
1788527178,15:06:18,15:06:18,7,187488,1860720,cap-wifi3,-51,24000000,229400000,2800,10960,00:01:13,00:00:00
1788527180,15:06:20,15:06:20,21,418584,3563696,cap-wifi3,-52,275300000,258100000,2800,2960,00:01:15,00:00:00
1788527182,15:06:22,15:06:22,6,91920,32648,cap-wifi3,-51,275300000,286800000,2800,10960,00:01:17,00:00:00
1788527184,15:06:24,15:06:24,8,229720,340576,cap-wifi3,-51,275300000,286800000,2800,10960,00:01:19,00:00:00
1788527186,15:06:26,15:06:26,11,324680,63616,cap-wifi3,-52,275300000,286800000,4184,4376,00:01:21,00:00:00
1788527188,15:06:28,15:06:28,7,323944,57120,cap-wifi3,-50,275300000,309700000,3360,3552,00:01:23,00:00:00
1788527190,15:06:30,15:06:30,7,89536,26840,cap-wifi3,-50,275300000,309700000,3360,3552,00:01:25,00:00:00
1788527192,15:06:32,15:06:32,6,88056,17368,cap-wifi3,-50,275300000,344100000,5344,8864,00:01:27,00:00:00
1788527194,15:06:34,15:06:34,6,78232,15688,cap-wifi3,-52,275300000,309700000,3248,3328,00:01:29,00:00:00
1788527196,15:06:36,15:06:36,6,77824,19488,cap-wifi3,-52,275300000,309700000,3248,3328,00:01:31,00:00:00
1788527198,15:06:38,15:06:38,8,91648,29960,cap-wifi3,-58,275300000,344100000,2800,2960,00:01:33,00:00:00
1788527200,15:06:40,15:06:40,6,479584,403096,cap-wifi3,-51,275300000,229400000,2800,2960,00:01:35,00:00:00
1788527202,15:06:42,15:06:42,5,83504,18032,cap-wifi3,-51,275300000,229400000,2800,2960,00:01:37,00:00:00
1788527204,15:06:44,15:06:44,12,94312,27480,cap-wifi3,-54,275300000,258100000,2800,2960,00:01:39,00:00:00
1788527206,15:06:46,15:06:46,11,104592,25288,cap-wifi3,-53,275300000,286800000,2800,10960,00:01:41,00:00:00
1788527208,15:06:48,15:06:48,9,77672,15824,cap-wifi3,-52,24000000,286800000,2800,2960,00:01:43,00:00:00
1788527210,15:06:50,15:06:50,8,130536,65520,cap-wifi3,-52,24000000,286800000,2800,2960,00:01:46,00:00:00
1788527212,15:06:52,15:06:52,6,179704,71320,cap-wifi3,-53,6000000,286800000,3360,3552,00:01:48,00:00:00
1788527214,15:06:54,15:06:54,7,150376,135320,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:50,00:00:00
1788527216,15:06:56,15:06:57,7,180576,117008,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:52,00:00:00
1788527219,15:06:59,15:06:59,9,81080,17128,cap-wifi3,-52,275300000,309700000,2800,2960,00:01:54,00:00:00
1788527221,15:07:01,15:07:01,6,267072,71760,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:56,00:00:00
1788527223,15:07:03,15:07:03,7,229720,79648,cap-wifi3,-51,275300000,309700000,2800,2960,00:01:58,00:00:00
1788527225,15:07:05,15:07:05,12,613656,242376,cap-wifi3,-53,275300000,344100000,2800,2960,00:02:00,00:00:00
1788527227,15:07:07,15:07:07,9,136256,40080,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:02,00:00:00
1788527229,15:07:09,15:07:09,11,113040,49536,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:04,00:00:00
1788527231,15:07:11,15:07:11,7,85432,17976,cap-wifi3,-53,275300000,309700000,2800,2960,00:02:06,00:00:00
1788527233,15:07:13,15:07:13,5,81944,26128,cap-wifi3,-56,275300000,286800000,2800,3552,00:02:08,00:00:00
1788527235,15:07:15,15:07:15,5,954264,397144,cap-wifi3,-56,275300000,286800000,2800,3552,00:02:10,00:00:00
1788527237,15:07:17,15:07:17,12,3430312,274976,cap-wifi3,-50,275300000,344100000,11168,29128,00:02:12,00:00:00
1788527239,15:07:19,15:07:19,21,5774264,240088,cap-wifi3,-50,275300000,344100000,3360,3552,00:02:14,00:00:00
1788527241,15:07:21,15:07:21,7,419688,124632,cap-wifi3,-50,275300000,344100000,3360,3552,00:02:16,00:00:00
1788527243,15:07:23,15:07:23,6,146872,47152,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:18,00:00:00
1788527245,15:07:25,15:07:25,6,469520,144920,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:20,00:00:00
1788527247,15:07:27,15:07:27,8,87480,21512,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:22,00:00:00
1788527249,15:07:29,15:07:29,20,89592,20496,cap-wifi3,-50,275300000,344100000,3360,3552,00:02:24,00:00:00
1788527251,15:07:31,15:07:31,9,77304,18144,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:26,00:00:00
1788527253,15:07:33,15:07:33,7,84240,17432,cap-wifi3,-50,275300000,344100000,2800,2960,00:02:28,00:00:00
1788527255,15:07:35,15:07:35,9,74928,18888,cap-wifi3,-51,275300000,344100000,2240,2368,00:02:30,00:00:00
1788527257,15:07:37,15:07:37,12,79856,17376,cap-wifi3,-51,275300000,344100000,2800,2960,00:02:33,00:00:00
1788527259,15:07:39,15:07:39,19,91680,31720,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:35,00:00:00
1788527261,15:07:41,15:07:41,7,82760,21192,cap-wifi3,-52,275300000,344100000,3808,3920,00:02:37,00:00:00
1788527263,15:07:43,15:07:44,6,91960,31680,cap-wifi3,-51,309700000,344100000,4912,4080,00:02:39,00:00:00
1788527266,15:07:46,15:07:46,12,986832,256184,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:41,00:00:00
1788527268,15:07:48,15:07:48,8,204344,305984,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:43,00:00:00
1788527270,15:07:50,15:07:50,21,90376,25984,cap-wifi3,-50,309700000,412900000,2800,2960,00:02:45,00:00:00
1788527272,15:07:52,15:07:52,9,106024,28632,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:47,00:00:00
1788527274,15:07:54,15:07:54,8,86752,24568,cap-wifi3,-51,309700000,344100000,3360,3552,00:02:49,00:00:00
1788527276,15:07:56,15:07:56,8,68568,17040,cap-wifi3,-51,309700000,412900000,2800,2960,00:02:51,00:00:00
1788527278,15:07:58,15:07:58,7,104792,53200,cap-wifi3,-48,206500000,344100000,3360,3552,00:02:53,00:00:00
1788527280,15:08:00,15:08:00,17,304368,102592,cap-wifi3,-48,206500000,344100000,3360,3552,00:02:55,00:00:00
1788527282,15:08:02,15:08:02,10,74432,14824,cap-wifi3,-49,206500000,344100000,2800,2960,00:02:57,00:00:00
1788527284,15:08:04,15:08:04,15,84656,54904,cap-wifi3,-48,206500000,344100000,2800,2960,00:02:59,00:00:00
1788527286,15:08:06,15:08:06,3,157752,48776,cap-wifi3,-48,206500000,344100000,2800,2960,00:03:01,00:00:00
1788527288,15:08:08,15:08:08,6,93880,28544,cap-wifi3,-48,206500000,344100000,3360,3552,00:03:03,00:00:00
1788527290,15:08:10,15:08:10,5,92704,21680,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:05,00:00:00
1788527292,15:08:12,15:08:12,4,1096952,456376,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:07,00:00:00
1788527294,15:08:14,15:08:14,5,96296,34168,cap-wifi3,-48,206500000,344100000,2800,2960,00:03:09,00:00:00
1788527296,15:08:16,15:08:16,4,323536,108008,cap-wifi3,-48,206500000,344100000,4184,4376,00:03:11,00:00:00
1788527298,15:08:18,15:08:18,5,106776,31872,cap-wifi3,-48,206500000,344100000,4184,4376,00:03:13,00:00:00
1788527300,15:08:20,15:08:20,5,180440,70648,cap-wifi3,-49,206500000,344100000,3360,3552,00:03:15,00:00:00
1788527302,15:08:22,15:08:22,5,258520,122376,cap-wifi3,-49,206500000,344100000,2800,10960,00:03:17,00:00:00
1788527304,15:08:24,15:08:24,8,484544,159104,cap-wifi3,-49,206500000,344100000,2800,10960,00:03:19,00:00:00
1788527306,15:08:26,15:08:26,5,85832,21400,cap-wifi3,-48,206500000,344100000,3360,2960,00:03:21,00:00:00
1788527308,15:08:28,15:08:28,7,86968,23984,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:24,00:00:00
1788527310,15:08:30,15:08:30,4,92848,27216,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:26,00:00:00
1788527312,15:08:32,15:08:32,13,88112,30272,cap-wifi3,-49,206500000,344100000,3360,3552,00:03:28,00:00:00
1788527314,15:08:34,15:08:35,6,97568,38688,cap-wifi3,-50,206500000,344100000,2800,2960,00:03:30,00:00:00
1788527317,15:08:37,15:08:37,7,69376,15424,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:32,00:00:00
1788527319,15:08:39,15:08:39,7,95672,27872,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:34,00:00:00
1788527321,15:08:41,15:08:41,8,81008,14064,cap-wifi3,-49,206500000,344100000,3360,3552,00:03:36,00:00:00
1788527323,15:08:43,15:08:43,8,79480,19824,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:38,00:00:00
1788527325,15:08:45,15:08:45,6,83080,28888,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:40,00:00:00
1788527327,15:08:47,15:08:47,9,77224,19568,cap-wifi3,-49,206500000,309700000,3360,3552,00:03:42,00:00:00
1788527329,15:08:49,15:08:49,7,87976,23544,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:44,00:00:00
1788527331,15:08:51,15:08:51,6,99288,43960,cap-wifi3,-49,206500000,344100000,2800,2960,00:03:46,00:00:00
1788527333,15:08:53,15:08:53,7,78784,16504,cap-wifi3,-45,206500000,309700000,2800,2960,00:03:48,00:00:00
1788527335,15:08:55,15:08:55,8,100664,43024,cap-wifi3,-60,206500000,309700000,2800,2960,00:03:50,00:00:00
1788527337,15:08:57,15:08:57,6,75392,68792,cap-wifi3,-60,206500000,309700000,2800,2960,00:03:52,00:00:00
1788527339,15:08:59,15:08:59,18,84648,23296,cap-wifi3,-58,206500000,309700000,2800,2960,00:03:54,00:00:00
1788527341,15:09:01,15:09:01,5,146608,49608,cap-wifi3,-54,6000000,6000000,3360,3552,00:03:56,00:00:00
1788527343,15:09:03,15:09:03,6,271512,52760,cap-wifi3,-54,6000000,6000000,3360,3552,00:03:58,00:00:00
1788527345,15:09:05,15:09:05,6,400696,3660640,cap-wifi3,-56,275300000,344100000,2800,2960,00:04:00,00:00:00
1788527347,15:09:07,15:09:07,6,131696,25096,cap-wifi3,-54,275300000,344100000,3360,3552,00:04:02,00:00:00
1788527349,15:09:09,15:09:09,19,174312,46976,cap-wifi3,-54,275300000,344100000,3360,3552,00:04:04,00:00:00
1788527351,15:09:11,15:09:11,6,359504,63184,cap-wifi3,-54,275300000,309700000,2800,2960,00:04:06,00:00:00
1788527353,15:09:13,15:09:13,8,181920,63704,cap-wifi3,-58,24000000,344100000,2800,4896,00:04:08,00:00:00
1788527355,15:09:15,15:09:15,5,306368,67704,cap-wifi3,-58,24000000,344100000,2800,4896,00:04:10,00:00:00
1788527357,15:09:17,15:09:17,7,306688,60896,cap-wifi3,-57,275300000,309700000,3656,3520,00:04:12,00:00:00
1788527359,15:09:19,15:09:19,19,310240,63104,cap-wifi3,-57,154900000,309700000,4384,6048,00:04:14,00:00:00
1788527361,15:09:21,15:09:21,10,228704,92160,cap-wifi3,-57,154900000,309700000,4384,6048,00:04:16,00:00:00
1788527363,15:09:23,15:09:23,7,292296,160184,cap-wifi3,-61,154900000,309700000,10568,37976,00:04:18,00:00:00
1788527365,15:09:25,15:09:25,5,695128,395648,cap-wifi3,-56,154900000,309700000,3360,3552,00:04:20,00:00:00
1788527367,15:09:27,15:09:27,6,123816,28072,cap-wifi3,-56,154900000,309700000,3360,3552,00:04:22,00:00:00
1788527369,15:09:29,15:09:29,19,124944,35616,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:24,00:00:00
1788527371,15:09:31,15:09:31,5,171352,44496,cap-wifi3,-57,154900000,275300000,4040,6584,00:04:26,00:00:00
1788527373,15:09:33,15:09:33,6,166240,43784,cap-wifi3,-57,154900000,275300000,4040,6584,00:04:28,00:00:00
1788527375,15:09:35,15:09:35,6,150760,49464,cap-wifi3,-56,154900000,309700000,2800,2960,00:04:31,00:00:00
1788527377,15:09:37,15:09:37,10,185768,47120,cap-wifi3,-57,24000000,309700000,2800,2960,00:04:33,00:00:00
1788527379,15:09:39,15:09:39,18,190032,49512,cap-wifi3,-57,24000000,309700000,2800,2960,00:04:35,00:00:00
1788527381,15:09:41,15:09:41,8,97808,22304,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:37,00:00:00
1788527383,15:09:43,15:09:43,8,148400,53672,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:39,00:00:00
1788527386,15:09:46,15:09:46,2,97568,37160,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:41,00:00:00
1788527387,15:09:47,15:09:48,4,76456,19280,cap-wifi3,-57,154900000,309700000,2800,3552,00:04:43,00:00:00
1788527389,15:09:49,15:09:50,17,74488,14496,cap-wifi3,-58,6000000,309700000,2800,2960,00:04:45,00:00:00
1788527392,15:09:52,15:09:52,4,81688,114120,cap-wifi3,-58,6000000,309700000,2800,2960,00:04:47,00:00:00
1788527394,15:09:54,15:09:54,8,139472,94312,cap-wifi3,-57,154900000,309700000,2800,2960,00:04:49,00:00:00
1788527396,15:09:56,15:09:56,4,99376,34800,cap-wifi3,-57,154900000,309700000,2800,2960,00:04:51,00:00:00
1788527398,15:09:58,15:09:58,5,95624,20936,cap-wifi3,-57,154900000,309700000,2800,2960,00:04:53,00:00:00
1788527400,15:10:00,15:10:00,19,75688,17080,cap-wifi3,-57,154900000,344100000,2800,2960,00:04:55,00:00:00
1788527402,15:10:02,15:10:02,12,194448,59984,cap-wifi3,-56,154900000,344100000,2800,2960,00:04:57,00:00:00
1788527404,15:10:04,15:10:04,10,87848,23392,cap-wifi3,-58,154900000,344100000,2800,2960,00:04:59,00:00:00
1788527406,15:10:06,15:10:06,9,102440,31824,cap-wifi3,-58,154900000,344100000,2800,2960,00:05:01,00:00:00
1788527408,15:10:08,15:10:08,8,140352,49312,cap-wifi3,-56,154900000,309700000,2800,2960,00:05:03,00:00:00
1788527410,15:10:10,15:10:10,25,88352,30376,cap-wifi3,-56,154900000,309700000,2800,2960,00:05:05,00:00:00
1788527412,15:10:12,15:10:12,7,124328,46808,cap-wifi3,-56,154900000,309700000,2800,2960,00:05:07,00:00:00
1788527414,15:10:14,15:10:14,8,84784,23040,cap-wifi3,-57,154900000,344100000,2800,2960,00:05:09,00:00:00
1788527415,15:10:15,RECONNECT
1 ts_epoch ts_local ros_time cpu wan_rx_bps wan_tx_bps sta_iface sta_signal sta_tx_rate sta_rx_rate sta_tx_bps sta_rx_bps sta_uptime sta_last_activity
2 1788527155 15:05:55 15:05:55 26 215104 164208 cap-wifi3 -50 6000000 6000000 0 0 00:00:50 00:00:18.020
3 1788527157 15:05:57 15:05:57 10 230144 103104 cap-wifi3 -49 309700000 344100000 63424 67648 00:00:52 00:00:00
4 1788527159 15:05:59 15:05:59 27 997352 175928 cap-wifi3 -49 309700000 344100000 63424 67648 00:00:55 00:00:00
5 1788527161 15:06:01 15:06:01 5 496624 179032 cap-wifi3 -49 309700000 344100000 2800 2960 00:00:57 00:00:00
6 1788527163 15:06:03 15:06:03 7 112272 25664 cap-wifi3 -49 309700000 344100000 2800 2960 00:00:59 00:00:00
7 1788527165 15:06:05 15:06:06 6 353280 101384 cap-wifi3 -49 309700000 344100000 2800 2960 00:01:01 00:00:00
8 1788527168 15:06:08 15:06:08 6 137256 37360 cap-wifi3 -53 309700000 344100000 5472 4672 00:01:03 00:00:00
9 1788527170 15:06:10 15:06:10 18 373144 1851168 cap-wifi3 -61 275300000 206500000 2800 2960 00:01:05 00:00:00
10 1788527172 15:06:12 15:06:12 2 79504 15688 cap-wifi3 -61 275300000 206500000 2800 2960 00:01:07 00:00:00
11 1788527174 15:06:14 15:06:14 6 215576 3512448 cap-wifi3 -56 154900000 258100000 3592 4872 00:01:09 00:00:00
12 1788527176 15:06:16 15:06:16 4 170440 37144 cap-wifi3 -51 24000000 229400000 2800 10960 00:01:11 00:00:00
13 1788527178 15:06:18 15:06:18 7 187488 1860720 cap-wifi3 -51 24000000 229400000 2800 10960 00:01:13 00:00:00
14 1788527180 15:06:20 15:06:20 21 418584 3563696 cap-wifi3 -52 275300000 258100000 2800 2960 00:01:15 00:00:00
15 1788527182 15:06:22 15:06:22 6 91920 32648 cap-wifi3 -51 275300000 286800000 2800 10960 00:01:17 00:00:00
16 1788527184 15:06:24 15:06:24 8 229720 340576 cap-wifi3 -51 275300000 286800000 2800 10960 00:01:19 00:00:00
17 1788527186 15:06:26 15:06:26 11 324680 63616 cap-wifi3 -52 275300000 286800000 4184 4376 00:01:21 00:00:00
18 1788527188 15:06:28 15:06:28 7 323944 57120 cap-wifi3 -50 275300000 309700000 3360 3552 00:01:23 00:00:00
19 1788527190 15:06:30 15:06:30 7 89536 26840 cap-wifi3 -50 275300000 309700000 3360 3552 00:01:25 00:00:00
20 1788527192 15:06:32 15:06:32 6 88056 17368 cap-wifi3 -50 275300000 344100000 5344 8864 00:01:27 00:00:00
21 1788527194 15:06:34 15:06:34 6 78232 15688 cap-wifi3 -52 275300000 309700000 3248 3328 00:01:29 00:00:00
22 1788527196 15:06:36 15:06:36 6 77824 19488 cap-wifi3 -52 275300000 309700000 3248 3328 00:01:31 00:00:00
23 1788527198 15:06:38 15:06:38 8 91648 29960 cap-wifi3 -58 275300000 344100000 2800 2960 00:01:33 00:00:00
24 1788527200 15:06:40 15:06:40 6 479584 403096 cap-wifi3 -51 275300000 229400000 2800 2960 00:01:35 00:00:00
25 1788527202 15:06:42 15:06:42 5 83504 18032 cap-wifi3 -51 275300000 229400000 2800 2960 00:01:37 00:00:00
26 1788527204 15:06:44 15:06:44 12 94312 27480 cap-wifi3 -54 275300000 258100000 2800 2960 00:01:39 00:00:00
27 1788527206 15:06:46 15:06:46 11 104592 25288 cap-wifi3 -53 275300000 286800000 2800 10960 00:01:41 00:00:00
28 1788527208 15:06:48 15:06:48 9 77672 15824 cap-wifi3 -52 24000000 286800000 2800 2960 00:01:43 00:00:00
29 1788527210 15:06:50 15:06:50 8 130536 65520 cap-wifi3 -52 24000000 286800000 2800 2960 00:01:46 00:00:00
30 1788527212 15:06:52 15:06:52 6 179704 71320 cap-wifi3 -53 6000000 286800000 3360 3552 00:01:48 00:00:00
31 1788527214 15:06:54 15:06:54 7 150376 135320 cap-wifi3 -51 275300000 309700000 2800 2960 00:01:50 00:00:00
32 1788527216 15:06:56 15:06:57 7 180576 117008 cap-wifi3 -51 275300000 309700000 2800 2960 00:01:52 00:00:00
33 1788527219 15:06:59 15:06:59 9 81080 17128 cap-wifi3 -52 275300000 309700000 2800 2960 00:01:54 00:00:00
34 1788527221 15:07:01 15:07:01 6 267072 71760 cap-wifi3 -51 275300000 309700000 2800 2960 00:01:56 00:00:00
35 1788527223 15:07:03 15:07:03 7 229720 79648 cap-wifi3 -51 275300000 309700000 2800 2960 00:01:58 00:00:00
36 1788527225 15:07:05 15:07:05 12 613656 242376 cap-wifi3 -53 275300000 344100000 2800 2960 00:02:00 00:00:00
37 1788527227 15:07:07 15:07:07 9 136256 40080 cap-wifi3 -52 275300000 344100000 3808 3920 00:02:02 00:00:00
38 1788527229 15:07:09 15:07:09 11 113040 49536 cap-wifi3 -52 275300000 344100000 3808 3920 00:02:04 00:00:00
39 1788527231 15:07:11 15:07:11 7 85432 17976 cap-wifi3 -53 275300000 309700000 2800 2960 00:02:06 00:00:00
40 1788527233 15:07:13 15:07:13 5 81944 26128 cap-wifi3 -56 275300000 286800000 2800 3552 00:02:08 00:00:00
41 1788527235 15:07:15 15:07:15 5 954264 397144 cap-wifi3 -56 275300000 286800000 2800 3552 00:02:10 00:00:00
42 1788527237 15:07:17 15:07:17 12 3430312 274976 cap-wifi3 -50 275300000 344100000 11168 29128 00:02:12 00:00:00
43 1788527239 15:07:19 15:07:19 21 5774264 240088 cap-wifi3 -50 275300000 344100000 3360 3552 00:02:14 00:00:00
44 1788527241 15:07:21 15:07:21 7 419688 124632 cap-wifi3 -50 275300000 344100000 3360 3552 00:02:16 00:00:00
45 1788527243 15:07:23 15:07:23 6 146872 47152 cap-wifi3 -50 275300000 344100000 2800 2960 00:02:18 00:00:00
46 1788527245 15:07:25 15:07:25 6 469520 144920 cap-wifi3 -50 275300000 344100000 2800 2960 00:02:20 00:00:00
47 1788527247 15:07:27 15:07:27 8 87480 21512 cap-wifi3 -50 275300000 344100000 2800 2960 00:02:22 00:00:00
48 1788527249 15:07:29 15:07:29 20 89592 20496 cap-wifi3 -50 275300000 344100000 3360 3552 00:02:24 00:00:00
49 1788527251 15:07:31 15:07:31 9 77304 18144 cap-wifi3 -50 275300000 344100000 2800 2960 00:02:26 00:00:00
50 1788527253 15:07:33 15:07:33 7 84240 17432 cap-wifi3 -50 275300000 344100000 2800 2960 00:02:28 00:00:00
51 1788527255 15:07:35 15:07:35 9 74928 18888 cap-wifi3 -51 275300000 344100000 2240 2368 00:02:30 00:00:00
52 1788527257 15:07:37 15:07:37 12 79856 17376 cap-wifi3 -51 275300000 344100000 2800 2960 00:02:33 00:00:00
53 1788527259 15:07:39 15:07:39 19 91680 31720 cap-wifi3 -52 275300000 344100000 3808 3920 00:02:35 00:00:00
54 1788527261 15:07:41 15:07:41 7 82760 21192 cap-wifi3 -52 275300000 344100000 3808 3920 00:02:37 00:00:00
55 1788527263 15:07:43 15:07:44 6 91960 31680 cap-wifi3 -51 309700000 344100000 4912 4080 00:02:39 00:00:00
56 1788527266 15:07:46 15:07:46 12 986832 256184 cap-wifi3 -51 309700000 344100000 3360 3552 00:02:41 00:00:00
57 1788527268 15:07:48 15:07:48 8 204344 305984 cap-wifi3 -51 309700000 344100000 3360 3552 00:02:43 00:00:00
58 1788527270 15:07:50 15:07:50 21 90376 25984 cap-wifi3 -50 309700000 412900000 2800 2960 00:02:45 00:00:00
59 1788527272 15:07:52 15:07:52 9 106024 28632 cap-wifi3 -51 309700000 344100000 3360 3552 00:02:47 00:00:00
60 1788527274 15:07:54 15:07:54 8 86752 24568 cap-wifi3 -51 309700000 344100000 3360 3552 00:02:49 00:00:00
61 1788527276 15:07:56 15:07:56 8 68568 17040 cap-wifi3 -51 309700000 412900000 2800 2960 00:02:51 00:00:00
62 1788527278 15:07:58 15:07:58 7 104792 53200 cap-wifi3 -48 206500000 344100000 3360 3552 00:02:53 00:00:00
63 1788527280 15:08:00 15:08:00 17 304368 102592 cap-wifi3 -48 206500000 344100000 3360 3552 00:02:55 00:00:00
64 1788527282 15:08:02 15:08:02 10 74432 14824 cap-wifi3 -49 206500000 344100000 2800 2960 00:02:57 00:00:00
65 1788527284 15:08:04 15:08:04 15 84656 54904 cap-wifi3 -48 206500000 344100000 2800 2960 00:02:59 00:00:00
66 1788527286 15:08:06 15:08:06 3 157752 48776 cap-wifi3 -48 206500000 344100000 2800 2960 00:03:01 00:00:00
67 1788527288 15:08:08 15:08:08 6 93880 28544 cap-wifi3 -48 206500000 344100000 3360 3552 00:03:03 00:00:00
68 1788527290 15:08:10 15:08:10 5 92704 21680 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:05 00:00:00
69 1788527292 15:08:12 15:08:12 4 1096952 456376 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:07 00:00:00
70 1788527294 15:08:14 15:08:14 5 96296 34168 cap-wifi3 -48 206500000 344100000 2800 2960 00:03:09 00:00:00
71 1788527296 15:08:16 15:08:16 4 323536 108008 cap-wifi3 -48 206500000 344100000 4184 4376 00:03:11 00:00:00
72 1788527298 15:08:18 15:08:18 5 106776 31872 cap-wifi3 -48 206500000 344100000 4184 4376 00:03:13 00:00:00
73 1788527300 15:08:20 15:08:20 5 180440 70648 cap-wifi3 -49 206500000 344100000 3360 3552 00:03:15 00:00:00
74 1788527302 15:08:22 15:08:22 5 258520 122376 cap-wifi3 -49 206500000 344100000 2800 10960 00:03:17 00:00:00
75 1788527304 15:08:24 15:08:24 8 484544 159104 cap-wifi3 -49 206500000 344100000 2800 10960 00:03:19 00:00:00
76 1788527306 15:08:26 15:08:26 5 85832 21400 cap-wifi3 -48 206500000 344100000 3360 2960 00:03:21 00:00:00
77 1788527308 15:08:28 15:08:28 7 86968 23984 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:24 00:00:00
78 1788527310 15:08:30 15:08:30 4 92848 27216 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:26 00:00:00
79 1788527312 15:08:32 15:08:32 13 88112 30272 cap-wifi3 -49 206500000 344100000 3360 3552 00:03:28 00:00:00
80 1788527314 15:08:34 15:08:35 6 97568 38688 cap-wifi3 -50 206500000 344100000 2800 2960 00:03:30 00:00:00
81 1788527317 15:08:37 15:08:37 7 69376 15424 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:32 00:00:00
82 1788527319 15:08:39 15:08:39 7 95672 27872 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:34 00:00:00
83 1788527321 15:08:41 15:08:41 8 81008 14064 cap-wifi3 -49 206500000 344100000 3360 3552 00:03:36 00:00:00
84 1788527323 15:08:43 15:08:43 8 79480 19824 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:38 00:00:00
85 1788527325 15:08:45 15:08:45 6 83080 28888 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:40 00:00:00
86 1788527327 15:08:47 15:08:47 9 77224 19568 cap-wifi3 -49 206500000 309700000 3360 3552 00:03:42 00:00:00
87 1788527329 15:08:49 15:08:49 7 87976 23544 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:44 00:00:00
88 1788527331 15:08:51 15:08:51 6 99288 43960 cap-wifi3 -49 206500000 344100000 2800 2960 00:03:46 00:00:00
89 1788527333 15:08:53 15:08:53 7 78784 16504 cap-wifi3 -45 206500000 309700000 2800 2960 00:03:48 00:00:00
90 1788527335 15:08:55 15:08:55 8 100664 43024 cap-wifi3 -60 206500000 309700000 2800 2960 00:03:50 00:00:00
91 1788527337 15:08:57 15:08:57 6 75392 68792 cap-wifi3 -60 206500000 309700000 2800 2960 00:03:52 00:00:00
92 1788527339 15:08:59 15:08:59 18 84648 23296 cap-wifi3 -58 206500000 309700000 2800 2960 00:03:54 00:00:00
93 1788527341 15:09:01 15:09:01 5 146608 49608 cap-wifi3 -54 6000000 6000000 3360 3552 00:03:56 00:00:00
94 1788527343 15:09:03 15:09:03 6 271512 52760 cap-wifi3 -54 6000000 6000000 3360 3552 00:03:58 00:00:00
95 1788527345 15:09:05 15:09:05 6 400696 3660640 cap-wifi3 -56 275300000 344100000 2800 2960 00:04:00 00:00:00
96 1788527347 15:09:07 15:09:07 6 131696 25096 cap-wifi3 -54 275300000 344100000 3360 3552 00:04:02 00:00:00
97 1788527349 15:09:09 15:09:09 19 174312 46976 cap-wifi3 -54 275300000 344100000 3360 3552 00:04:04 00:00:00
98 1788527351 15:09:11 15:09:11 6 359504 63184 cap-wifi3 -54 275300000 309700000 2800 2960 00:04:06 00:00:00
99 1788527353 15:09:13 15:09:13 8 181920 63704 cap-wifi3 -58 24000000 344100000 2800 4896 00:04:08 00:00:00
100 1788527355 15:09:15 15:09:15 5 306368 67704 cap-wifi3 -58 24000000 344100000 2800 4896 00:04:10 00:00:00
101 1788527357 15:09:17 15:09:17 7 306688 60896 cap-wifi3 -57 275300000 309700000 3656 3520 00:04:12 00:00:00
102 1788527359 15:09:19 15:09:19 19 310240 63104 cap-wifi3 -57 154900000 309700000 4384 6048 00:04:14 00:00:00
103 1788527361 15:09:21 15:09:21 10 228704 92160 cap-wifi3 -57 154900000 309700000 4384 6048 00:04:16 00:00:00
104 1788527363 15:09:23 15:09:23 7 292296 160184 cap-wifi3 -61 154900000 309700000 10568 37976 00:04:18 00:00:00
105 1788527365 15:09:25 15:09:25 5 695128 395648 cap-wifi3 -56 154900000 309700000 3360 3552 00:04:20 00:00:00
106 1788527367 15:09:27 15:09:27 6 123816 28072 cap-wifi3 -56 154900000 309700000 3360 3552 00:04:22 00:00:00
107 1788527369 15:09:29 15:09:29 19 124944 35616 cap-wifi3 -57 154900000 344100000 2800 2960 00:04:24 00:00:00
108 1788527371 15:09:31 15:09:31 5 171352 44496 cap-wifi3 -57 154900000 275300000 4040 6584 00:04:26 00:00:00
109 1788527373 15:09:33 15:09:33 6 166240 43784 cap-wifi3 -57 154900000 275300000 4040 6584 00:04:28 00:00:00
110 1788527375 15:09:35 15:09:35 6 150760 49464 cap-wifi3 -56 154900000 309700000 2800 2960 00:04:31 00:00:00
111 1788527377 15:09:37 15:09:37 10 185768 47120 cap-wifi3 -57 24000000 309700000 2800 2960 00:04:33 00:00:00
112 1788527379 15:09:39 15:09:39 18 190032 49512 cap-wifi3 -57 24000000 309700000 2800 2960 00:04:35 00:00:00
113 1788527381 15:09:41 15:09:41 8 97808 22304 cap-wifi3 -57 154900000 344100000 2800 2960 00:04:37 00:00:00
114 1788527383 15:09:43 15:09:43 8 148400 53672 cap-wifi3 -57 154900000 344100000 2800 2960 00:04:39 00:00:00
115 1788527386 15:09:46 15:09:46 2 97568 37160 cap-wifi3 -57 154900000 344100000 2800 2960 00:04:41 00:00:00
116 1788527387 15:09:47 15:09:48 4 76456 19280 cap-wifi3 -57 154900000 309700000 2800 3552 00:04:43 00:00:00
117 1788527389 15:09:49 15:09:50 17 74488 14496 cap-wifi3 -58 6000000 309700000 2800 2960 00:04:45 00:00:00
118 1788527392 15:09:52 15:09:52 4 81688 114120 cap-wifi3 -58 6000000 309700000 2800 2960 00:04:47 00:00:00
119 1788527394 15:09:54 15:09:54 8 139472 94312 cap-wifi3 -57 154900000 309700000 2800 2960 00:04:49 00:00:00
120 1788527396 15:09:56 15:09:56 4 99376 34800 cap-wifi3 -57 154900000 309700000 2800 2960 00:04:51 00:00:00
121 1788527398 15:09:58 15:09:58 5 95624 20936 cap-wifi3 -57 154900000 309700000 2800 2960 00:04:53 00:00:00
122 1788527400 15:10:00 15:10:00 19 75688 17080 cap-wifi3 -57 154900000 344100000 2800 2960 00:04:55 00:00:00
123 1788527402 15:10:02 15:10:02 12 194448 59984 cap-wifi3 -56 154900000 344100000 2800 2960 00:04:57 00:00:00
124 1788527404 15:10:04 15:10:04 10 87848 23392 cap-wifi3 -58 154900000 344100000 2800 2960 00:04:59 00:00:00
125 1788527406 15:10:06 15:10:06 9 102440 31824 cap-wifi3 -58 154900000 344100000 2800 2960 00:05:01 00:00:00
126 1788527408 15:10:08 15:10:08 8 140352 49312 cap-wifi3 -56 154900000 309700000 2800 2960 00:05:03 00:00:00
127 1788527410 15:10:10 15:10:10 25 88352 30376 cap-wifi3 -56 154900000 309700000 2800 2960 00:05:05 00:00:00
128 1788527412 15:10:12 15:10:12 7 124328 46808 cap-wifi3 -56 154900000 309700000 2800 2960 00:05:07 00:00:00
129 1788527414 15:10:14 15:10:14 8 84784 23040 cap-wifi3 -57 154900000 344100000 2800 2960 00:05:09 00:00:00
130 1788527415 15:10:15 RECONNECT

View File

@@ -0,0 +1 @@
Sampler laeuft -> /Users/christophemsenhuber/dev/bf-infra/docs/messdaten/tp25-runde-dauerping/sampler-s22.csv (Takt 2s, Client 2A:0D:B0:5D:AD:A7)

View File

@@ -0,0 +1,2 @@
14:58:12 Verbindung weg -- neuer Versuch in 2 s
15:10:15 Verbindung weg -- neuer Versuch in 2 s

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -63,6 +63,11 @@ teuerste Eigenschaft der Datei zerstört, um ihr billigstes Problem zu lösen. B
| [TP28](#tp28) | WLAN über CAPsMAN auf `crs326-core` | ↩️ **wieder geöffnet 2026-08-30** (ap3) — Volltext in [teilprojekte.md](teilprojekte.md#tp28) |
| [TP-R](#tp-r) | Router-Capabilities-Sweep | FERTIG (docs/research/routeros-capabilities.md) |
| [TP39](#tp39) | LXC-Hygiene pve: Resolver-Altlasten, `networking.service`, DB-Reverse-Lookup | ✅ ABGESCHLOSSEN (2026-09-01) — pve+NAS-Sweep grün |
| [TP34](#tp34) | Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) | ❌ VERWORFEN (2026-09-08) — Caddyfile bleibt manuell |
| [TP44](#tp44) | Cloudflare-Estate als Dokumentations-SSoT in Nautobot | ✅ DURCH (2026-09-10) |
| [TP41](#tp41) | CF-Access-Reparatur + Zero-Trust-Konsolidierung | ✅ ABGESCHLOSSEN (2026-09-10) — Gelis WARP via Android eingerichtet, letzter Blocker weg |
| [TP43](#tp43) | dw-Standort-DNS-Uplink (site-spezifische Overrides) | ♻️ REOPENED (2026-09-11) — Volltext zurück in teilprojekte.md; interne BF-Namen über WG am dw offen |
| [TP42](#tp42) | Namens-Vereinheitlichung: ein interner Suffix bf.emsenhuber.net | ✅ DURCH (2026-09-02) — `.bf.lan` raus, `.16` abgebaut, Compliance 140/140 |
Dazu am Ende: **[TP25 (Langfassung)](#tp25-lang)** — die Messchronik und die Funde A–E im Volltext.
TP25 selbst ist **nicht** abgeschlossen und steht weiter in `teilprojekte.md`; nur seine 394 Zeilen
@@ -1777,3 +1782,198 @@ gemessen hat. Beim Beheben kam eine zweite, unabhängige Altlast zum Vorschein.
- **Nicht** TP31/TP34 (Caddy) und nicht TP11 (Monitoring) — obwohl gilt: ein Monitoring, das
DB-Verbindungszeiten kennt, hätte diesen Fall Monate früher gezeigt.
- **Nicht** TP40: der HA-Recorder-Wildwuchs (Punkt 3) ist HA-seitig und ein eigenes TP.
---
### TP34 — Caddyfile via Nautobot/GC (generische Reverse-Proxy-Schnittstelle) ▸ ❌ **VERWORFEN (2026-09-08)**
> 🔴 **Nachtrag 2026-09-08 (verworfen):** Der Ansatz „Caddyfile via Golden Config rendern" ist
> zurückgezogen (Commits `d63dc7b`, `bca8f6e`; Gitea-Issue #24 → `status:dropped`, closed). Der
> `420.teilzeitladen.xyz`-Block wurde wieder aus dem GC-gerenderten Caddyfile entfernt; **der
> Caddyfile bleibt manuell** in `caddy/Caddyfile`. Gründe: kein zweites SSoT-Modell für Proxy-Routen
> nötig, TP37 deckt die Dienst-Doku als `ipam.Service` bereits ab, und der einzige akute Anwendungsfall
> ließ sich mit einem manuellen Block lösen. Text unten unverändert als Konzept-Historie.
> **Konzept + Architektur-Skizze:** [`docs/handoff-20260827-inventur-und-architektur.md`](handoff-20260827-inventur-und-architektur.md) — bitte dort weiterlesen (Architektur-Abschnitt).
- **Scope:** Reverse-Proxy-Hosts werden im **Nautobot-Datenmodell** gepflegt (Site, Host, Backend-Spec). **Golden Config** rendert den Caddyfile aus den Daten, Diff-Check gegen die Live-Version auf `caddy-bf1`, Compliance-Checks + Transaktionen identisch zum bestehenden Workflow für Router-Configs.
- **Auslöser (Inventur 2026-08-27):** der Caddyfile (`bf-infra/caddy/Caddyfile`) ist heute **manuell gepflegt** — kein Drift-Check, keine Transaktionen, andere Projekte können keine Sites anlegen ohne Christoph. Lösung: **Nautobot/GC**, kein Caddy-API-Sidecar (kein zweites SSoT).
- **Erster Anwendungsfall:** `terpene.teilzeitladen.xyz → http://10.40.20.167:8890` (Mac-mini-Backend, dort PostgREST + sync + web via lokalem Caddy `:8890`). Vor TP34: manueller Quick-Win-Caddy-Block.
- **Abh.:** TP22 (GC-Pipeline) ✅ · TP23 (DNS/Caddy-Voraussetzungen) ✅ Stufe 1 · 🔴 **NEU 2026-09-06: TP37 Punkt 1+2** — Caddy rendert *Config aus Daten*, die Backend-Dienste müssen als `ipam.Service` in Nautobot existieren, sonst gibt es nichts zu rendern. **TP37 vor TP34.**
- **Datenmodell (entschieden 2026-09-06):** native Modelle — Backend = `ipam.Service`, Proxy-Route = Relationship/CustomField Frontend↔Backend, GC-Job rendert den Caddyfile. Keine eigene App (konsistent zu TP44).
- **Status:** 🔜 Stub; wartet auf TP37 P1+2. Quick-Win `terpene.teilzeitladen.xyz → 10.40.20.167:8890` als manueller Caddy-Block ist **Schritt 0** des Runbooks. Plan: [`handoff-20260906-tp37-34-36-plan.md`](handoff-20260906-tp37-34-36-plan.md).
---
<a id="tp44"></a>
### TP44 — Cloudflare-Estate als Dokumentations-SSoT in Nautobot ▸ ✅ **DURCH (2026-09-10): Etappe 1 + Etappe 2 (Teil A IPAM-Prefixe, Teil B Live-Sync als täglicher Nautobot-Job)**
> **Entscheid (User, 2026-09-02):** die volle CF-Estate (Tunnel + WARP-Connector + VPC-Service +
> Hyperdrive + Workers + alle Access-Apps) als strukturierte, abfragbare SSoT in Nautobot abbilden —
> **etappenweise: manuell jetzt, Sync später.** Nautobot kann CF nicht steuern → „SSoT" heißt
> **Dokumentations-SSoT; CF bleibt operativer Master.** Detail-Handoff:
> [`handoff-20260902-cf-estate-nautobot-ssot.md`](handoff-20260902-cf-estate-nautobot-ssot.md).
- **Warum eigenes TP, nicht TP36:** TP36 ist eng auf `teilprojekte.md`-Live-Daten geschnitten; gleiche
Idee (Nautobot als Doku-SSoT), andere Dimension. TP44 = nächste freie Nummer nach TP43.
- **Modell (native `nautobot.cloud`, Nautobot 3.1.7 — keine eigene App):** `Manufacturer "Cloudflare"` →
`CloudAccount` (`393c051f…`) → `CloudResourceType ×6` → `CloudNetwork ×4` (`bf-public`/`fm`/`terpene-db`/
`bf-core-mesh`) + `CloudService ×14`; Service↔Tunnel über das Through-Modell
`cloud-service-network-assignments` (3 Rows). IDs/Ports/Hostnames/Origins je Objekt in `extra_config`.
- **Werkzeug:** `nautobot/tp44-cf-estate-seed.py` — idempotenter Seeder (Re-Run = 26/26 „existiert"),
Datenstand inline (Live-CF-Inventur 2026-09-02). Token aus `docs/nas-vlan20/stacks/210-nautobot.yml`.
- ✅ **Verifikation 2026-09-06 (live gegen die API):** CloudAccount 1 · ResourceType 6 · CloudNetwork 4 ·
CloudService 14 — unverändert seit 09-02.
- 🔴 **Gotchas:** `CloudService.cloud_networks` ist `read_only` (nur Through-Rows schreiben/lesen) ·
VPC-Service-API unter `connectivity/directory/services` (PUT, voller Body) · **VPC-Objekte tragen ihren
Identifier in `service_id`, NICHT `id`** (kostete im Sync einen Fehl-Match) · ⚠️ **DRIFT-KORREKTUR
2026-09-10:** die frühere Zeile „Repo-`CF_API_TOKEN` darf kein Workers-VPC → über den `cloudflare`-MCP"
war **falsch**. Live getestet liest der `CF_API_TOKEN` aus `~/.secrets/credentials.env` Hyperdrive **und**
VPC **und** Workers (alle 200). Der schmale Token ist `CF_DNS_API_TOKEN` (403). Der `cloudflare`-MCP ist
der **remote OAuth-MCP** (kein API-Token) und für einen serverseitigen Job ohnehin nicht nutzbar.
- ✅ **Etappe 2 Teil A (2026-09-08): IPAM-Prefixe live.** `10.40.0.0/16` (container, Route `bf-core-mesh`) +
`10.101.0.0/24` (network, Route `fm`) angelegt via `nautobot/tp44-ipam-prefixes.py`; der Seeder-Re-Run
hat die zwei `cloud-network-prefix-assignments` eingehängt (count=2, Idempotenz-Gegenprobe grün).
- ✅ **Etappe 2 Teil B (2026-09-10): Live-Sync als Nautobot-Job — DURCH.** Governance (User 2026-09-09):
periodische externe→Nautobot-Syncs leben als **Nautobot-Jobs** in `bf-infra/jobs/`, in Nautobot geplant —
**kein per-Task-Container/-Cron.** Runtime `jobs/cf_estate_sync.py` (`CFEstateSync`, ORM, read-only Pull,
403-tolerant, Verwaisung = `extra_config.stale` statt Löschen). Token = Nautobot-Secret `cf-api-token`
(Provider env → `CF_API_TOKEN` am Worker, in `210-nautobot.yml` verdrahtet). **Schedule: täglich 03:00Z**
(`ScheduledJob "CF Estate Sync – taeglich"`). Verifiziert: Dry-Run + Commit-Run sauber, **4 Networks /
14 Services, alle Endpoints lesbar, 0 Drift**. Der REST-Einmalproof `nautobot/tp44-cf-sync.py` bleibt als
workstation-seitiges Diagnose-Werkzeug liegen (nicht die kanonische Runtime).
- 🔴 **Drei load-bearing Funde (Detail-Handoff `handoff-20260910-tp44-teilb-sync-live.md`):**
(1) **Wurzel-`__init__.py` im Repo ist Pflicht** — Nautobot lädt Git-Repo-Jobs via
`pkgutil.walk_packages([GIT_ROOT])`, das Namespace-Packages (ohne `__init__.py`) NICHT entdeckt; ohne die
Datei bleibt `bf_infra.jobs` unsichtbar (Symptom: Sync SUCCESS + „No jobs were registered"). bf-infra ist
das erste Git-Repo mit `extras.job`. (2) `register_jobs()` gehört ins **Paket-`__init__`**, nicht nur ins
Submodul. (3) `Meta.has_sensitive_variables=False` nötig, sonst verweigert Nautobot das Scheduling.
- **Beziehung zu TP37:** TP44 hat **TP37 Punkt 3** (CF-Connectoren) vorweggenommen — dieselbe native-Modell-
Linie, die TP37 P1+2 (Substrat/Dienste) fortsetzt.
### TP41 — CF-Access-Reparatur + Zero-Trust-Konsolidierung ▸ ✅ **ABGESCHLOSSEN (2026-09-10)** — Auth-Kern seit 2026-09-01 komplett; **Gelis WARP-Client am 2026-09-10 via Android erfolgreich eingerichtet** (letzter Blocker weg, User-Bestätigung). Optionale Restpunkte (T6 Rate-Limit, geli-CGNAT-Policy-Cleanup) bewusst nicht gezogen; Keystore-Rotation läuft unter TP30 #7.
**Auslöser:** CF-Access zwang Christoph **und Geli** täglich zum OTP-Login (soll: 30 Tage); GitHub/Google
„funktionieren nicht". Root-Causes: Team-Domain-Rename `bf4`→`emsenhuber` (Provider-Callback veraltet),
App-Session 24h, diverse Ordnungs-/Sicherheitslecks. Vollständiger Verlauf + offene Schritte:
**[`docs/handoff-20260901-tp41.md`](handoff-20260901-tp41.md)**. Branch `tp41-cf-access-repair`.
**✅ Live erledigt:** Session 720h (Wildcard/vw/Warp-Login) · login_method-Loch zu (reusable Policy
`bf-users` = nur `email:christoph`+`email:geli`) · `8e44f5d1` von 4 Apps auf **nur Terpenfinder**
entkoppelt · Access-**Gruppen** `zt-humans`/`zt-home`/`zt-automation`, Policies zeigen darauf · **vw voll
Bypass** (Lebensader offen) + **`vw/admin` per WAF-Regel öffentlich geblockt** (CF-Edge + Mobilfunk
verifiziert) · API-Token auf das vollständige `…4148` konsolidiert (User hat Service-Tokens- + Zero-Trust-
Write ergänzt), altes `…2174` revoken.
**✅ T4 DURCH (2026-09-01, Variante B):** ein Access-Service-Token **`zt-svc`** (`65f1821a`, rotiert) über
Gruppe `zt-automation`; Terpene-Worker per `wrangler secret put TERPENE_SVC_CLIENT_ID` auf zt-svc
umgestellt (Worker-Pin `index.js:44`); `terpene-verify`+`-v2` **gelöscht**; `test_whoami` grün.
**Token-Altlast geklärt:** `b00722` = LIVE Caddy-DNS-Token (LXC130 caddy.env, SSoT), `d47435` = stale
Kopie (kein Consumer) → **User revoket `d47435`**; `credentials.env`-Kopie auf b00722 realignt.
**✅ T3 APPLIED (2026-09-01):** Default-Profil (`0197d1b3`; das custom „Cloudflare Mesh" matcht nur den
`warp_connector`) `fallback_domains += emsenhuber.net → [10.40.20.36, 10.40.20.37]`; Tunnel-Route
`10.40.0.0/16` (`d1da7c8a`) da, kein `10/8`-Exclude → routbar. ⏳ Client-Verify: WARP neu verbinden.
**✅ T2 DURCH (2026-09-01):** WAF-Regel `f26744eb` gelöscht; Caddy `vw`-Block `respond @cf_admin 404` bei
Header `CF-Connecting-IP` (LXC130). Verify: Edge `/admin`=404, lokal/WARP `/admin`=200. ✅
**✅ T5 DURCH (2026-09-01, User-bestätigt):** GitHub-Login läuft; Google-Login läuft nach dem
Consent-Screen-Fix (§A des Follow-up-Handoffs: User Type *Internal*→*External*/veröffentlicht).
Callback für beide `https://emsenhuber.cloudflareaccess.com/cdn-cgi/access/callback`.
**❌ Facebook/Meta für TP41 abgesagt (2026-09-01, User-Entscheid):** optional, kein Bedarf — Geli ist
über OTP `angelikahy@outlook.de` + Google `pillepalle670@gmail.com` voll gedeckt. **Keine Facebook-App,
kein CF-Facebook-IdP angelegt → nichts aufzuräumen.** Instagram hat ohnehin keinen CF-IdP.
**✅ App-Launcher (D1):** je eine Bookmark-Kachel vw/hass/terpenfinder, Wildcard-Kachel raus, Launcher
gestylt (Follow-up-Handoff §D, Policies unverändert).
**✅ Geli in WARP — CF-seitig nichts zu tun (2026-09-01 live geprüft):** Device-Enrollment läuft über
die App **„Warp Login App"** (`6c32fe23…`, type `warp`) → Policy `bf-users` → Gruppe **`zt-humans`**, die
Gelis beide Mails **schon enthält** → sie **darf bereits enrollen** (deshalb war „Device enrollment
permissions" nicht als fehlendes Setting zu finden). Terpenfinder-`geli`-Policy lässt sie per E-Mail durch.
✅ **Client am 2026-09-10 via Android erfolgreich eingerichtet** (WARP installiert, Team `emsenhuber`,
Login OTP `angelikahy@outlook.de` — User-Bestätigung); damit ist der einzige verbliebene Handgriff erledigt.
🔑 **Permission-Frage beantwortet:** CF-seitig **keine** nötig. Für generelle WARP/Enrollment/User-Verwaltung
per Account-Token: *Access: Apps and Policies → Edit* + *Access: Organizations, IdPs, and Groups → Edit*
(User erteilt 2026-09-01). **Seat-Verwaltung (`/access/seats`) bleibt per MCP gesperrt** — `10405 Method
not allowed for this authentication scheme` (Endpoint will User-Token, nicht Account-Token; kein Scope-Fix,
für Enroll irrelevant).
**🔻 Optionale Restpunkte (bewusst nicht gezogen, kein Blocker):** **T6** optional Rate-Limit ·
🔴 `TERPENE_ANDROID_KEYSTORE_PW`-Rotation (→ **TP30 Posten #7**, Transkript-Leak) · **Security-Cleanup:**
die `geli`-Terpenfinder-Policy hat **OR-Semantik** und enthält den breiten CGNAT-Bereich
`94.154.138.0/24` als IP-Include → jeder aus dieser geteilten Range käme **ohne Login** rein. Über WARP ist
der Egress ohnehin Cloudflare (nicht diese IP) → der IP-Include wäre dann überflüssig und entfernbar.
**d47435-Revoke ✅ · T3-WARP-Client-Verify ✅** (User, 2026-09-01).
**Abgrenzung:** hass/gitea bleiben (diese Runde) öffentlich; Terpenfinder-Human-Policies nicht angefasst;
**Gitea-Least-Privilege** = eigener künftiger TP (jedes Projekt repo-scoped Login, Admin nur Claude/Christoph).
- Bezug **TP11** (Monitoring): eine Plattenfüllstand-Warnung hätte das Wochen früher gezeigt.
### TP43 — dw-Standort-DNS-Uplink (site-spezifische Overrides) ▸ ♻️ **REOPENED 2026-09-11 → Volltext zurück in [`teilprojekte.md`](teilprojekte.md) (Abschnitt TP43)**
Kurz zwischen 2026-09-11 verworfen und am selben Tag reopened: die 420-Prämisse war gegenstandslos
(public CF-Worker, via WARP/TP41 gelöst), aber die **interne** BF-Namensauflösung über WG am dw blieb
dabei offen (`portainer.bf.emsenhuber.net` am dw nicht erreichbar). Korrigierter Scope + verworfene
420-Historie stehen jetzt aktiv in `teilprojekte.md`. Gitea-Issue #32 = `status:todo` · `thema:firewall-dns`.
### TP42 — Namens-Vereinheitlichung: ein interner Suffix bf.emsenhuber.net ▸ ✅ **DURCH (2026-09-02)** — ein interner Suffix `bf.emsenhuber.net`, `.bf.lan` raus, `.16` (adguard_bf1) abgebaut, Compliance 140/140. Offen nur der an **TP37** gekoppelte Nautobot-Doku-Teil.
**Auslöser (2026-09-01, TP41-Randbefund):** live gemessen liefern die realen Client-Resolver
`10.40.20.36`/`.37` `*.emsenhuber.net → 10.40.20.40` (Caddy) — korrekt. Daneben existiert aber ein
zweiter, gedrifteter interner Namensraum: der **Core** trägt in `/ip dns static` 11 Einträge auf
`*.bf.lan`, der **Caddyfile** doppelt jeden internen Namen als `*.bf.emsenhuber.net`, und die alten
AdGuard `.16`/`.17` antworten noch mit `nginx*.bf.emsenhuber.net` bzw. totem VLAN1 `10.40.41.123`.
Christoph: „aus emsenhuber.net wurde schon wieder bf.lan — das müssen wir ein für alle mal aus allen
Geräten rausprügeln und in Nautobot festhalten."
**Ziel:** genau **ein** interner Namensraum `emsenhuber.net` (Split-Horizon `.36/.37 → .40`). `.bf.lan`
und `.bf.emsenhuber.net` werden entfernt; Sollzustand in Nautobot dokumentiert.
**Scope (Reihenfolge = eigene Session):**
1. **Bestandsaufnahme** aller Fundstellen: Core `/ip dns static` (`*.bf.lan`), DHCP-Option
`domain`/Search-Domain je Netz, Caddyfile-Aliase (`*.bf.emsenhuber.net`), AdGuard-Rewrites `.36/.37`,
stale `.16/.17`, Geräte-`identity`.
2. **Entscheidung Zielschema** (nur `emsenhuber.net`, ggf. `bf.emsenhuber.net` als *einzige* interne
Zone — Christoph-Entscheid) und Migrationsreihenfolge ohne DNS-Loch.
3. **Umsetzen:** Core-DNS + DHCP + Caddyfile angleichen; stale `.16/.17` klären/abbauen.
4. **Nautobot:** interne Namen/Records als Sollzustand erfassen (Bezug TP37 Datenmodell).
**Abgrenzung:** kein CF-Public-DNS-Umbau (Zone `emsenhuber.net` öffentlich bleibt); kein Resolver-Swap
(`.36/.37` bleiben); `.1`-als-DNS-Reste auf Clients sind separat/tolerierbar (User: „bis jetzt kein
Problem"). **Abh.:** TP37 (Nautobot-Datenmodell) für Punkt 4; sonst nichts Offenes.
#### ✅ Bestandsaufnahme LIVE (2026-09-02) — Drift hat 80 % schon erledigt
Gegen die Geräte gemessen (MikroMCP + dig), nicht aus dem Handoff:
| Fundstelle | Handoff 09-01 | Live 09-02 |
|---|---|---|
| Core `/ip dns static` | 11× `*.bf.lan` | ✅ **0× `.bf.lan`** — 10× `*.bf.emsenhuber.net` (deckt sich mit GC-Template Z.284–293) |
| DHCP `domain` (7 Netze) | „prüfen" | `emsenhuber.net` (GC-Template Z.133 = gleich ⇒ **keine Drift**), DNS `.36/.37` |
| `.36/.37` (Soll) | aktiv | `vw.emsenhuber.net→.40` ✅ · `macmini.bf.emsenhuber.net→.20.167` ✅ · **`macmini.emsenhuber.net→leer`** ❌ |
| Caddyfile | `*.bf.emsenhuber.net`-Aliase | unverändert, **konsistent** mit Core-Static |
| `.16`/`.17` | tot | laufen (:53), liefern totes VLAN1; **kein Core-Objekt** (Firewall/NAT/DNS-Upstream/Addr-List) hängt an `.16` |
**Kernkonflikt:** DHCP verteilt `emsenhuber.net` (bare), Records leben unter `bf.emsenhuber.net` ⇒ bare `macmini` löst nicht.
#### ✅ Entscheidungen (User, 2026-09-02)
1. **Zielschema = `bf.emsenhuber.net`** (der wenig-Arbeit-Weg): DHCP-domain → `bf.emsenhuber.net`, dann
löst `macmini` bare korrekt; Core-Static + Caddyfile bleiben (tragen schon `.bf.`). Öffentliche Zone
`emsenhuber.net` bleibt getrennt.
2. **`.16` (adguard_bf1) abbauen**, **`.17` (adguard_fm2 = Standort FM) NICHT anfassen.**
#### ✅ Umsetzung DURCH (2026-09-02)
- **(A) DHCP-domain `emsenhuber.net → bf.emsenhuber.net` über GC ✅** — kein Direkt-Write:
`mikrotik_routeros.j2` Z.133 gehoben → `push-gc-template.py` (Commit `7a4068c4`, **Nebenbefund:** das
Remote-Template hing dem lokalen hinterher — es trug noch `*.bf.lan`+`router.lan`, obwohl Gerät+lokal
längst `.bf.emsenhuber.net` fuhren; der Push hat das GC-Repo an den Live-Stand angeglichen) →
GitRepo-Sync (SUCCESS) → manueller ConfigPlan **`tp42-dhcp-domain`** (`set [find] domain=…`, weil
`add` das Netz doppelt anlegen würde) → Deploy an **crs326-core** → Live **7/7 = bf.emsenhuber.net**,
Compliance **140/140, keine Drifts**. Der Job steht dauerhaft in `nautobot/gc-configplan.py`.
- **(B) `.16`-Teardown ✅** — `adguard_bf1` lag im geteilten Portainer-Stack **195 `adguard`** (Docker-LXC
`.126`, **ep2** — *nicht* ep14) **zusammen mit `adguard_fm2` (`.17`, Standort FM!)**. Deshalb **nicht**
Stack löschen, sondern compose auf nur `.17` getrimmt + Stack redeployt (Prune): `.16`-Container weg,
`.16:53` tot; **`.17` läuft** (⚠️ ~40 s mit-neugestartet durch den Redeploy — kurzer FM-DNS-Blip,
danach sauber). Rollback-compose gesichert. 🧹 Daten-Dirs `/opt/docker/adguard_bf1/*` bleiben als
harmlose Leichen auf dem LXC.
- **(C) Nautobot-Soll** (Scope-Punkt 4) bleibt an **TP37** gekoppelt (Datenmodell), separat — kein Blocker.
**Status:** ✅ **Namensraum vereinheitlicht (2026-09-02)** — ein interner Suffix `bf.emsenhuber.net`,
`.bf.lan` raus, `.16` abgebaut, Compliance 140/140. Offen nur der TP37-gekoppelte Nautobot-Doku-Teil.
Handoff: [`docs/handoff-20260901-tp42-naming.md`](handoff-20260901-tp42-naming.md).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
# TP23 Stufe 6 — DNS-Bypass-Sperre (Runbook für eine SEPARATE, VOR-ORT-Session)
> 🔴🔴 **HARTES GATE: NUR VOR ORT ausführen. NICHT aus der Ferne, nicht während Christoph
> abwesend ist.** (Notiert 2026-09-06: Christoph ist ~1 Woche nicht vor Ort → in diesem Fenster
> **gar nicht anfangen**, auch nicht die log-only-Vorstufe scharf lassen.)
>
> Grund: Die Sperre macht das AGH-Paar `.36`/`.37` zum **harten DNS-SPOF**. Bis heute kann jeder
> Client bei einem AGH-Ausfall auf einen externen Resolver ausweichen; **nach** der Sperre nicht
> mehr — ein AGH-Ausfall = **hausweiter DNS-Ausfall** (betrifft die Familie), und ohne physischen
> Zugriff gibt es keinen schnellen Rollback. Eine falsch platzierte Drop-Regel kann außerdem den
> **Fernzugang selbst** (WG/cf-mesh) aussperren, mit dem man den Fehler zurücknehmen wollte.
## Ziel
Clients dürfen plain **DNS (udp/tcp 53)** und **DoT (853)** nur noch zu den erlaubten Resolvern
(`10.40.20.36`, `10.40.20.37`, Core `10.40.X.1`) schicken. Externe DNS-Server (Smart-TV mit
`8.8.8.8` hartkodiert, App-eigene Resolver) werden geblockt → **kein Umgehen des Filters**.
Das ist der letzte Baustein von TP23 und lebt in der **TP5-Firewall** (`forward`-Kette).
## Voraussetzungen
**Erfüllt (Stand 2026-09-06):**
- Self-Service-Oberfläche steht und ist getestet (HA-Dashboard `dns-ausnahmen`, Stufe 5) → ein
geblockter Dienst kann **ohne Admin** temporär freigegeben werden. Das war die harte
Reihenfolge-Regel („erst der Ersatz, dann die Sperre").
- `dns-bypass-exempt`-Gruppe existiert auf dem Resolver-Paar (AGH-Client-Seite).
**Noch zu bauen (Teil dieser Session, VOR dem Drop):**
- **Firewall-Exempt** ist noch NICHT da: eine Address-List `dns-bypass-exempt` (permanent) mit dem
dev-MacBook (`10.40.10.183` **und** `10.40.10.82`, dual-homed) + Agent-Toolchain, plus eine
`accept`-Regel **vor** dem Drop. Ohne die verliert der Entwicklungsrechner seinen Ausweg.
- Ad-hoc-JIT: Address-List `jit-dns-bypass` mit `timeout` nach dem Muster `jit-admin`
(`routeros/tp5-etappe4-input-mgmt.rsc`) — selbstverfallende Freigabe.
## Bekannte Grenze (offen benennen, nicht „lösen")
Die Sperre greift auf **Port** (53/853). **DoH läuft über 443** und ist damit portgleich zu HTTPS —
ein Gerät, das DoH gegen `8.8.8.8:443` fährt, umgeht die Sperre. Das per SNI/IP zu schließen ist
ein eigenes, größeres Thema (nicht Teil von TP23). Für den Alltag (TVs/IoT mit Plain-DNS) reicht die
Port-Sperre.
## Sichere Methodik — log-only zuerst, Drop zuletzt
1. **Exempt + JIT bauen** (via Nautobot GC, `ip-firewall-filter` steht unter Drift-Kontrolle → **kein
Direkt-Write**): `accept` für `dns-bypass-exempt`/`jit-dns-bypass` → 53/853, platziert **vor** der
künftigen Drop-Regel. Erst hier abnehmen, dass die Exempts wirklich durchkommen.
2. **Log-only-Vorstufe**: eine Regel `TP5-WOULD-DROP-DNS`, die LAN→extern auf `dst-port 53,853`
(udp+tcp), **nicht** zu `.36/.37/Core`, **nur loggt** (in den Kollektor `10.40.20.18:514`, wie die
bestehende `TP5-WOULD-DROP`). **Mehrere Tage laufen lassen** und den Drop-Log lesen: *welche*
Geräte reden mit *welchen* externen Resolvern? Jedes davon ist ein Kandidat, der nach dem Drop
bricht — vorab entscheiden (Reservierung auf AGH, Exempt, oder bewusst brechen lassen).
🔑 Merkregel aus dem E5-Drop-Log: Geräte fallen oft mit **udp/161/andere** nebenbei auf — nur die
53/853-Zeilen zählen hier.
3. **Erst nach ruhigem/verstandenem Log**: die Log-only-Regel auf `action=drop` (oder `reject` mit
`icmp-port-unreachable`, damit Clients schneller auf den nächsten Resolver fallen) heben —
**mit Auto-Revert-Absicherung** (Scheduler/Netwatch, der die Regel nach X Minuten deaktiviert,
falls nicht bestätigt), analog zum TP5-E3/E4-Vorgehen. **Vor Ort**, mit offener Konsole.
## Was NICHT gesperrt werden darf (sonst Selbst-Aussperrung)
- `.36`/`.37` → CF-DoH-Upstream (443) und Core-Resolver-Egress: die Resolver müssen raus.
- Core `10.40.X.1` DoH-Egress.
- **cf-mesh / WG-Pfad** (Fernzugang) — die Drop-Regel matcht nur `dst-port 53,853`; trotzdem vor dem
Scharfschalten gegenprüfen, dass Management-Input (`cf-mesh`, HA `8728`, Nautobot `22`) unberührt
bleibt.
## Rollback
- GC-Deploy der vorherigen Version (Regel zurück auf `disabled`/entfernt) — bzw. der Auto-Revert.
- Fällt das AGH-Paar bei aktiver Sperre aus: Drop-Regel deaktivieren (Vor-Ort-Konsole) → Clients
können sofort wieder externe Resolver nutzen.
## Abnahme
- Exempt-Host (dev-MacBook) löst extern weiter auf; ein Test-Gerät mit hartkodiertem `8.8.8.8` löst
**nicht** mehr (aber über AGH schon).
- Self-Service: eine geblockte Domain per HA-Button freigeben → wirkt; nach Ablauf wieder gefiltert.
- Compliance nach dem GC-Deploy grün (`python3 nautobot/gc-transaktion.py status`, GC 140/140).
## Verweise
- Stufe 4/5 (fertig): `adguard/README.md`, `adguard/ha-self-service.md`, `adguard/agh-exception.py`.
- JIT-/Firewall-Muster: `routeros/tp5-etappe4-input-mgmt.rsc`; GC-Pipeline: `nautobot/gc-configplan.py`.
- Kontext/Reihenfolge-Regel: TP23-Abschnitt in `docs/teilprojekte.md`.

View File

@@ -22,6 +22,7 @@ Damit wird aus "irgendwo zwischen 15:07 und 15:09 war es schlecht" ein Satz mit
"""
import argparse
import csv
import glob
import os
import re
import sys
@@ -98,24 +99,45 @@ def lade_pings_alt(pfad):
return treffer
def geraete(run_dir):
"""Liste von Geraeten: (rolle, ping-Liste, funk-Liste).
def _sampler_funk(pfad):
"""funk-Liste (sekunde, iface, signal, phy_rate_oder_None) aus einer sampler-CSV."""
funk = []
if os.path.exists(pfad):
for r in csv.DictReader(open(pfad)):
if r.get("sta_signal"):
funk.append((sec(r["ts_local"]), r.get("sta_iface") or "",
int(r["sta_signal"]),
int(r["sta_tx_rate"]) if (r.get("sta_tx_rate") or "").isdigit() else None))
return funk
funk-Liste = (sekunde, iface, signal, phy_rate_oder_None). Die PHY-Rate gibt es nur
fuer die Sonde (sampler.csv, 1-s-Takt); fuer die Referenz liefert beide-telefone.csv
nur AP und Signal im 2-s-Takt. Das ist bewusst so und wird unten beim Ruhezustand
beruecksichtigt -- ohne Rate ist der Befund schwaecher und wird auch so benannt.
def geraete(run_dir):
"""Liste benannter Geraete: (name, ping-Liste, funk-Liste).
funk-Liste = (sekunde, iface, signal, phy_rate_oder_None).
Seit 2026-09-04 (N-Geraete-Umbau) schreibt die Harness pro Geraet walk-ping-<name>.csv
UND sampler-<name>.csv -- jedes Paar wird als EIN benanntes Geraet gelesen, beliebig viele,
ohne feste Sonde/Referenz-Rollen. Faellt auf das alte 2-Rollen-Schema zurueck (sampler.csv /
walk-ping.csv / walk-ping-iphone.csv / beide-telefone.csv), damit Laeufe vor dem Umbau
weiter auswertbar bleiben. Unterschieden wird an der NACKTEN sampler.csv/walk-ping.csv:
die schreibt nur das alte Schema -- die neue Harness nie (immer mit -<name>). Ohne diese
Klammer wuerde der glob unten die walk-ping-iphone.csv eines Alt-Laufs fassen und dessen
Sonde (walk-ping.csv, ohne Suffix) stillschweigend verlieren.
"""
pfad = lambda n: os.path.join(run_dir, n)
sonde_funk = []
if os.path.exists(pfad("sampler.csv")):
for r in csv.DictReader(open(pfad("sampler.csv"))):
if r.get("sta_signal"):
sonde_funk.append((sec(r["ts_local"]), r.get("sta_iface") or "",
int(r["sta_signal"]),
int(r["sta_tx_rate"]) if (r.get("sta_tx_rate") or "").isdigit() else None))
legacy = os.path.exists(pfad("sampler.csv")) or os.path.exists(pfad("walk-ping.csv"))
if not legacy:
gs = []
for pp in sorted(glob.glob(os.path.join(run_dir, "walk-ping-*.csv"))):
name = os.path.basename(pp)[len("walk-ping-"):-len(".csv")]
gs.append((name, lade_pings(pp), _sampler_funk(pfad("sampler-%s.csv" % name))))
if gs:
return gs
# --- Legacy: 2-Rollen-Schema (Laeufe vor 2026-09-04) ---
sonde_funk = _sampler_funk(pfad("sampler.csv"))
ref_funk = []
if os.path.exists(pfad("beide-telefone.csv")):
for r in csv.DictReader(open(pfad("beide-telefone.csv"))):
@@ -189,6 +211,9 @@ def main():
gs = geraete(a.dir)
if not any(g[1] or g[2] for g in gs):
raise SystemExit("Weder Ping-Antworten noch Funkproben gefunden.")
# Alte 2-Rollen-Laeufe tragen die Namen "Referenz"/"Sonde" und bekommen den Rollen-Text;
# neue N-Geraete-Laeufe tragen Geraetenamen (iphone/s22/ipad/...) -- ohne Rollen-Erklaerung.
legacy_rollen = any("Sonde" in r or "Referenz" in r for r, _, _ in gs)
rooms = []
for m in csv.DictReader(open(os.path.join(a.dir, "markers.csv"))):
@@ -209,9 +234,12 @@ def main():
for i, r in enumerate(rooms)]
mehrere = len(gs) > 1
if mehrere:
if mehrere and legacy_rollen:
print("REFERENZ = iPhone, roamt frei (was du hier wirklich hast)")
print("SONDE = S22, auf den Gegen-AP gezwungen (was die Rückfallebene noch kann)\n")
elif mehrere:
print("Ein Block je Raum, eine Zeile je Gerät (%s) — alle frei roamend.\n"
% ", ".join(r for r, _, _ in gs))
print("%-15s %-17s %5s %-22s %-17s %s"
% ("Raum", "Rolle", "Dauer", "Signal min/⌀/max", "Verlust", "längste Lücke"))
print("-" * 100)
@@ -262,9 +290,13 @@ def main():
print("\nLesehilfe: eine längste Lücke über ~2 s ist für einen Videocall eine hörbare")
print("Unterbrechung, über 10 s ist der Call praktisch tot. Signal unter −70 dBm ist die")
print("Zone, in der das passiert.")
if mehrere:
if mehrere and legacy_rollen:
print("\nDie interessante Spalte ist der Unterschied: gute Referenz + schlechte Sonde")
print("= hier hängt alles an EINEM AP. Beide schlecht = echtes Loch ohne Rückfallebene.")
elif mehrere:
print("\nDie interessante Spalte ist der Unterschied ZWISCHEN den Geräten am selben Ort:")
print("streuen Signal/Verlust stark, liegt es am Gerät (Antenne/Standby), nicht am Funk;")
print("sind alle an einem Ort schlecht, ist es ein echtes Loch der Ausleuchtung.")
if __name__ == "__main__":

105
docs/tp25-pin-multi.sh Executable file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env bash
#
# TP25 — MEHRERE Clients gleichzeitig band-genau auf je EINEN AP pinnen.
#
# Wozu (2026-09-04): die Gehweg-Messung soll pro AP getrennt zeigen, wie weit er reicht. Dazu
# wird je Sonde GENAU EIN cap-wifiN erlaubt (also ein AP UND ein Band) und alle anderen per
# access-list abgewiesen. Das iPhone bleibt bewusst UNGEPINNT (frei roamende Referenz).
#
# Unterschied zu tp25-pin-s22.sh: das pinnt EIN Geraet AP-genau (beide Baender). Hier: N
# Geraete, band-genau, je eigener Tag TP25-PINM-<name> -- damit `off` sauber nur diese entfernt.
#
# set: TP25_PINSPEC="ipad|CA:..|ap1|5;macbook|56:..|ap2|5;s22|2A:..|ap3|5" bash tp25-pin-multi.sh set
# verify: bash tp25-pin-multi.sh verify # zeigt je Sonde das aktuelle Interface
# off: bash tp25-pin-multi.sh off # alle TP25-PINM-* weg
#
# Band im Spec: "5" = 5 GHz, "24"/"2"/"2.4" = 2,4 GHz. AP: ap1|ap2|ap3 (wie in der Live-Karte).
#
# 🔴 Die cap-wifiN-Zuordnung wird bei JEDEM Aufruf frisch aus der Karte (tp25-pin-s22.sh map)
# gelesen -- sie wandert bei jedem CAP-Rejoin. Niemals cachen.
# 🔴 access-list steht unter KEINER ComplianceRule -> kein Nautobot-Drift. Jede Regel traegt
# ihren Tag; `off` raeumt vollstaendig auf.
# 🔴 Bewusst KEINE assoziativen Arrays (declare -A): macOS /bin/bash ist 3.2. Lookup per grep.
set -uo pipefail
TAG_PREFIX="TP25-PINM"
ROUTER_IP="${TP25_MANAGER_IP:-10.40.99.1}"
HERE="$(cd "$(dirname "$0")" && pwd)"
ZIEL="${1:-verify}"
PW="$(grep -m1 '^CRS326_CORE_PASS=' ~/.secrets/credentials.env | cut -d= -f2- | sed 's/^["'"'"']//; s/["'"'"']$//')"
[[ -n "$PW" ]] || { echo "CRS326_CORE_PASS nicht in ~/.secrets/credentials.env gefunden" >&2; exit 1; }
# 🔴 sshpass -e statt -p: PW nie in die Kommandozeile (ps/Trace-Leak, 2026-08-22). Ausgabe zusaetzlich maskiert.
ros() {
SSHPASS="$PW" sshpass -e ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 \
"admin@${ROUTER_IP}" "$1" 2>&1 | sed "s/${PW//\//\\/}/***/g"
}
# Live-Karte (cap-wifiN=apX/Band, je Zeile) als String. Reuse von tp25-pin-s22.sh (map).
MAP=""
declare -a ALL_IFACES
lade_karte() {
MAP="$(bash "$HERE/tp25-pin-s22.sh" map)"
[[ -n "${MAP//[[:space:]]/}" ]] || { echo "Live-Karte leer -- haengen die CAPs am Manager?" >&2; exit 1; }
ALL_IFACES=()
while IFS='=' read -r iface _label; do [[ -n "$iface" ]] && ALL_IFACES+=("$iface"); done <<< "$MAP"
}
label_of() { grep -m1 "^$1=" <<< "$MAP" | cut -d= -f2-; }
# ap + band -> cap-wifiN (aus der Karte). Band-Eingabe normalisieren.
ziel_iface() { # $1=ap $2=band
local want
case "$2" in
5|5g|5G|5GHz) want="$1/5GHz" ;;
24|2|2.4|2,4|2g|2G) want="$1/2,4GHz" ;;
*) echo "" ; return ;;
esac
grep -m1 "=${want}\$" <<< "$MAP" | cut -d= -f1
}
kick() { ros "/interface wifi registration-table remove [find where mac-address=\"$1\"]" >/dev/null; }
aufraeumen_alle() { ros "/interface wifi access-list remove [find where comment~\"$TAG_PREFIX\"]" >/dev/null; }
case "$ZIEL" in
set)
[[ -n "${TP25_PINSPEC:-}" ]] || { echo "TP25_PINSPEC fehlt (name|mac|ap|band;...)" >&2; exit 2; }
lade_karte
aufraeumen_alle
IFS=';' read -ra ENTRIES <<< "$TP25_PINSPEC"
for e in "${ENTRIES[@]}"; do
[[ -z "${e//[[:space:]]/}" ]] && continue
IFS='|' read -r name mac ap band <<< "$e"
[[ -n "$name" && -n "$mac" && -n "$ap" && -n "$band" ]] || { echo "Spec-Eintrag unvollstaendig: '$e'" >&2; exit 2; }
ziel="$(ziel_iface "$ap" "$band")"
[[ -n "$ziel" ]] || { echo "Kein Interface fuer $ap/$band in der Karte -- AP am Manager? Abbruch." >&2; exit 1; }
tag="${TAG_PREFIX}-${name}"
# Alle Interfaces AUSSER dem Ziel abweisen -> nur $ziel bleibt erlaubt (AP + Band erzwungen).
gesperrt=""
for i in "${ALL_IFACES[@]}"; do
[[ "$i" == "$ziel" ]] && continue
ros "/interface wifi access-list add mac-address=$mac interface=$i action=reject comment=\"$tag\"" >/dev/null
gesperrt="$gesperrt $i"
done
echo "$name ($mac) -> $ziel ($(label_of "$ziel")); abgewiesen:$gesperrt"
kick "$mac"
done
echo; echo "Gesetzt. Kontrolle in ~6 s: bash $0 verify" ;;
off)
aufraeumen_alle; echo "Alle ${TAG_PREFIX}-* entfernt." ;;
verify)
lade_karte
echo "--- aktive ${TAG_PREFIX}-Regeln ---"
r="$(ros "/interface wifi access-list print terse where comment~\"$TAG_PREFIX\"")"
[[ -z "${r//[[:space:]]/}" ]] && echo " (keine)" || echo "$r" | tr -d '\r' | sed 's/^/ /'
echo "--- aktuelle Anmeldungen (Ziel-Kontrolle) ---"
a="$(ros '/interface wifi registration-table print terse proplist=mac-address,interface,signal,ssid')"
echo "$a" | tr -d '\r' | grep -E 'mac-address=' | while IFS= read -r line; do
ifc="$(sed -n 's/.*interface=\([^ ]*\).*/\1/p' <<< "$line")"
echo " ${line} [$(label_of "$ifc")]"
done ;;
map) bash "$HERE/tp25-pin-s22.sh" map ;;
*) echo "Aufruf: $0 {set|verify|off|map} (set liest TP25_PINSPEC)" >&2; exit 2 ;;
esac

View File

@@ -56,8 +56,14 @@ ros() {
}
# cap-wifiN -> "apX Band" -- live, ohne Cache. Ausgabe je Zeile: cap-wifi3=ap1/5GHz
# 🔴 channel.frequency ist seit dem DFS-Kanalplan (2026-09-03, Frequenz-Listen 5260,5280 /
# 5300,5320) fuer die 5G-Radios ein ARRAY, kein Skalar. Die alte Zeile verglich das Array
# direkt mit 3000 und lieferte fuer die betroffenen Radios Muell -- den `grep '^cap-wifi'`
# samt pipefail dann verschluckte, sodass `map` LEER zurueckkam und ap-map.txt leer blieb.
# Fix: bei :typeof=array das erste Element nehmen. Beleg-Kommando dieses Fundes am Manager:
# `:foreach ... :put (name . " freq=" . channel.frequency)` -> "5260;5280" fuer cap-wifi1.
karte() {
ros ':foreach i in=[/interface wifi find where !master-interface] do={:local c [/interface wifi get $i cap]; :local f [/interface wifi get $i channel.frequency]; :local b "2,4GHz"; :if ($f > 3000) do={:set b "5GHz"}; :put ([/interface wifi get $i name] . "=" . [:pick $c 0 [:find $c "@"]] . "/" . $b)}' \
ros ':foreach i in=[/interface wifi find where !master-interface] do={:local c [/interface wifi get $i cap]; :local fl [/interface wifi get $i channel.frequency]; :local f 0; :if ([:typeof $fl]="array") do={:set f [:tonum [:pick $fl 0]]} else={:set f [:tonum $fl]}; :local b "2,4GHz"; :if ($f > 3000) do={:set b "5GHz"}; :put ([/interface wifi get $i name] . "=" . [:pick $c 0 [:find $c "@"]] . "/" . $b)}' \
| tr -d '\r' | grep '^cap-wifi[0-9]*='
}

View File

@@ -19,9 +19,9 @@ cd "$HERE"
NAME="${1:-$(date +%Y%m%d-%H%M)}"
export TP6_RUN_DIR="$HERE/docs/messdaten/tp25-runde-$NAME"
export TP25_PHONE_IP="${TP25_PHONE_IP:-10.40.10.178}" # S22 -- wird gepingt
export TP25_PHONE_MAC="${TP25_PHONE_MAC:-2A:0D:B0:5D:AD:A7}"
export TP25_IPHONE_MAC="${TP25_IPHONE_MAC:-F2:62:4C:E1:AF:09}"
# N-Geraete-Liste (name|ip|mac;...). Default = die bisherigen zwei, damit alte Aufrufe
# unveraendert weiterlaufen. Wird an tp25-walk-messung.sh durchgereicht.
export TP25_PHONES="${TP25_PHONES:-iphone|10.40.10.196|F2:62:4C:E1:AF:09;s22|10.40.10.178|2A:0D:B0:5D:AD:A7}"
mkdir -p "$TP6_RUN_DIR"
@@ -36,14 +36,6 @@ else
sleep 2
fi
# 🔴 Gegen-AP-Automatik gleich einschalten. Sie war bisher ein Klick auf der Konsole -- und
# wer ihn vergisst, geht die ganze Runde mit beiden Telefonen auf DEMSELBEN AP und merkt
# es erst bei der Auswertung (im Test am 2026-08-22 genau so passiert). Abschalten geht
# weiter jederzeit ueber den Knopf.
curl -s -X POST --max-time 10 "http://127.0.0.1:3031/auto?an=1" >/dev/null 2>&1 \
&& echo "Gegen-AP-Automatik: EIN" \
|| echo "⚠️ Automatik konnte nicht eingeschaltet werden -- auf der Konsole nachholen!"
echo
echo "════════════════════════════════════════════════════════════"
echo " Konsole am Telefon oeffnen:"
@@ -53,8 +45,8 @@ ifconfig | awk '/^[a-z0-9]+:/{i=substr($1,1,length($1)-1)}
/inet /{if ($2 !~ /^127\.|^169\.254\./) printf " http://%s:3031/ (%s)\n", $2, i}'
echo
echo " 1) Auf dem Telefon einmal irgendwo tippen -> schaltet den Signalton frei"
echo " 2) Gegen-AP-Automatik laeuft bereits -> S22 folgt dem iPhone spiegelverkehrt"
echo " 3) Losgehen. Doppelton = beide angemeldet -> Raum antippen, weiter"
echo " 2) In der Konsole pinnen (Multi-Pin) -> je Client AP/Band waehlen, 'Pin setzen'"
echo " 3) Losgehen. Raum antippen, weiter -> Alarm = gepinnter Client haengt nirgends"
echo
echo " Lauf: $TP6_RUN_DIR"
echo "════════════════════════════════════════════════════════════"
@@ -63,18 +55,17 @@ echo
aufraeumen() {
echo
echo "Runde beendet. Aufraeumen …"
# 🔴 REIHENFOLGE: erst die Konsole toeten, dann den Pin loesen. Andersherum ist es ein
# Wettlauf, den man verliert -- die Automatik der noch laufenden Konsole sieht den
# geloesten Pin und setzt ihn binnen zwei Sekunden wieder. Am 2026-08-22 meldete der
# Aufraeumer brav "AP-Pin geloest", und danach standen die Regeln trotzdem am Core:
# das Telefon waere nach jeder Runde gepinnt geblieben.
# 🔴 REIHENFOLGE: erst die Konsole toeten, dann den Pin loesen. Die Konsole pinnt nicht
# mehr automatisch (die alte Gegen-AP-Automatik ist mit dem Multi-Pin-Umbau 2026-09-04
# entfallen), aber sie haelt ggf. noch SSH-Sitzungen zum Manager offen -- die erst
# beenden, bevor der Pin geloest wird.
[[ -n "$KONSOLE" ]] && kill "$KONSOLE" 2>/dev/null && echo " Konsole beendet."
# Muster bewusst ohne -e/-p: es gab beide Varianten, und die enge Fassung liess den
# Sampler stehen.
pkill -f 'sshpass.*10.40.99.1' 2>/dev/null
pkill -f 'tp6-monitor-core.sh' 2>/dev/null
sleep 1
bash docs/tp25-pin-s22.sh off >/dev/null 2>&1 && echo " AP-Pin geloest."
bash docs/tp25-pin-multi.sh off >/dev/null 2>&1 && echo " Multi-Pin geloest."
echo
echo "Auswertung:"
echo " python3 docs/tp25-gehweg-auswertung.py --dir $TP6_RUN_DIR"

View File

@@ -19,14 +19,24 @@
set -uo pipefail
RUN_DIR="${TP6_RUN_DIR:-/private/tmp/claude-501/-Users-christophemsenhuber-dev-bf-network-r6/0d86ebd1-035f-4513-a231-5cca8111ecfd/scratchpad/tp6-run2}"
PHONE="${TP25_PHONE_IP:-10.40.10.178}" # S22 -- wird gepingt und gesampelt
PHONE_MAC="${TP25_PHONE_MAC:-2A:0D:B0:5D:AD:A7}"
# 🔴 Seit dem Lauf vom 2026-08-22 wird das ZWEITE Telefon mitgepingt. Vorher lief der Ping
# nur auf das gepinnte Geraet -- und weil das per Automatik immer auf dem GEGEN-AP sitzt,
# fehlte ausgerechnet die Strecke, die die Alltagsabdeckung zeigt. Der Terrassen-Vergleich
# liess sich deshalb nicht fuehren, obwohl beide Telefone dabei waren.
PHONE2="${TP25_PHONE2_IP:-10.40.10.196}" # iPhone -- roamt frei
PHONE2_NAME="${TP25_PHONE2_NAME:-iphone}"
# 🔴 Handy-Liste generalisiert (2026-09-03, TP25-4-Handy-Messung): statt zwei hartkodierter
# Telefone eine Liste. Format: "name|ip|mac;name|ip|mac;..." -- '|' als Feldtrenner (die MAC
# enthaelt selbst ':'), ';' als Listentrenner. Pro Handy laeuft EIN eigener Sampler
# (sampler-<name>.csv) UND ein eigener Core-Ping (walk-ping-<name>.csv). Default = die
# bisherigen zwei, damit alte Aufrufe unveraendert weiterlaufen.
# Der Core-Ping (5/s) erzeugt zugleich den Dauer-Downlink, der die Taschen-Handys wach haelt.
TP25_PHONES="${TP25_PHONES:-iphone|10.40.10.196|F2:62:4C:E1:AF:09;s22|10.40.10.178|2A:0D:B0:5D:AD:A7}"
declare -a PH_NAME PH_IP PH_MAC
IFS=';' read -ra _ENTRIES <<< "$TP25_PHONES"
for _e in "${_ENTRIES[@]}"; do
[[ -z "${_e//[[:space:]]/}" ]] && continue
IFS='|' read -r _n _ip _mac <<< "$_e"
[[ -n "$_n" && -n "$_ip" && -n "$_mac" ]] || { echo "TP25_PHONES-Eintrag unvollstaendig: '$_e' (erwartet name|ip|mac)" >&2; exit 2; }
PH_NAME+=("$_n"); PH_IP+=("$_ip"); PH_MAC+=("$_mac")
done
[[ ${#PH_NAME[@]} -gt 0 ]] || { echo "TP25_PHONES leer/ungueltig: '$TP25_PHONES'" >&2; exit 2; }
STATE="$RUN_DIR/phase.json"
MARKERS="$RUN_DIR/markers.csv"
HERE="$(cd "$(dirname "$0")/.." && pwd)"
@@ -34,6 +44,14 @@ HERE="$(cd "$(dirname "$0")/.." && pwd)"
mkdir -p "$RUN_DIR"
[[ -f "$MARKERS" ]] || echo "ts_epoch,ts_local,marker" > "$MARKERS"
# Client-Liste fuer die Klick-Konsole (docs/tp6-marker/server.py). Die Konsole liest sie
# ueber den .current-run-Zeiger -- so kennt sie die N Geraete auch, wenn sie als
# Dauer-Preview schon vor dem Messlauf lief. Format: name|ip|mac je Zeile.
: > "$RUN_DIR/geraete.txt"
for i in "${!PH_NAME[@]}"; do
printf '%s|%s|%s\n' "${PH_NAME[$i]}" "${PH_IP[$i]}" "${PH_MAC[$i]}" >> "$RUN_DIR/geraete.txt"
done
# Zeiger fuer die Klick-Konsole (docs/tp6-marker/server.py). Die laeuft als Dauer-Preview
# auf Port 3031 und kennt dieses Verzeichnis sonst nicht -- ihre Marker landeten dann im
# Lauf von gestern, waehrend der Sampler hierher schreibt. Beides fiel erst bei der
@@ -51,10 +69,17 @@ bash "$HERE/docs/tp25-pin-s22.sh" map > "$RUN_DIR/ap-map.txt" 2>/dev/null \
|| echo "⚠️ AP-Zuordnung konnte nicht gelesen werden -- Auswertung bleibt bei cap-wifiN"
# Frueheren Lauf beiseitelegen, statt ihn zu ueberschreiben.
if [[ -f "$RUN_DIR/sampler.csv" ]]; then
# 🔴 Seit dem N-Geraete-Umbau (2026-09-04) schreiben neue Laeufe pro Geraet
# sampler-<name>.csv / walk-ping-<name>.csv -- der alte Trigger auf die nackte sampler.csv
# haette einen Re-Run nicht mehr erkannt und den Vorlauf ueberschrieben. Legacy-Namen
# (sampler.csv/walk-ping.csv/beide-telefone.csv aus 2-Rollen-Laeufen) bleiben in der Liste.
if compgen -G "$RUN_DIR/sampler-*.csv" >/dev/null || compgen -G "$RUN_DIR/walk-ping-*.csv" >/dev/null \
|| [[ -f "$RUN_DIR/sampler.csv" ]]; then
ARCHIV="$RUN_DIR/archiv-$(date +%H%M%S)"; mkdir -p "$ARCHIV"
for f in sampler.csv markers.csv walk-ping.csv walk-ping.log ping-dauerlauf.log; do
[[ -f "$RUN_DIR/$f" ]] && mv "$RUN_DIR/$f" "$ARCHIV/"
for f in "$RUN_DIR"/sampler.csv "$RUN_DIR"/sampler-*.csv "$RUN_DIR"/sampler-*.out \
"$RUN_DIR"/markers.csv "$RUN_DIR"/walk-ping.csv "$RUN_DIR"/walk-ping-*.csv \
"$RUN_DIR"/walk-ping.log "$RUN_DIR"/ping-dauerlauf.log "$RUN_DIR"/beide-telefone.csv; do
[[ -f "$f" ]] && mv "$f" "$ARCHIV/"
done
echo "ts_epoch,ts_local,marker" > "$MARKERS"
echo "Vorheriger Lauf -> $ARCHIV"
@@ -74,9 +99,16 @@ PY
state "Kein Call nötig. <b>🚶</b> drücken, wenn du losgehst, <b>📍</b> wenn du stehen bleibst — und bitte den Weg gehen, den du beim Telefonieren wirklich gehst.<br><br>Ich pinge dein Telefon fünfmal pro Sekunde. Jeder AP- oder Bandwechsel zeigt sich dann als echter Paketverlust: <b>so lange ist der Call wirklich tot.</b><br><br>Am Ende: <b>⏹ Aufzeichnung stoppen</b>."
# Sampler am Manager (1-s-Takt, feiner als bei der TP6-Messung)
bash "$HERE/docs/tp6-monitor-core.sh" --out "$RUN_DIR/sampler.csv" --mac "$PHONE_MAC" --interval 1 \
> "$RUN_DIR/sampler.out" 2>&1 & SAMPLER=$!
# Sampler am Manager -- pro Geraet einer. 2-s-Takt: bei 4 Geraeten laufen sonst 8 SSH-Sessions
# gegen den Core-SPOF, und Signal alle 2 s reicht fuer einen Gehweg (der Ping bleibt fein bei
# 200 ms). Jeder Sampler holt sich den Core-PW selbst (docs/tp6-monitor-core.sh, SSHPASS -e).
declare -a SAMPLERS
for i in "${!PH_NAME[@]}"; do
bash "$HERE/docs/tp6-monitor-core.sh" --out "$RUN_DIR/sampler-${PH_NAME[$i]}.csv" \
--mac "${PH_MAC[$i]}" --interval 2 \
> "$RUN_DIR/sampler-${PH_NAME[$i]}.out" 2>&1 &
SAMPLERS+=("$!")
done
# 5 Pings/s auf JEDES Telefon — GEPINGT WIRD VOM CORE, nicht von diesem Rechner.
# 🔴 Der Grund: pingt der Laptop, laeuft der Weg ueber ZWEI Funkstrecken (Laptop -> AP ->
@@ -124,8 +156,11 @@ ping_lauf() {
# stdout-Pipe schliesst, und der Hintergrundjob darin haelt sie offen -- das Skript blieb
# dort stehen, der zweite Ping wurde nie gestartet (2026-08-22). Die Funktion laeuft in
# der aktuellen Shell, also liefert $! danach die richtige PID.
ping_lauf "$PHONE" "$RUN_DIR/walk-ping.csv"; PINGER=$!
ping_lauf "$PHONE2" "$RUN_DIR/walk-ping-$PHONE2_NAME.csv"; PINGER2=$!
declare -a PINGERS
for i in "${!PH_NAME[@]}"; do
ping_lauf "${PH_IP[$i]}" "$RUN_DIR/walk-ping-${PH_NAME[$i]}.csv"
PINGERS+=("$!")
done
# 🔴 Kinder ZUERST. `kill $SAMPLER` traf nur den Wrapper; dessen Subshell samt SSH-Sitzung
# wurde dabei verwaist und lief weiter -- nach dem Stopp hielt der Core stumm eine
@@ -138,9 +173,8 @@ killbaum() {
}
beenden() {
for pid in $SAMPLER $PINGER $PINGER2; do killbaum "$pid"; done
pkill -f "ping $PHONE interval=200ms" 2>/dev/null
pkill -f "ping $PHONE2 interval=200ms" 2>/dev/null
for pid in "${SAMPLERS[@]}" "${PINGERS[@]}"; do killbaum "$pid"; done
for ip in "${PH_IP[@]}"; do pkill -f "ping $ip interval=200ms" 2>/dev/null; done
# Der /ping am Router endet mit der SSH-Sitzung (am 2026-08-22 nachgeprueft: nach dem
# Kill der Sitzungen lief am Core nichts weiter). Bewusst KEIN "job remove" am Geraet --
# ein pauschales Aufraeumen fremder Jobs waere ein zu grobes Werkzeug fuer ein Messskript.
@@ -150,10 +184,12 @@ beenden() {
}
trap beenden EXIT
echo "Gehweg-Messung laeuft."
echo " Funk -> $RUN_DIR/sampler.csv"
echo " Ping -> $RUN_DIR/walk-ping.csv ($PHONE, gepinnt)"
echo " Ping -> $RUN_DIR/walk-ping-$PHONE2_NAME.csv ($PHONE2, frei roamend)"
echo "Gehweg-Messung laeuft (${#PH_NAME[@]} Geraete, alle frei roamend)."
for i in "${!PH_NAME[@]}"; do
printf ' %-9s Funk -> sampler-%s.csv Ping -> walk-ping-%s.csv (%s)\n' \
"${PH_NAME[$i]}" "${PH_NAME[$i]}" "${PH_NAME[$i]}" "${PH_IP[$i]}"
done
echo " Verzeichnis: $RUN_DIR"
echo " Stoppen: '⏹ Aufzeichnung stoppen' auf der Konsole -- oder Ctrl-C hier."
# 🔴 Bis 2026-08-22 lief hier nur `while true; do touch; sleep 5; done`, und das Skript war

View File

@@ -16,12 +16,12 @@ Zwei Aufgaben:
- Die Seite hat ein <meta refresh>. Ohne JS aktualisiert sich die Anleitung dadurch
trotzdem; laeuft JS, entfernt es das Meta-Tag und pollt stattdessen leise.
🔴 SEIT 2026-08-22 AENDERT DIESE SEITE DOCH ETWAS AM NETZ: der AP-Pin (TP25) schreibt
🔴 SEIT 2026-08-22 AENDERT DIESE SEITE DOCH ETWAS AM NETZ: der Multi-Pin (TP25) schreibt
access-list-Regeln auf den WLAN-Manager. Die Seite bindet auf 0.0.0.0 und kennt keine
Authentifizierung — wer in VLAN10 steht, kann den Pin umschalten. Das ist fuer die Dauer
einer Messung vertretbar und sonst nicht: den Server nach dem Rundgang beenden. Der Pin
selbst ist harmlos genug (er betrifft eine MAC), aber die Regel ist es nicht, die als
naechstes hier landen koennte.
Authentifizierung — wer in VLAN10 steht, kann pinnen. Das ist fuer die Dauer einer Messung
vertretbar und sonst nicht: den Server nach dem Rundgang beenden. Der Pin selbst ist
harmlos genug (er betrifft MACs), aber die Regel ist es nicht, die als naechstes hier
landen koennte.
Bindet auf 0.0.0.0 (Bedienung vom iPhone/iPad).
"""
@@ -164,6 +164,82 @@ def sampler_tail():
return {}
def geraete():
"""Liste (name, ip, mac) aus geraete.txt im Laufverzeichnis.
🔴 Die Datei schreibt tp25-walk-messung.sh beim Start des Messlaufs (eine Zeile
name|ip|mac je Client). Fehlt sie — Alt-Lauf oder Dauer-Preview, die schon vor dem
ersten Lauf lief — fallen wir auf die zwei bisherigen Geraete zurueck, damit die
Anzeige nicht leer ist. Die Namen muessen zu den sampler-<name>.csv /
walk-ping-<name>.csv passen, die die Harness schreibt.
"""
try:
zeilen = [z.strip() for z in open(_p("geraete.txt")) if z.strip()]
gs = []
for z in zeilen:
teile = z.split("|")
if len(teile) >= 3 and teile[0]:
gs.append((teile[0], teile[1], teile[2]))
if gs:
return gs
except Exception:
pass
return [("iphone", "", "F2:62:4C:E1:AF:09"), ("s22", "", "2A:0D:B0:5D:AD:A7")]
def client_tail(name):
"""Letzte Sampler-Zeile EINES Geraets (sampler-<name>.csv). Fehlt sie, ist das kein Fehler.
Gleiche Spalten wie sampler_tail() — die Harness schreibt pro Geraet einen eigenen
Sampler mit demselben Header (tp6-monitor-core.sh). Die Konsole braucht deshalb KEINE
eigene SSH-Sitzung mehr: sie liest nur, was die Sampler schon auf die Platte legen.
"""
try:
pfad = _p("sampler-%s.csv" % name)
rows = [r.strip() for r in open(pfad) if r.strip()]
if len(rows) < 2:
return {}
row = dict(zip(rows[0].split(","), rows[-1].split(",")))
return {
"age": int(time.time() - int(row.get("ts_epoch", "0"))),
"cpu": row.get("cpu", ""), "wan_rx": row.get("wan_rx_bps", ""),
"wan_tx": row.get("wan_tx_bps", ""), "iface": row.get("sta_iface", ""),
"signal": row.get("sta_signal", ""), "tx_rate": row.get("sta_tx_rate", ""),
"sta_tx_bps": row.get("sta_tx_bps", ""), "sta_rx_bps": row.get("sta_rx_bps", ""),
}
except Exception:
return {}
def ping_loss(name, n=150):
"""Ping-Verlust der letzten ~n Zeilen von walk-ping-<name>.csv (5 Pings/s -> n=150 ~ 30 s).
Leeres ms-Feld = Verlust. Liefert (verloren, gesamt) oder None, wenn noch keine Daten da
sind. Der Header (ts_local,seq,ms) wird ueber die nicht-numerische seq-Spalte uebersprungen.
"""
try:
rows = [r.strip() for r in open(_p("walk-ping-%s.csv" % name)) if r.strip()]
verloren = gesamt = 0
for z in rows[-n:]:
teile = z.split(",")
if len(teile) >= 3 and teile[1].isdigit():
gesamt += 1
if not teile[2].strip():
verloren += 1
return (verloren, gesamt) if gesamt else None
except Exception:
return None
def wan_tail():
"""WAN/CPU-Anzeige: aus sampler.csv (Alt-Lauf) oder dem ersten Geraet-Sampler."""
w = sampler_tail()
if w.get("cpu") or w.get("wan_rx"):
return w
gs = geraete()
return client_tail(gs[0][0]) if gs else {}
def kill_flows():
"""Not-Aus: Saettigungs-Flows sofort beenden."""
killed = 0
@@ -214,153 +290,104 @@ def ap_map():
return _apmap["karte"]
# 🔎 Die Messidee (Christoph, 2026-08-22): das iPhone roamt frei und zeigt damit, welchen AP
# ein normaler Client an dieser Stelle waehlt -- das wissen wir also ohnehin. Interessant
# ist der ANDERE. Deshalb wird das S22 automatisch auf den Gegen-AP gezwungen: pro Standort
# gibt es dann zwei Messpunkte statt einem, ohne zweimal zu gehen.
IPHONE_MAC = os.environ.get("TP25_IPHONE_MAC", "F2:62:4C:E1:AF:09")
S22_MAC = os.environ.get("TP25_PIN_MAC", "2A:0D:B0:5D:AD:A7")
# 🔎 Die Messidee (Christoph, 2026-08-22, generalisiert 2026-09-04): die Clients roamen frei
# und zeigen damit, welchen AP ein normaler Client an dieser Stelle waehlt. Fuer die
# Abdeckungsfrage wird je Client per access-list GENAU EIN AP+Band erlaubt
# (tp25-pin-multi.sh). Die alte Gegen-AP-Automatik (S22 folgt dem iPhone) ist damit
# ueberholt: gepinnt wird vorab band-genau, nicht mehr automatisch waehrend des Gehens.
# Was der Beobachter sieht. "" = nicht angemeldet.
_live = {"iphone": "", "iphone_sig": "", "s22": "", "s22_sig": "", "stand": 0.0}
_auto = {"an": False, "seit_weg": 0.0, "aufgegeben": ""}
PINM_SH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "tp25-pin-multi.sh")
# Pin-Zustand. Das Setzen dauert ~8 s (Regeln + Kick), deshalb laeuft es in einem Thread und
# die Seite zeigt solange "setze Pin …". pins = {name: "ap|band"} der zuletzt gesetzten Auswahl.
_pinm = {"busy": False, "msg": "", "pins": {}, "stand": 0.0}
def core_passwort():
"""Aus dem Credential-Store. Wird nie geloggt und nie in die Seite gerendert."""
with open(os.path.expanduser("~/.secrets/credentials.env")) as fh:
for zeile in fh:
if zeile.startswith("CRS326_CORE_PASS="):
return zeile.split("=", 1)[1].strip().strip("\"'")
raise RuntimeError("CRS326_CORE_PASS nicht gefunden")
def pin_targets():
"""Eindeutige (ap, band)-Paare aus der Live-Karte, band-normalisiert fuer tp25-pin-multi.sh.
def _ap_von(iface):
return ap_map().get(iface, "").split(" /")[0]
def beobachter():
"""Haelt EINE SSH-Sitzung offen und liest beide Telefone im 2-s-Takt.
🔴 Bewusst kein Poll mit je einem ssh-Aufruf: das waeren ueber einen Rundgang mehrere
hundert Verbindungsaufbauten, jeder ~1 s. Dasselbe Muster wie tp6-monitor-core.sh --
inklusive Reconnect-Schleife, weil die Sitzung am 2026-08-21 mitten in einer Messung
weggebrochen ist und die Daten still endeten.
ap_map() liefert 'apX / 5 GHz' bzw. 'apX / 2,4 GHz'; das Skript erwartet Band '5' oder '24'.
"""
# 🔴 KEINE Klammern um die :while-Schleife -- "(:while ...)" laesst RouterOS die
# Sitzung wortlos beenden, und mit stderr auf DEVNULL sieht man nur, dass alle 3 s
# ein neuer ssh startet. Genau so lag der Beobachter am 2026-08-22 tot.
ros = (':while (true) do={'
':local a [/interface/wifi/registration-table find where mac-address="%s"];'
':local b [/interface/wifi/registration-table find where mac-address="%s"];'
':local ai ""; :local as2 ""; :local bi ""; :local bs "";'
':if ([:len $a] > 0) do={:set ai [/interface/wifi/registration-table get [:pick $a 0] interface];'
':set as2 [/interface/wifi/registration-table get [:pick $a 0] signal]};'
':if ([:len $b] > 0) do={:set bi [/interface/wifi/registration-table get [:pick $b 0] interface];'
':set bs [/interface/wifi/registration-table get [:pick $b 0] signal]};'
':put ($ai . "," . $as2 . "," . $bi . "," . $bs); :delay 2s;}'
% (IPHONE_MAC, S22_MAC))
while True:
try:
pw = core_passwort()
# 🔴 sshpass -e statt -p: bei -p steht das Router-Passwort in der KOMMANDOZEILE
# und damit in `ps`, in jedem Prozess-Trace und in jeder Debug-Ausgabe, die
# argv anfasst. Am 2026-08-22 ist es genau so im Klartext in einem Trace
# gelandet. Mit -e liegt es nur in der Umgebung dieses einen Kindprozesses.
umgebung = dict(os.environ, SSHPASS=pw)
proc = subprocess.Popen(
["sshpass", "-e", "ssh", "-o", "StrictHostKeyChecking=no",
"-o", "ConnectTimeout=8", "-o", "ServerAliveInterval=15",
"admin@10.40.99.1", ros],
stdout=subprocess.PIPE, stderr=open(_p("beobachter.log"), "a"),
text=True, bufsize=1, env=umgebung)
# 🔴 NICHT `for zeile in proc.stdout`: die Iteration eines Pipes liest blockweise
# vor, die Zeilen kommen also erst an, wenn ~4 KB beisammen sind -- bei einer
# Zeile alle 2 s waere das eine Stunde. readline() liefert sofort.
for zeile in iter(proc.stdout.readline, ""):
teile = zeile.strip().split(",")
if len(teile) != 4:
ziele, gesehen = [], set()
for wert in ap_map().values():
ap, _, band = wert.partition(" / ")
band = band.replace(" GHz", "").replace(",", ".")
if band.startswith("5"):
band = "5"
elif band.startswith("2"):
band = "24"
else:
continue
_live.update(iphone=teile[0], iphone_sig=teile[1],
s22=teile[2], s22_sig=teile[3], stand=time.time())
# 🔴 Bis 2026-08-22 blieben diese Zahlen NUR im Speicher, fuer die Anzeige.
# Nach dem Rundgang fehlte deshalb die halbe Messung: das S22 sitzt per
# Automatik immer auf dem Gegen-AP, die Alltagsabdeckung zeigt das iPhone
# -- und genau dessen Zeitreihe war weg. Nachtraeglich liess sich nur das
# Roaming-Log am Manager retten: Ereignisse, keine Kurve.
mitschreiben(teile)
entscheide()
except Exception as e:
# Ein Beobachter, der still stirbt, ist schlimmer als keiner (Lehre aus dem
# Sampler-Abbruch am 2026-08-21). Also mitschreiben statt schlucken.
try:
with open(_p("beobachter.log"), "a") as fh:
fh.write("%s %s: %s\n" % (time.strftime("%H:%M:%S"), type(e).__name__, e))
except Exception:
pass
time.sleep(3)
if (ap, band) not in gesehen:
gesehen.add((ap, band))
ziele.append((ap, band))
return sorted(ziele)
def mitschreiben(teile):
"""Beide Telefone im 2-s-Takt in den Lauf schreiben: iface + Signal je Geraet."""
try:
pfad = _p("beide-telefone.csv")
frisch = not os.path.exists(pfad) or os.path.getsize(pfad) == 0
with open(pfad, "a") as fh:
if frisch:
fh.write("ts_epoch,ts_local,iphone_iface,iphone_sig,s22_iface,s22_sig\n")
fh.write("%d,%s,%s\n" % (time.time(), time.strftime("%H:%M:%S"), ",".join(teile)))
except Exception:
pass
def build_spec(form):
"""Aus den Formular-Auswahlen (pin_<name>=ap|band oder frei) den TP25_PINSPEC-String bauen.
Clients ohne Ziel (frei) bleiben frei — tp25-pin-multi.sh set raeumt vorher alle
TP25-PINM-*-Regeln ab und setzt nur die hier genannten.
"""
eintraege = []
for name, _ip, mac in geraete():
wert = (form.get("pin_%s" % name) or ["frei"])[0]
if wert and wert != "frei" and "|" in wert:
ap, band = wert.split("|", 1)
eintraege.append("%s|%s|%s|%s" % (name, mac, ap, band))
return ";".join(eintraege)
def entscheide():
"""Gegen-AP setzen, sobald das iPhone den AP wechselt."""
if not _auto["an"] or _pin["busy"]:
return
ip_ap = _ap_von(_live["iphone"])
if ip_ap not in ("ap1", "ap2"):
return # iPhone selbst nicht angemeldet -> nichts zu spiegeln
gegen = "ap1" if ip_ap == "ap2" else "ap2"
if pin_lesen() != gegen:
_auto["aufgegeben"] = ""
_auto["seit_weg"] = time.time()
pin_setzen(gegen)
def pinm_aktion(spec):
"""Pin setzen (spec = 'name|mac|ap|band;...') oder loesen (spec = ''). Laeuft im Thread."""
pins = {}
for e in (spec.split(";") if spec else []):
teile = e.split("|")
if len(teile) >= 4:
pins[teile[0]] = "%s|%s" % (teile[2], teile[3])
# Pin-Zustand. Das Umschalten dauert ~8 s (Regeln + Kick + Nachlesen), deshalb laeuft es
# in einem Thread und die Seite zeigt solange "schaltet um".
_pin = {"ziel": None, "busy": False, "msg": "", "stand": 0.0}
def pin_lesen():
if _pin["busy"] or time.time() - _pin["stand"] < 20:
return _pin["ziel"]
try:
_pin["ziel"] = subprocess.run(["bash", PIN_SH, "which"], capture_output=True,
text=True, timeout=20).stdout.strip() or None
_pin["stand"] = time.time()
except Exception:
pass
return _pin["ziel"]
def pin_setzen(ziel):
def lauf():
try:
r = subprocess.run(["bash", PIN_SH, ziel], capture_output=True, text=True, timeout=60)
_pin["msg"] = (r.stdout.strip().splitlines() or [""])[0]
umgebung = dict(os.environ)
if spec:
umgebung["TP25_PINSPEC"] = spec
r = subprocess.run(["bash", PINM_SH, "set"], capture_output=True, text=True,
timeout=90, env=umgebung)
else:
r = subprocess.run(["bash", PINM_SH, "off"], capture_output=True, text=True,
timeout=90)
_pinm["msg"] = r.stdout.strip() or r.stderr.strip() or "ok"
except Exception as e:
_pin["msg"] = "Fehler: %s" % e
_pinm["msg"] = "Fehler: %s" % e
finally:
_pin["busy"] = False
_pin["stand"] = 0.0
pin_lesen()
_pin["busy"] = True
_pin["msg"] = "schaltet um …"
_pinm["busy"] = False
_pinm["stand"] = time.time()
_pinm["busy"] = True
_pinm["msg"] = "setze Pin …" if spec else "löse Pin …"
_pinm["pins"] = pins
# Der Klick gehoert in dieselbe Zeitachse wie alles andere — sonst laesst sich hinterher
# nicht sagen, welche Messpunkte zu welchem AP gehoeren.
write_marker("PIN=%s" % ziel)
# nicht sagen, welche Messpunkte zu welchem Pin gehoeren.
write_marker("PINM=%s" % (spec or "off"))
threading.Thread(target=lauf, daemon=True).start()
def pinm_verify():
"""tp25-pin-multi.sh verify im Thread — zeigt Regeln + aktuelle Anmeldungen."""
def lauf():
try:
r = subprocess.run(["bash", PINM_SH, "verify"], capture_output=True, text=True,
timeout=60)
_pinm["msg"] = r.stdout.strip() or r.stderr.strip() or "ok"
except Exception as e:
_pinm["msg"] = "Fehler: %s" % e
finally:
_pinm["busy"] = False
_pinm["stand"] = time.time()
_pinm["busy"] = True
_pinm["msg"] = "prüfe …"
threading.Thread(target=lauf, daemon=True).start()
@@ -391,27 +418,42 @@ def fmt_bps(v):
def render(st):
w = sampler_tail()
w = wan_tail()
rest = max(0, int(st.get("ends", 0) - time.time())) if st.get("ends") else 0
mode = st.get("mode", "wartet")
banner = ""
alarm = False # nur DIESER Zustand loest Ton + Vibration aus, nicht jeder Banner
# 🔴 Der wichtigste Alarm der Seite, seit es den AP-Pin gibt (2026-08-22): ein vom Pin
# ABGEWIESENER Verbindungsversuch ist in den Ping-Daten nicht von einem Funkloch zu
# unterscheiden -- und der Manager protokolliert die Abweisung auf info-Ebene nicht.
# Android quittiert sie mit "Verbindung fehlgeschlagen" und WAEHLT DAS NETZ AB, danach
# misst der restliche Rundgang nur noch Stille. Deshalb wird "haengt nirgends" hier
# nicht klein in der WLAN-Zeile gezeigt, sondern schreit.
if pin_lesen() in ("ap1", "ap2") and w.get("iface") == "absent" and w.get("age", 999) < 30:
haengende = []
# 🔴 Der wichtigste Alarm der Seite, seit es den Pin gibt (2026-08-22, generalisiert
# 2026-09-04): ein vom Pin ABGEWIESENER Verbindungsversuch ist in den Ping-Daten nicht
# von einem Funkloch zu unterscheiden -- und der Manager protokolliert die Abweisung auf
# info-Ebene nicht. Android quittiert sie mit "Verbindung fehlgeschlagen" und WAEHLT DAS
# NETZ AB, danach misst der restliche Rundgang nur noch Stille. Deshalb wird "haengt
# nirgends" hier nicht klein in der Client-Zeile gezeigt, sondern schreit.
clients = []
for name, ip, mac in geraete():
t = client_tail(name)
pl = ping_loss(name)
iface = t.get("iface", "")
ap = ap_map().get(iface, iface) if iface else ""
signal = t.get("signal", "")
frisch = t.get("age", 999) < 30
gepinnt = name in _pinm["pins"]
if gepinnt and iface == "absent" and frisch:
alarm = True
banner = ('<div class="banner warn">📵 S22 HÄNGT NIRGENDS — Display an und wieder auf '
'dirtyvader-main verbinden. Der Pin wirft es vom gesperrten AP; Android '
'wählt das Netz dann von selbst ab. <b>Nicht weitergehen</b>, sonst misst '
'du Stille statt Abdeckung.</div>')
haengende.append(name)
clients.append((name, ip, mac, iface, ap, signal, pl, frisch, gepinnt))
if haengende:
banner = ('<div class="banner warn">📵 <b>%s</b> HÄNGT NIRGENDS — der Pin wirft das '
'Geraet vom gesperrten AP; Android waehlt das Netz dann von selbst ab. '
'<b>Nicht weitergehen</b>, sonst misst du Stille statt Abdeckung.</div>'
% ", ".join(haengende))
elif not st.get("driver"):
banner = ('<div class="banner done">ℹ️ Keine Ping-Aufzeichnung — Räume markieren und '
'AP-Pin gehen trotzdem. Für die Messkurve <b>tp25-walk-messung.sh</b> starten.</div>')
'pinnen geht trotzdem. Für die Messkurve <b>tp25-walk-messung.sh</b> starten.</div>')
elif mode == "langzeit":
banner = ('<div class="banner done">✅ MESSUNG ABGESCHLOSSEN — die Zahlen liegen vor. '
'Ab jetzt läuft nur noch die Langzeit-Aufzeichnung.</div>')
@@ -423,86 +465,65 @@ def render(st):
countdown = ('<div class="cd" id="cd" data-ends="%d">noch ~%d s</div>' % (st.get("ends", 0), rest)
if rest else '<div class="cd" id="cd" data-ends="0"></div>')
wlan = "—"
if w.get("iface"):
wlan = "%s · %s dBm · tx %s / rx %s" % (
ap_map().get(w["iface"], w["iface"]), w.get("signal", "?"),
fmt_bps(w.get("sta_tx_bps")), fmt_bps(w.get("sta_rx_bps")))
ziel = pin_lesen()
ip_ap, s22_ap = _ap_von(_live["iphone"]), _ap_von(_live["s22"])
frisch = time.time() - _live["stand"] < 15
# Drei Zustaende, nicht zwei. "S22 kommt nicht rein" ist ein ERGEBNIS (der Gegen-AP
# traegt hier nicht), kein Defekt -- es darf deshalb nicht wie ein Fehler aussehen und
# nicht ewig Alarm schlagen.
# 🔴 "beide angemeldet" ist NICHT das Kriterium -- der Messpunkt taugt nur, wenn die
# beiden Telefone auf VERSCHIEDENEN APs sitzen. Am 2026-08-22 meldete die Seite
# "✅ beide angemeldet, auf verschiedenen APs", waehrend beide auf ap2 hingen: ein
# gruenes Licht fuer eine Messung, die es gar nicht gab. Wieder derselbe Fehler --
# die Anzeige geprueft statt der Wirkung.
getrennt = bool(ip_ap and s22_ap and ip_ap != s22_ap)
bereit = bool(frisch and getrennt)
gleich = bool(frisch and ip_ap and s22_ap and ip_ap == s22_ap)
wartet = bool(frisch and ip_ap and not s22_ap and not _auto["aufgegeben"])
if wartet and _auto["seit_weg"] and time.time() - _auto["seit_weg"] > 45:
_auto["aufgegeben"] = ziel or "?"
write_marker("UNERREICHBAR=%s" % (ziel or "?"))
wartet = False
def z(ap, sig, mac_name):
if not frisch:
return "%s: —" % mac_name
return ("%s: <b>%s</b> %s dBm" % (mac_name, ap, sig)) if ap else ("%s: <b>nirgends</b>" % mac_name)
doppel = "%s &nbsp;·&nbsp; %s" % (z(ip_ap, _live["iphone_sig"], "iPhone"),
z(s22_ap, _live["s22_sig"], "S22"))
if _pin["busy"]:
pinstatus = "⏳ %s<br>%s" % (_pin["msg"], doppel)
elif _auto["aufgegeben"]:
pinstatus = ("🚫 S22 bekommt <b>%s</b> hier nicht — <b>das ist das Messergebnis</b>, "
"Raum markieren und weitergehen.<br>%s" % (_auto["aufgegeben"], doppel))
elif bereit:
pinstatus = "✅ beide angemeldet, <b>verschiedene APs</b> — Messpunkt zählt<br>%s" % doppel
elif gleich and _auto["an"]:
pinstatus = ("⏳ beide auf <b>%s</b> — Gegen-AP wird gerade nachgezogen, "
"noch nicht weitergehen<br>%s" % (ip_ap, doppel))
elif gleich:
pinstatus = ("⚠️ beide auf <b>%s</b> — <b>kein Gegen-AP-Messpunkt.</b> "
"Automatik einschalten oder S22 von Hand pinnen.<br>%s" % (ip_ap, doppel))
elif wartet:
pinstatus = "⏳ S22 sucht <b>%s</b> …<br>%s" % (ziel or "?", doppel)
elif ziel in ("ap1", "ap2"):
pinstatus = "S22 gepinnt auf <b>%s</b><br>%s" % (ziel, doppel)
elif ziel == "off":
pinstatus = "kein Pin — S22 roamt frei<br>%s" % doppel
# Client-Karten: je Geraet Name, AP+Signal, Ping-Verlust der letzten ~30 s.
karten = ""
for name, ip, mac, iface, ap, signal, pl, frisch, gepinnt in clients:
if iface and iface != "absent":
status = ("%s · %s dBm" % (ap, signal)) if signal else ap
elif iface == "absent":
status = "<b>nirgends</b>"
else:
pinstatus = "Zustand unbekannt (Manager nicht erreichbar?)"
pinkarte = (
'<div class="card"><span id="sig" data-alarm="%d" data-busy="%d" data-pin="%s" '
'data-bereit="%d"></span>'
'<div class="phase">AP-Pin S22</div>'
'<div class="inst" id="pininst">%s</div><div class="raster">'
'<form method="post" action="/pin?ap=ap1" onsubmit="return sendpin(event,\'ap1\')">'
'<button class="raum%s" type="submit">ap1</button></form>'
'<form method="post" action="/pin?ap=ap2" onsubmit="return sendpin(event,\'ap2\')">'
'<button class="raum%s" type="submit">ap2</button></form>'
'</div>'
'<form method="post" action="/auto" onsubmit="return sendauto(event)">'
'<button class="%s" style="margin-top:8px" type="submit">%s</button></form>'
'<form method="post" action="/pin?ap=off" onsubmit="return sendpin(event,\'off\')">'
'<button class="cam" style="margin-top:8px" type="submit">Pin lösen</button></form>'
'</div>' % (1 if alarm else 0, 1 if _pin["busy"] else 0, ziel or "?",
1 if bereit else 0,
pinstatus,
" hier" if ziel == "ap1" else "",
" hier" if ziel == "ap2" else "",
"ok" if _auto["an"] else "cam",
"🔁 Gegen-AP: AN (folgt dem iPhone)" if _auto["an"]
else "🔁 Gegen-AP automatisch",
)
)
status = "—"
if pl:
verloren, gesamt = pl
ping = "%d/%d verloren" % (verloren, gesamt)
else:
ping = "—"
karten += ('<div class="card"><div class="phase">%s</div>'
'<div class="inst"><b>%s</b></div>'
'<div class="cval">%s</div>'
'<div class="cval">Ping: %s</div></div>'
% ("📌 gepinnt" if gepinnt else "Client", name, status, ping))
# Pin-UI: je Client ein Ziel-Dropdown, dazu setzen/loesen/verify.
ziele = pin_targets()
def optionen(aktuell):
out = ['<option value="frei"%s>frei</option>' % (" selected" if aktuell == "frei" else "")]
for ap, band in ziele:
wert = "%s|%s" % (ap, band)
label = "%s / %s GHz" % (ap, "5" if band == "5" else "2,4")
out.append('<option value="%s"%s>%s</option>'
% (wert, " selected" if wert == aktuell else "", label))
return "".join(out)
zeilen = ""
for name, ip, mac in geraete():
zeilen += ('<div class="pinzeile"><label>%s</label>'
'<select name="pin_%s">%s</select></div>'
% (name, name, optionen(_pinm["pins"].get(name, "frei"))))
if _pinm["busy"]:
pinstatus = "⏳ %s" % _pinm["msg"].replace("\n", "<br>")
elif _pinm["msg"]:
pinstatus = _pinm["msg"].replace("\n", "<br>")
elif not ziele:
pinstatus = "Manager nicht erreichbar — keine Pin-Ziele."
else:
pinstatus = "Je Client AP/Band wählen, dann „Pin setzen“."
pinm_karte = (
'<div class="card"><span id="sig" data-alarm="%d" data-busy="%d"></span>'
'<div class="phase">Pinnen (Multi-Pin)</div>'
'<div class="inst" id="pininst">%s</div>'
'<form method="post" action="/pinmulti" onsubmit="return sendpinm(event)">'
'%s'
'<button class="ok" type="submit">📌 Pin setzen</button></form>'
'<form method="post" action="/pinmulti?off=1" onsubmit="return sendpinmoff(event)">'
'<button class="cam" type="submit">Pin lösen</button></form>'
'<form method="post" action="/pinmulti?verify=1" onsubmit="return sendpinmoff(event)">'
'<button class="cam" type="submit">verify</button></form>'
'</div>' % (1 if alarm else 0, 1 if _pinm["busy"] else 0, pinstatus, zeilen))
raum, seit = current_room()
# 🔴 Die Kacheln hingen bis 2026-08-22 am Treiber-Zustand -- ohne laufenden TP6-Treiber
@@ -547,7 +568,8 @@ def render(st):
return PAGE.format(
banner=banner, title=st.get("title", "—"), phase=st.get("phase", "—"),
instruction=st.get("instruction", ""), prog=prog, countdown=countdown,
raumzeile=raumzeile, pinkarte=pinkarte, wlan=wlan, wan="rx %s / tx %s · CPU %s%%" % (fmt_bps(w.get("wan_rx")),
raumzeile=raumzeile, clients=karten, pinm_karte=pinm_karte,
wan="rx %s / tx %s · CPU %s%%" % (fmt_bps(w.get("wan_rx")),
fmt_bps(w.get("wan_tx")), w.get("cpu", "?")),
last=last_marker(), buttons=btns, notaus=notaus,
)
@@ -579,6 +601,11 @@ button:active{{filter:brightness(1.3)}}
.raster form{{margin:0}}
.raum{{margin:0;padding:16px 8px;font-size:16px;background:#1e3a5f}}
.raum.hier{{background:#0ea5e9;color:#06202e;box-shadow:0 0 0 3px #7dd3fc inset}}
.cval{{font:14px/1.6 ui-monospace,Menlo,monospace;color:#9aa4b2;margin-top:2px}}
.pinzeile{{display:flex;align-items:center;gap:10px;margin:8px 0}}
.pinzeile label{{flex:0 0 90px;font-weight:600}}
.pinzeile select{{flex:1;padding:10px;font-size:16px;background:#262b34;color:#e8eaed;
border:1px solid #2a2f3a;border-radius:8px}}
form{{margin:0}}
</style>
{banner}
@@ -589,10 +616,10 @@ form{{margin:0}}
{countdown}
{prog}
</div>
{pinkarte}
{clients}
{pinm_karte}
{raumzeile}
<div class="live">WLAN {wlan}
WAN {wan}
<div class="live">WAN {wan}
Marker {last}</div>
{buttons}
{notaus}
@@ -638,18 +665,10 @@ function alarmton(){{ ton(880,180,0); ton(660,180,0.24); ton(880,260,0.48);
function okton(){{ ton(1320,90,0); ton(1760,120,0.11);
try{{ navigator.vibrate && navigator.vibrate(90); }}catch(e){{}} }}
function bereitton(){{ ton(1180,110,0); ton(1580,150,0.13);
try{{ navigator.vibrate && navigator.vibrate([60,60,60]); }}catch(e){{}} }}
var letzterAlarm = 0, letzterBusy = 0, letzterBereit = 0, alarmTimer = null;
var letzterAlarm = 0, letzterBusy = 0, alarmTimer = null;
function signale(){{
var sig = document.getElementById('sig'); if(!sig) return;
var alarm = sig.dataset.alarm === '1', busy = sig.dataset.busy === '1';
var bereit = sig.dataset.bereit === '1';
// Der Piep, auf den Christoph wartet: beide Telefone haengen, auf verschiedenen APs --
// der Messpunkt ist vollstaendig, weitergehen. Nur bei ZUSTANDSWECHSEL, nicht dauernd.
if(bereit && !letzterBereit) bereitton();
letzterBereit = bereit ? 1 : 0;
if(alarm && !letzterAlarm){{
alarmton();
// Solange nichts geschieht, alle 12 s erinnern -- ein einmaliger Piep in der Hosentasche
@@ -657,7 +676,7 @@ function signale(){{
if(!alarmTimer) alarmTimer = setInterval(alarmton, 12000);
}}
if(!alarm && alarmTimer){{ clearInterval(alarmTimer); alarmTimer = null; }}
if(!busy && letzterBusy) okton(); // Umschalten fertig
if(!busy && letzterBusy) okton(); // Pin-Aktion fertig
letzterAlarm = alarm ? 1 : 0; letzterBusy = busy ? 1 : 0;
}}
@@ -672,28 +691,22 @@ function sendstop(ev){{
return false;
}}catch(e){{ return true; }}
}}
function sendauto(ev){{
function sendpinm(ev){{
try{{
ev.preventDefault(); unlock(); okton();
fetch('/auto', {{method:'POST'}}).catch(function(){{}});
setTimeout(refresh, 400); setTimeout(refresh, 3000);
var inst = document.getElementById('pininst');
if(inst) inst.innerHTML = '⏳ setze Pin …<br>Gepinnte Geräte fliegen kurz aus dem WLAN und verbinden sich neu.';
var fd = new FormData(ev.target);
fetch('/pinmulti', {{method:'POST', body: new URLSearchParams(fd)}}).catch(function(){{}});
setTimeout(refresh, 3000); setTimeout(refresh, 9000); setTimeout(refresh, 20000);
return false;
}}catch(e){{ return true; }}
}}
function sendpin(ev, ap){{
function sendpinmoff(ev){{
try{{
ev.preventDefault(); unlock();
// 🔴 Der Klick kommt vom S22 SELBST -- also von genau dem Geraet, das der Pin gleich vom
// WLAN wirft. Die Antwort auf dieses fetch() kommt deshalb womoeglich nie an, und die
// Seite kann sich nicht mehr nachladen. Die Anweisung muss JETZT auf dem Schirm
// stehen, solange die Verbindung noch steht.
var inst = document.getElementById('pininst');
if(inst) inst.innerHTML = '⏳ schalte auf <b>' + ap + '</b> …<br>' +
'<b>Dieses Telefon fliegt jetzt aus dem WLAN.</b> Wenn die Seite haengt: in den ' +
'WLAN-Einstellungen wieder auf <b>dirtyvader-main</b> verbinden, dann laedt sie von selbst.';
okton();
fetch('/pin?ap=' + encodeURIComponent(ap), {{method:'POST'}}).catch(function(){{}});
setTimeout(refresh, 3000); setTimeout(refresh, 9000); setTimeout(refresh, 20000);
ev.preventDefault(); unlock(); okton();
fetch(ev.target.action, {{method:'POST'}}).catch(function(){{}});
setTimeout(refresh, 3000); setTimeout(refresh, 9000);
return false;
}}catch(e){{ return true; }}
}}
@@ -767,37 +780,27 @@ class Handler(BaseHTTPRequestHandler):
self._send(200, json.dumps({"ok": True})) if "text/html" not in (
self.headers.get("Accept") or "") else self._back()
return
if self.path.startswith("/auto"):
# Ohne Parameter umschalten (das macht der Knopf), mit ?an=0|1 gezielt setzen --
# tp25-runde.sh schaltet damit beim Start scharf. Ein Toggle waere dort falsch:
# laeuft die Konsole schon mit Automatik, haette der Start sie AUSgeschaltet.
if "an=" in self.path:
_auto["an"] = self.path.split("an=", 1)[1].split("&")[0] in ("1", "true", "an")
else:
_auto["an"] = not _auto["an"]
_auto["aufgegeben"] = ""
_auto["seit_weg"] = time.time()
write_marker("AUTO=%s" % ("an" if _auto["an"] else "aus"))
if _auto["an"]:
entscheide()
if self.path.startswith("/pinmulti"):
if _pinm["busy"]:
if "text/html" in (self.headers.get("Accept") or ""):
self._back()
else:
self._send(200, json.dumps({"ok": True, "auto": _auto["an"]}))
return
if self.path.startswith("/pin?"):
ap = urllib.parse.unquote(self.path.split("ap=", 1)[1].split("&")[0])
if ap not in ("ap1", "ap2", "off"):
self._send(400, json.dumps({"error": "ap muss ap1, ap2 oder off sein"}))
return
if _pin["busy"]:
self._send(409, json.dumps({"error": "laeuft schon"}))
return
pin_setzen(ap)
qs = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query)
if qs.get("off"):
pinm_aktion("")
elif qs.get("verify"):
pinm_verify()
else:
laenge = int(self.headers.get("Content-Length") or 0)
body = self.rfile.read(laenge).decode("utf-8") if laenge else ""
form = urllib.parse.parse_qs(body)
pinm_aktion(build_spec(form))
if "text/html" in (self.headers.get("Accept") or ""):
self._back()
else:
self._send(200, json.dumps({"ok": True, "ziel": ap}))
self._send(200, json.dumps({"ok": True}))
return
if self.path.startswith("/m?"):
# 🔴 Erst dekodieren, dann NICHT hochschreiben: "RAUM%3DDiele%20OG" wurde sonst zu
@@ -836,8 +839,7 @@ if __name__ == "__main__":
print("Marker -> %s" % markers_pfad())
for iface, wo in sorted(ap_map().items()):
print(" %-14s %s" % (iface, wo))
threading.Thread(target=beobachter, daemon=True).start()
# 🔴 Threading ist Pflicht, seit der Pin dazugekommen ist: das Umschalten redet ueber SSH
# 🔴 Threading ist Pflicht, seit der Pin dazugekommen ist: das Setzen redet ueber SSH
# mit dem Manager und braucht ~8 s. Mit dem alten HTTPServer (single-threaded) haette
# das die ganze Konsole blockiert -- inklusive Not-Aus.
ThreadingHTTPServer(("0.0.0.0", PORT), Handler).serve_forever()

View File

@@ -0,0 +1,7 @@
/interface bridge vlan set [find where vlan-ids=10 and !dynamic] tagged=ether1,ether3,ether8,ether13,ether15
/interface bridge vlan set [find where vlan-ids=20 and !dynamic] tagged=ether3,ether8,ether13,ether15
/interface bridge vlan set [find where vlan-ids=30 and !dynamic] tagged=ether1,ether3,ether8,ether15
/interface bridge vlan set [find where vlan-ids=40 and !dynamic] tagged=ether1,ether3,ether8,ether13,ether15 untagged=ether2,ether4,ether5
/interface bridge vlan set [find where vlan-ids=50 and !dynamic] tagged=ether1,ether3,ether8,ether15
/interface bridge vlan set [find where vlan-ids=90 and !dynamic] tagged=ether1,ether3,ether8,ether15
/interface bridge vlan set [find where vlan-ids=99 and !dynamic] tagged=ether3,ether8,ether15,bridge

View File

@@ -0,0 +1,15 @@
{
"change_id": "TEST-ether3-trunk-ap1-sideboard-2",
"device": "crs326-core",
"scope": "bridge-vlan",
"match_config": [
"/interface bridge vlan"
],
"reason": "ap1 testweise am Sideboard, Uplink auf ether3 (Messung TP25)",
"started": "2026-09-03",
"expires": "2026-09-10",
"state": "committed",
"snapshot": "docs/transaktionen/TEST-ether3-trunk-ap1-sideboard-2.snapshot.rsc",
"device_backup": "",
"closed": "2026-09-03"
}

View File

@@ -0,0 +1,15 @@
# Snapshot des Scopes 'bridge-vlan' auf crs326-core, 2026-09-03 (Transaktion TEST-ether3-trunk-ap1-sideboard-2)
# Bewusst NUR dieser Abschnitt — der Vollexport gehoert nicht ins Repo.
/interface bridge vlan
add bridge=bridge untagged=ether1,ether2 vlan-ids=1
add bridge=bridge tagged=ether1,ether8,ether13,ether15,ether21 vlan-ids=10
add bridge=bridge tagged=ether8,ether13,ether15,ether21 vlan-ids=20
add bridge=bridge tagged=ether1,ether8,ether15,ether21 untagged=ether14 \
vlan-ids=30
add bridge=bridge tagged=ether1,ether8,ether13,ether15,ether21 untagged=\
ether2,ether3,ether4,ether5 vlan-ids=40
add bridge=bridge tagged=ether1,ether8,ether15,ether21 vlan-ids=50
add bridge=bridge tagged=ether1,ether8,ether15,ether21 vlan-ids=90
add bridge=bridge tagged=ether8,ether15,ether21,bridge vlan-ids=99
add bridge=bridge tagged=ether1 untagged=ether16 vlan-ids=100

View File

@@ -0,0 +1,8 @@
# TP25 — sec-main zurueck auf ft=yes / ft-over-ds=yes (Ruecknahme der 09-04-Entscheidung "ft=no als Dauerzustand")
# Go: Christoph 2026-09-14 ("go fuer ft=yes, dry-run vorlegen"), Terrasse-In-situ-Session
# Anlass: 2 Call-Aussetzer + ~30 Roams in 25 min — mit ft=no ist jeder Roam (Band- und AP-Wechsel)
# eine Voll-Reassoziation in Sekundenhoehe; genau darin sterben Anrufe.
# Nachweis, dass ft-over-ds=yes + 7.24.1 ruhig ist: Fund-E-Abschlussmessung 09-02 (4 reauth/8,6 h, 0 Ausfaelle).
# Nur am Manager noetig: sec-main wird per CAPsMAN an alle CAPs verteilt (Uniformitaet per Konstruktion);
# Inline-Overrides je CAP gibt es seit dem ap3-Fix 09-04 nicht mehr — Abnahme prueft sie trotzdem (Merkregel).
/interface wifi security set sec-main ft=yes ft-over-ds=yes

View File

@@ -0,0 +1,19 @@
# Live gesetzt am crs326-core 2026-09-03 (via MikroMCP run_command).
# Zwei Scopes betroffen; die Akte fuehrt formell nur wifi-channel — die zwei
# Provisioning-Adds sind hier mit-dokumentiert, weil das begin-Skript nur einen
# Scope je offener Akte kennt und sie inhaltlich zum selben Test gehoeren.
# Beim Commit gehoert BEIDES ins Template (nautobot/mikrotik_routeros.j2):
# - Zeilen 206-207: frequency=5180/5220 -> Frequenz-Liste 5260,5280 / 5300,5320
# - Zeilen 236f: neue Provisioning-Regeln fuer ap1 (radio-mac E5=5G, E6=2G)
# --- Scope wifi-channel ---
/interface wifi channel set [find name=ch-5g-ap1] frequency=5260,5280
/interface wifi channel set [find name=ch-5g-ap2] frequency=5300,5320
# --- Scope wifi-provisioning (mit-dokumentiert, nicht formell im scope der Akte) ---
/interface wifi provisioning add radio-mac=D0:EA:11:4D:40:E5 action=create-dynamic-enabled master-configuration=cfg-main-5g-ap1 slave-configurations=cfg-media,cfg-untrusted,cfg-guest comment="ap1 5GHz"
/interface wifi provisioning add radio-mac=D0:EA:11:4D:40:E6 action=create-dynamic-enabled master-configuration=cfg-main-2g-ap1 slave-configurations=cfg-iot,cfg-media,cfg-untrusted,cfg-guest comment="ap1 2.4GHz"
# Anschliessend am Manager:
/interface wifi capsman remote-cap provision [find where identity=ap1]
/interface wifi capsman remote-cap provision [find where identity=ap2]

View File

@@ -0,0 +1,15 @@
{
"change_id": "TP25-kanalplan-ap1-live",
"device": "crs326-core",
"scope": "wifi-channel",
"match_config": [
"/interface wifi channel"
],
"reason": "TP25-Kanalplan live: ap1=5260/5280, ap2=5300/5320 (DFS Band B). Testet den Zielzustand nach TP25 (dritter AP + ap2-Umverteilung) am tatsaechlichen Aufstellort. Bei ok: Template auf Frequenz-Listen umstellen und committen. Bei nicht ok: zurueck auf 5180/5220 (Snapshot).",
"started": "2026-09-03",
"expires": "2026-09-10",
"state": "committed",
"snapshot": "docs/transaktionen/TP25-kanalplan-ap1-live.snapshot.rsc",
"device_backup": "",
"closed": "2026-09-04"
}

View File

@@ -0,0 +1,10 @@
# Snapshot des Scopes 'wifi-channel' auf crs326-core, 2026-09-03 (Transaktion TP25-kanalplan-ap1-live)
# Bewusst NUR dieser Abschnitt — der Vollexport gehoert nicht ins Repo.
/interface wifi channel
add band=5ghz-ax frequency=5260,5280 name=ch-5g-ap1 width=20/40mhz
add band=5ghz-ax frequency=5300,5320 name=ch-5g-ap2 width=20/40mhz
add band=2ghz-ax frequency=2412 name=ch-2g-ap1 width=20mhz
add band=2ghz-ax frequency=2462 name=ch-2g-ap2 width=20mhz
add band=5ghz-ax frequency=5180 name=ch-5g-ap3 width=20/40mhz
add band=2ghz-ax frequency=2437 name=ch-2g-ap3 width=20mhz

View File

@@ -0,0 +1,10 @@
# TP25 — 5G bricht frueher zur 2.4G ab (Terrasse sass am Rundgang 09-15 auf der -80/5G-Kante)
# Go: Christoph 2026-09-15 ("committen und threshold deployen")
# Nur 5G: neues Steering-Profil st-main-5g mit transition-threshold=-72 (statt Default -80) und
# transition-threshold-time=5s (statt 10s). 2G bleibt auf st-main (unset -80) — Reichweite draussen.
# Nur am Manager noetig: steering/config werden per CAPsMAN an die CAPs verteilt.
# Rollback = steering der drei Configs zurueck auf st-main + st-main-5g loeschen.
/interface wifi steering add name=st-main-5g neighbor-group=bf-main rrm=yes wnm=yes transition-threshold=-72 transition-threshold-time=5s
/interface wifi configuration set [find name=cfg-main-5g-ap1] steering=st-main-5g
/interface wifi configuration set [find name=cfg-main-5g-ap2] steering=st-main-5g
/interface wifi configuration set [find name=cfg-main-5g-ap3] steering=st-main-5g

View File

@@ -0,0 +1,15 @@
# TP45 Schicht A — Nautobot-Literal in der Core-Firewall von .30 auf .154
#
# KEINE Transaktion: das ist eine dauerhafte Soll-Aenderung (Nautobot ist umgezogen,
# das Soll in Nautobot wurde mitgezogen). Die Datei liegt nur hier, weil
# gc-manual-plan.py eine Commands-Datei braucht.
#
# Kontext: die Regel *24 "TP5-E2: Nautobot->MGMT ssh" ist der LITERAL-Pfad und stand
# auf 10.40.20.30. Sie steht bei 0 Paketen — die Arbeit macht die Parallelregel *28
# "TP5-E2: Nautobot->MGMT ssh (list)" ueber src-address-list=nautobot (113 Pakete,
# Liste am 2026-09-21 um .154/.155/.156 erweitert). Der Literal ist damit
# funktional redundant, wird aber auf .154 gezogen, damit Soll (Nautobot-Daten
# `firewall_filter`) und Ist nicht auseinanderlaufen.
#
# Rollback: siehe TP45-firewall-nautobot-154.rollback.rsc
/ip firewall filter set [find comment="TP5-E2: Nautobot->MGMT ssh"] src-address=10.40.20.154

View File

@@ -0,0 +1,4 @@
# Rueckbau TP45 Schicht A: Nautobot-Literal zurueck auf .30
# (nur noetig, wenn Nautobot wieder auf .30 zurueckzieht — die Adressliste ist die
# wirksame Ebene, dieser Literal ist der tote Parallelpfad.)
/ip firewall filter set [find comment="TP5-E2: Nautobot->MGMT ssh"] src-address=10.40.20.30

View File

@@ -0,0 +1,3 @@
# Ist-Stand der Regel VOR dem TP45-Schicht-A-Deploy (2026-09-21, gelesen per MikroMCP).
/ip firewall filter
add action=accept chain=forward comment="TP5-E2: Nautobot->MGMT ssh" dst-port=22 out-interface=vlan99 protocol=tcp src-address=10.40.20.30

View File

@@ -84,7 +84,7 @@ dns:
ipset_file: ""
bootstrap_prefer_ipv6: false
upstream_timeout: 10s
private_networks: []
private_<redacted>: []
use_private_ptr_resolvers: false
local_ptr_upstreams: []
use_dns64: false

14
jobs/__init__.py Normal file
View File

@@ -0,0 +1,14 @@
"""bf-infra Nautobot-Jobs (Git-Datenquelle).
Nautobot importiert nur dieses Paket; damit die enthaltenen Jobs sich
registrieren, muss jedes Job-Modul hier importiert werden. Neue periodische
externe->Nautobot-Syncs kommen als weiteres Modul dazu (kein per-Task-Container).
"""
from nautobot.apps.jobs import register_jobs
from .cf_estate_sync import CFEstateSync
# Nautobot importiert nur dieses Paket (bf_infra.jobs) und erwartet register_jobs()
# HIER im __init__ (nicht im Submodul) — sonst: "No jobs were registered on loading
# the bf_infra.jobs submodule". Neue Jobs: Klasse importieren + hier mitregistrieren.
register_jobs(CFEstateSync)

267
jobs/cf_estate_sync.py Normal file
View File

@@ -0,0 +1,267 @@
"""
TP44 Teil B — CF-Estate → Nautobot, als geplanter Nautobot-Job (ORM).
Kanonische Runtime des CF→Nautobot-Sync. Laeuft im nautobot-worker (kein extra
Container), schreibt per ORM (keine Nautobot-Exposure), zieht die CF-API outbound.
Portierung der Reconcile-Logik aus nautobot/tp44-cf-sync.py (REST) auf das ORM.
Governance (User 2026-09-09): periodische externe->Nautobot-Syncs leben als
Nautobot-Jobs in bf-infra/jobs/ und werden in Nautobot geplant — KEIN per-Task-
Container/-Cron. Kuenftige Syncs = weitere Jobs hier.
Deckung: CloudNetwork (cfd_tunnel + warp_connector), CloudService (workers,
access-apps, hyperdrive, VPC), Prefix-Assignments (teamnet/routes), Verwaisung
(stale-Markierung statt Loeschen). ID-Matching + extra_config-Merge wie im Skript.
Token: Nautobot-Secret "cf-api-token" (Provider environment-variable -> CF_API_TOKEN
am Worker). CF-Account-ID: Secret "cf-account-id" ODER Konstante unten.
CF bleibt operativer Master; Nautobot ist Dokumentations-SSoT (read-only Pull).
"""
import json
import urllib.request
import urllib.parse
import urllib.error
from django.contrib.contenttypes.models import ContentType
from nautobot.apps.jobs import BooleanVar, Job
from nautobot.cloud.models import (
CloudAccount,
CloudNetwork,
CloudNetworkPrefixAssignment,
CloudResourceType,
CloudService,
)
from nautobot.dcim.models import Manufacturer
from nautobot.extras.models import Secret
from nautobot.ipam.models import Prefix
CF_API = "https://api.cloudflare.com/client/v4"
CF_ACCOUNT_ID = "393c051f3accf51881d6c98fc5b66c36"
RESOURCE_TYPES = [
("Cloudflare cloudflared Tunnel", "cloud", "cloudnetwork"),
("Cloudflare WARP Connector", "cloud", "cloudnetwork"),
("Cloudflare VPC Service", "cloud", "cloudservice"),
("Cloudflare Hyperdrive", "cloud", "cloudservice"),
("Cloudflare Worker", "cloud", "cloudservice"),
("Cloudflare Access Application", "cloud", "cloudservice"),
]
class CFEstateSync(Job):
dryrun = BooleanVar(
default=True,
description="Nur berichten, nichts schreiben (empfohlen fuer den ersten Lauf).",
)
class Meta:
name = "CF Estate Sync"
description = "Cloudflare-Estate (Tunnel/Worker/Access/Hyperdrive/VPC) nach Nautobot syncen (Doku-SSoT)."
grouping = "TP44 / Cloudflare"
# Nur ein Boolean (dryrun) als Eingabe; das CF-Token kommt aus dem Nautobot-Secret,
# nicht aus einer Job-Variable. Ohne diese Zeile (Default True) verweigert Nautobot
# das Scheduling: "Job may have sensitive input variables".
has_sensitive_variables = False
# ---------------------------------------------------------------- CF-Pull
def _cf_get(self, path):
"""(ok, result) — 403/404 werden abgefangen, damit fehlende Scopes den Sync nicht kippen."""
req = urllib.request.Request(CF_API + path, headers={"Authorization": "Bearer " + self._tok})
try:
with urllib.request.urlopen(req, timeout=30) as r:
return True, json.load(r).get("result")
except urllib.error.HTTPError as e:
if e.code in (403, 404):
return False, None
raise
def _ingress(self, tunnel_id):
ok, res = self._cf_get(f"/accounts/{CF_ACCOUNT_ID}/cfd_tunnel/{tunnel_id}/configurations")
rules = ((res or {}).get("config") or {}).get("ingress") or [] if ok else []
return [r["hostname"] for r in rules if r.get("hostname")]
def _load_cf(self):
"""networks/services: (name, rt_name, desc, extra, match_key, match_val).
routes: {tunnel_id: cidr}. skipped: Liste nicht lesbarer Endpoints."""
A = CF_ACCOUNT_ID
networks, services, routes, skipped = [], [], {}, []
_, tuns = self._cf_get(f"/accounts/{A}/cfd_tunnel?is_deleted=false&per_page=50")
for t in (tuns or []):
networks.append((t["name"], "Cloudflare cloudflared Tunnel",
f"cloudflared-Tunnel ({len(t.get('connections') or [])} Connectoren)",
{"tunnel_id": t["id"], "kind": "cloudflared",
"connector_count": len(t.get("connections") or []),
"ingress_hostnames": self._ingress(t["id"])},
"tunnel_id", t["id"]))
_, warps = self._cf_get(f"/accounts/{A}/warp_connector?per_page=50")
for w in (warps or []):
networks.append((w["name"], "Cloudflare WARP Connector",
f"WARP-Connector ({len(w.get('connections') or [])} Connectoren)",
{"tunnel_id": w["id"], "kind": "warp_connector",
"connector_count": len(w.get("connections") or [])},
"tunnel_id", w["id"]))
_, scripts = self._cf_get(f"/accounts/{A}/workers/scripts")
for s in (scripts or []):
services.append((s["id"], "Cloudflare Worker", "Cloudflare Worker",
{"script": s["id"]}, "script", s["id"]))
ok, apps = self._cf_get(f"/accounts/{A}/access/apps?per_page=100")
if not ok:
skipped.append("access/apps")
for a in (apps or []):
services.append((a.get("name") or a.get("id"), "Cloudflare Access Application",
f"Access-App ({a.get('type')})",
{"id": a.get("id"), "type": a.get("type"), "domain": a.get("domain")},
"id", a.get("id")))
ok, hyper = self._cf_get(f"/accounts/{A}/hyperdrive/configs")
if not ok:
skipped.append("hyperdrive/configs")
for h in (hyper or []):
origin = h.get("origin") or {}
services.append((h.get("name") or h.get("id"), "Cloudflare Hyperdrive", "Hyperdrive-Config",
{"id": h.get("id"), "database": origin.get("database"),
"user": origin.get("user")}, "id", h.get("id")))
ok, vpc = self._cf_get(f"/accounts/{A}/connectivity/directory/services")
if not ok:
skipped.append("connectivity/directory/services")
for v in (vpc or []):
# VPC-Directory-Services tragen ihren Identifier in "service_id" (NICHT "id").
sid = v.get("service_id") or v.get("id")
services.append((v.get("name") or sid, "Cloudflare VPC Service", "VPC-Service",
{"service_id": sid, "type": v.get("type")}, "service_id", sid))
ok, rts = self._cf_get(f"/accounts/{A}/teamnet/routes?per_page=50")
if not ok:
skipped.append("teamnet/routes")
for r in (rts or []):
if r.get("network") and r.get("tunnel_id"):
routes[r["tunnel_id"]] = r["network"]
return networks, services, routes, skipped
# ---------------------------------------------------------------- ORM-Upsert
def _upsert(self, model, cache, name, rt, acct, desc, extra, mk, mv, label, seen, dryrun):
# mv=None nie matchen: sonst greift .get(mk)==None auf das erste Objekt OHNE mk
# und mischt fremde extra_config zusammen (z.B. VPC ohne id -> App-Launcher).
if mv is None:
self.logger.warning("~ %s '%s' ohne Match-Wert (%s) — uebersprungen", label, name, mk)
return None
ex = next((o for o in cache if (o.extra_config or {}).get(mk) == mv), None)
if ex:
seen.add(ex.id)
merged = dict(ex.extra_config or {})
merged.update(extra)
if merged == (ex.extra_config or {}):
return ex
if dryrun:
self.logger.info("~ %s '%s': extra_config-Update [DRY-RUN]", label, ex.name)
return ex
ex.extra_config = merged
ex.validated_save()
self.logger.info("~ %s '%s' aktualisiert", label, ex.name)
return ex
if dryrun:
self.logger.info("+ %s '%s' [DRY-RUN]", label, name)
return None
obj = model(name=name, cloud_resource_type=rt, cloud_account=acct,
description=desc, extra_config=extra)
obj.validated_save()
cache.append(obj)
seen.add(obj.id)
self.logger.info("+ %s '%s' angelegt", label, name)
return obj
def _mark_stale(self, cache, seen, label, dryrun):
for o in cache:
extra = o.extra_config or {}
if o.id in seen:
if extra.get("stale") and not dryrun:
o.extra_config = {k: v for k, v in extra.items() if k != "stale"}
o.validated_save()
self.logger.info("↩ %s '%s': stale entfernt (wieder da)", label, o.name)
continue
if extra.get("stale"):
continue
if dryrun:
self.logger.warning("⚠ %s '%s' fehlt im Live-Pull → wuerde stale markiert [DRY-RUN]", label, o.name)
continue
o.extra_config = dict(extra, stale=True)
o.validated_save()
self.logger.warning("⚠ %s '%s' als stale markiert (nicht mehr in CF)", label, o.name)
# ---------------------------------------------------------------- run
def run(self, dryrun=True):
try:
self._tok = Secret.objects.get(name="cf-api-token").get_value()
except Secret.DoesNotExist:
raise RuntimeError("Nautobot-Secret 'cf-api-token' fehlt — bitte anlegen (Provider env, CF_API_TOKEN).")
networks, services, routes, skipped = self._load_cf()
self.logger.info("Live-Pull: %d CloudNetworks · %d CloudServices%s",
len(networks), len(services),
f" · SKIP: {', '.join(skipped)}" if skipped else " · alle Endpoints lesbar")
mfr, _ = Manufacturer.objects.get_or_create(name="Cloudflare")
acct, created = CloudAccount.objects.get_or_create(
name="Cloudflare", defaults={"account_number": CF_ACCOUNT_ID, "provider": mfr})
if created and dryrun:
pass
rt_by_name = {}
for name, app, model_name in RESOURCE_TYPES:
ct = ContentType.objects.get(app_label=app, model=model_name)
rt, _ = CloudResourceType.objects.get_or_create(name=name, defaults={"provider": mfr})
rt.content_types.add(ct)
rt_by_name[name] = rt
net_cache = list(CloudNetwork.objects.filter(cloud_account=acct))
svc_cache = list(CloudService.objects.filter(cloud_account=acct))
seen_net, seen_svc = set(), set()
self.logger.info("[CloudNetworks]")
for name, rt_name, desc, extra, mk, mv in networks:
self._upsert(CloudNetwork, net_cache, name, rt_by_name.get(rt_name), acct,
desc, extra, mk, mv, "CloudNetwork", seen_net, dryrun)
self.logger.info("[CloudServices]")
for name, rt_name, desc, extra, mk, mv in services:
self._upsert(CloudService, svc_cache, name, rt_by_name.get(rt_name), acct,
desc, extra, mk, mv, "CloudService", seen_svc, dryrun)
self.logger.info("[Prefix-Assignments]")
for tunnel_id, cidr in routes.items():
net = next((n for n in net_cache if (n.extra_config or {}).get("tunnel_id") == tunnel_id), None)
if not net or getattr(net, "id", None) is None:
continue
pfx = Prefix.objects.filter(prefix=cidr).first()
if not pfx:
self.logger.info(" ~ Route %s: Prefix nicht in IPAM → uebersprungen", cidr)
continue
if CloudNetworkPrefixAssignment.objects.filter(cloud_network=net, prefix=pfx).exists():
continue
if dryrun:
self.logger.info(" + %s ↔ %s [DRY-RUN]", net.name, cidr)
continue
CloudNetworkPrefixAssignment(cloud_network=net, prefix=pfx).validated_save()
self.logger.info(" + %s ↔ %s angelegt", net.name, cidr)
self.logger.info("[Verwaisung]")
# CloudServices nur markieren, wenn ALLE Service-Endpoints lesbar waren — sonst
# wuerde ein fehlender Scope echte Objekte faelschlich als verwaist markieren.
svc_safe = not ({"access/apps", "hyperdrive/configs", "connectivity/directory/services"} & set(skipped))
if svc_safe:
self._mark_stale(svc_cache, seen_svc, "CloudService", dryrun)
else:
self.logger.info(" · CloudService-Verwaisung uebersprungen (Token-Scope unvollstaendig)")
self._mark_stale(net_cache, seen_net, "CloudNetwork", dryrun)
self.logger.info("Fertig (%s).", "DRY-RUN — nichts geschrieben" if dryrun else "COMMIT")
# Registrierung zentral in jobs/__init__.py (Nautobot importiert nur das Paket).

View File

@@ -52,15 +52,19 @@ BENUTZUNG
python3 nautobot/gc-configplan.py --job drift-cleanup --apply --no-deploy
"""
import argparse
import importlib.util
import json
import os
import pathlib
import re
import sys
import time
import urllib.error
import urllib.parse
import urllib.request
from datetime import datetime
BASE = "http://10.40.20.30:8080/api"
BASE = "http://10.40.20.154:8080/api"
TOKEN = os.environ.get("NAUTOBOT_TOKEN", "")
# Status-UUIDs fuer nautobot_golden_config.configplan (2026-08-16 aus der API gelesen)
@@ -160,8 +164,22 @@ def create_plans(device_names, config_set, change_control_id, dry):
# Sammelabfrage zuordnen (Lehre aus TP21.1: REST sortiert alphabetisch).
q = urllib.parse.urlencode({"change_control_id": change_control_id, "depth": 1})
found = req("GET", f"/plugins/golden-config/config-plan/?{q}").get("results", [])
# Mehrere Plaene unter derselben ccid sind normal, sobald ein Job mit geaendertem
# Inhalt erneut laeuft -- die ccid benennt die Aenderung, nicht den Versuch.
# 🔴 Wer dann die REST-Reihenfolge entscheiden laesst, nimmt nondeterministisch
# den ALTEN Plan und laeuft in den config_set-Guard unten (am 2026-09-21 genau so
# passiert: Abbruch trotz korrekt erzeugtem neuen Plan). Der Job hat eben einen
# neuen Plan angelegt, also gilt der juengste -- die alten bleiben Historie.
def created(p):
raw = str(p.get("created") or "")
try:
return datetime.fromisoformat(raw.replace("Z", "+00:00")).replace(tzinfo=None)
except ValueError:
return datetime.min
by_name = {}
for p in found:
for p in sorted(found, key=created):
name = (p.get("device") or {}).get("display")
by_name[name] = p["id"]
@@ -289,7 +307,7 @@ def job_mgmt_acl():
das ist auf dem Core passiert. Umgekehrt fuhren branch/ap1/ap2 ssh/www/winbox/api/ftp/
telnet komplett OHNE Address-Beschraenkung; winbox war auf allen vier offen.
KEIN LOCKOUT-RISIKO: der Deploy laeuft von Nautobot (10.40.20.30) aus, also aus
KEIN LOCKOUT-RISIKO: der Deploy laeuft von Nautobot (10.40.20.154) aus, also aus
10.40.0.0/16 -- die Adresse bleibt in jeder gesetzten ACL enthalten. RouterOS wendet
`address=` ohnehin erst auf NEUE Verbindungen an, die laufende Session ueberlebt.
@@ -330,7 +348,391 @@ def job_mgmt_acl():
]
JOBS = {"drift-cleanup": job_drift_cleanup, "mgmt-acl": job_mgmt_acl}
def job_tp42_dhcp_domain():
"""TP42 (2026-09-02): DHCP-Search-Domain der 7 Netze emsenhuber.net -> bf.emsenhuber.net.
WARUM: das GC-Template verteilte `domain=emsenhuber.net` (bare), die internen A-Records leben
aber unter `bf.emsenhuber.net`. Folge: ein bare `macmini` loeste NICHT auf (nur der volle FQDN).
Zielschema-Entscheid (User 2026-09-02) = `bf.emsenhuber.net`. Das Template (Z.133) ist bereits
auf `bf.emsenhuber.net` gehoben; dieser Job zieht das laufende Geraet nach.
MODIFY, kein add: das Netz existiert -> `set [find]`, nicht die `add`-Zeile der intended config
(die wuerde `already have such address` werfen). `[find]` ohne Filter trifft alle 7 Netze.
KEIN LOCKOUT-RISIKO: `domain` ist eine DHCP-Option, sie beruehrt weder Routing noch Mgmt-Zugang;
Clients ziehen sie erst beim naechsten Lease-Renew (lease-time 1d).
"""
core_set = "\n".join([
':do { /ip dhcp-server network set [find] domain=bf.emsenhuber.net } '
'on-error={ :log info "tp42-dhcp: set geworfen" }',
':log info ("tp42-dhcp: bf-domains=" . [:tostr [:len [/ip dhcp-server network '
'find where domain="bf.emsenhuber.net"]]] . "/7")',
])
return [(["crs326-core"], core_set, "TP42-dhcp-domain-bf")]
def job_tp38_oob():
"""TP38 (2026-09-15): OOB-MGMT-Port (ether23 untagged VLAN99) + Branch-Input-Firewall.
Zwei Geraete, zwei config_sets:
* branch: ether23 untaggen, VLAN99 um untagged=ether23 erweitern, 8 Input-Regeln
(deny-by-default). Die Regeln werden in der Reihenfolge angelegt, in der das
Template sie rendert — established zuerst, drop zuletzt — damit kein LOCKOUT:
die laufende Nautobot-SSH-Session (10.40.20.154) matcht auf Regel 1 (established),
bevor Regel 8 (drop) greift.
* core: ether23 untaggen, VLAN99 untagged=ether23, EINE Regel "OOB->core mgmt" mit
place-before vor die Log-Regel (sonst landet sie hinter dem finalen drop und
waere wirkungslos + non-compliant).
KEIN LOCKOUT-RISIKO: ether23 ist auf beiden Geraeten frei (running=false); der
VLAN99-Umbau aendert nur `untagged`, nicht `tagged`; der Deploy laeuft von Nautobot
(10.40.20.154), das in jeder gesetzten Firewall-Freigabe enthalten bleibt.
"""
bridge_set = (
':do { /interface bridge port set [find interface=ether23] pvid=99 '
'frame-types=admit-only-untagged-and-priority-tagged comment="TP38-OOB-MGMT" } '
'on-error={ :log info "tp38: ether23 set geworfen" }'
)
vlan_set = (
':do { /interface bridge vlan set [find vlan-ids=99] untagged=ether23 } '
'on-error={ :log info "tp38: vlan99 untagged geworfen" }'
)
branch_fw = "\n".join([
'add action=accept chain=input comment="TP38: established" connection-state=established,related,untracked',
'add action=drop chain=input comment="TP38: invalid" connection-state=invalid',
'add action=accept chain=input comment="TP38: icmp" protocol=icmp',
'add action=accept chain=input comment="TP38: mndp" dst-port=5678 protocol=udp',
'add action=accept chain=input comment="TP38: mgmt LAN" dst-port=22,80,8291,8728 protocol=tcp src-address=10.40.0.0/16',
'add action=accept chain=input comment="TP38: mgmt mesh" dst-port=22,80,8291,8728 protocol=tcp src-address=100.96.0.0/12',
'add action=log chain=input comment="TP38: input log-only" log-prefix=TP38-BRANCH-WOULD-DROP',
'add action=drop chain=input comment="TP38: input deny-by-default"',
])
branch_set = "\n".join([
bridge_set,
vlan_set,
*[f"/ip firewall filter {ln}" for ln in branch_fw.splitlines()],
':log info ("tp38: branch pvid=" . [:tostr [/interface bridge port get [find interface=ether23] pvid]]'
' . " fw=" . [:tostr [:len [/ip firewall filter find where comment~"TP38"]]] . "/8")',
])
# ⚠️ `add ... place-before=[find ...]` wird ueber Netmiko IGNORIERT (Regel landet am
# Ketten-Ende, also HINTER dem finalen drop = wirkungslos; beim Deploy 2026-09-15 so
# aufgeschlagen). Deshalb: erst add (appends), dann `move` vor die Log-Regel.
core_set = "\n".join([
bridge_set,
vlan_set,
'/ip firewall filter add action=accept chain=input comment="TP38: OOB->core mgmt" '
'dst-port=22,80,8291,8728 in-interface=vlan99 protocol=tcp',
'/ip firewall filter move [find where comment="TP38: OOB->core mgmt"] '
'destination=[find where comment="TP5: input log-only"]',
':log info ("tp38: core pvid=" . [:tostr [/interface bridge port get [find interface=ether23] pvid]]'
' . " oob=" . [:tostr [:len [/ip firewall filter find where comment="TP38: OOB->core mgmt"]]])',
])
return [
(["crs326-branch"], branch_set, "TP38-oob-branch"),
(["crs326-core"], core_set, "TP38-oob-core"),
]
def job_tp45_agh_fw():
"""TP45 Schicht A (2026-09-21): DNS-Freigaben fuer die neuen Resolver-Adressen .30/.31.
Der Resolver zieht von .36/.37 auf .30/.31 (TP32-Oktett-Klasse DNS `.3x`). Damit die
Umstellung ohne Ausfall geht, laufen beide Adressen kurz parallel — also braucht der
Core **beide** Freigaben. Diese hier ist ADDITIV: die vier .36/.37-Regeln bleiben
stehen und fallen erst beim Rueckbau (eigener Schritt, wenn die Zaehler stillstehen).
Die vier Regeln sind ein Literal im Soll (`local_config_context_data.firewall_filter`,
gepflegt mit `nautobot/tp45-agh-firewall.py`) — der Job zieht nur das Geraet nach.
🔴 `place-before` wird ueber Netmiko IGNORIERT (Lehre aus TP38, 2026-09-15): die Regel
landet am Ketten-Ende, also HINTER dem finalen `drop` und waere wirkungslos, waehrend
der Plan trotzdem „Completed" meldet. Deshalb `add` (appends) und danach `move` vor
die Log-Regel — in der Reihenfolge, in der die Regeln stehen sollen (jedes `move`
schiebt seine Regel unmittelbar vor das Ziel, also hinter die zuvor verschobenen).
🔴 **Zweite Falle, am 2026-09-21 beim ersten Lauf aufgeschlagen:** nicht der `move`
war falsch, sondern der **Selektor** — `find where dst-address=<bare-IP>` matcht nie
(Details und Tragweite in der Docstring von `sel()` unten). Der Plan meldete
trotzdem „Completed", die Regeln lagen hinter dem `drop`. Deshalb ist die Abnahme
hier **nicht** der Plan-Status, sondern die Position am Geraet.
KEIN LOCKOUT-RISIKO: die Regeln erweitern nur `accept` in der forward-Kette; der
Mgmt-Pfad (Nautobot-SSH -> vlan99) ist von der Aenderung nicht beruehrt. Der Deploy
laeuft von 10.40.20.154, das auf Regel 22 (established) matcht.
"""
ips = ["10.40.20.30", "10.40.20.31"]
log = 'TP5: log-only, Vorstufe zum deny-by-default'
def sel(cmt, ip):
"""Selektor auf genau eine Regel.
🔴 **`dst-address=<bare-IP>` matcht in `find where` NIE** — live am Core
gemessen (2026-09-21): `find where dst-address=10.40.20.30` → **0 Treffer**,
auch mit `/32`; `dst-address~"10.40.20.30"` (Regex) → 2. Deshalb steht hier
`~`, nicht `=`.
⚠️ Die Tragweite ist größer als dieser Job: **eine Prüfung, die 0 meldet,
sieht wie „nicht vorhanden" aus und nicht wie „kaputt".** Genau daran ist
der erste Lauf dieses Jobs gescheitert — der `add` lief (der Guard sah
„nicht vorhanden"), der `move` lief ins Leere, und der Plan meldete
trotzdem „Completed". Dieselbe Zeile stand als *Verifikation* in
`docs/transaktionen/TP23-agh-firewall.commands.rsc:7` und hat dort seit
dem 2026-08-25 immer `0` gemeldet, ohne je etwas zu prüfen.
Gleiche Klasse wie `nc -z` (2026-09-01) und das `sed`-Maskierungsmuster:
**erst den Selektor verdächtigen, dann das Gerät.**
"""
return f'comment="{cmt}" dst-address~"{ip}"'
def rule(ip, proto, cmt):
return (f'/ip firewall filter add action=accept chain=forward comment="{cmt}" '
f'dst-address={ip} dst-port=53 protocol={proto}')
lines = []
for ip in ips:
# Guard + move getrennt: nur der Guard ist idempotent (ein zweiter Lauf
# verdoppelt die Regeln nicht), der move läuft immer — er ist auch der
# Reparaturweg, wenn eine Regel schon existiert, aber falsch einsortiert ist.
for proto, cmt in (("udp", "TP5-E2: LAN->AGH dns"), ("tcp", "TP5-E2: LAN->AGH dns-tcp")):
lines.append(f':if ([:len [/ip firewall filter find where {sel(cmt, ip)}]] = 0) '
f'do={{ {rule(ip, proto, cmt)} }}')
for ip in ips:
for cmt in ("TP5-E2: LAN->AGH dns", "TP5-E2: LAN->AGH dns-tcp"):
lines.append(f'/ip firewall filter move [find where {sel(cmt, ip)}] '
f'destination=[find where comment="{log}"]')
# Der Anker ist bewusst die Log-Regel (Baseline, stabil) und nicht `caddy`: haengt
# sie unmittelbar vor der Log-Regel, landen die vier Regeln DAHINTER -- der AGH-Block
# bleibt so zusammen, wie das Soll ihn fuehrt. Waehlte man `caddy` als Ziel und die
# Regel fehlte, laegen die vier hinter dem `drop` = funktional kaputt; so bleibt im
# Fehlerfall nur eine Reihenfolge-Abweichung (Compliance-Drift, kein Ausfall).
lines.append(f'/ip firewall filter move [find where comment="TP31: AP-cloudflared -> caddy-bf1"] '
f'destination=[find where comment="{log}"]')
# ⚠️ Diese Zeile meldet NUR Anwesenheit (je IP 2 Regeln erwartet), NICHT die
# Position -- sie kann also gruen aussehen, waehrend die Regeln hinter dem `drop`
# liegen. Genau daran ist der erste Lauf gescheitert. **Die Abnahme ist der
# Geraete-Read nach dem Deploy** (`print terse proplist=comment,packets`).
lines.append(
':log info ("tp45-agh-fw: .30=" . '
'[:tostr [:len [/ip firewall filter find where dst-address~"10.40.20.30"]]] . " .31=" . '
'[:tostr [:len [/ip firewall filter find where dst-address~"10.40.20.31"]]] . " log=" . '
f'[:tostr [:len [/ip firewall filter find where comment="{log}"]]])')
return [(["crs326-core"], "\n".join(lines), "TP45-agh-firewall")]
def job_tp45_agh_dhcp():
"""TP45 Schicht A (2026-09-21): DHCP-DNS-Server der 7 Netze .36,.37 -> .30,.31.
Der Core verteilt in ALLEN sieben Netzen `dns-server=10.40.20.36,10.40.20.37`
(live geprueft 2026-09-21). Das Template (Z.137) ist auf .30,.31 gehoben; dieser Job
zieht das laufende Geraet nach.
MODIFY, kein add: das Netz existiert -> `set [find]`, nicht die `add`-Zeile der
intended config (die wuerfe `already have such address`). `[find]` ohne Filter
trifft alle 7 Netze. Gleiche Form wie `job_tp42_dhcp_domain`.
⚠️ **Reihenfolge zwingend:** erst `tp45-agh-fw` deployen. Sonst liefert DHCP Adressen
aus, die die Firewall noch nicht durchlaesst — unter deny-by-default faellt DNS aus
allen VLANs aus.
KEIN LOCKOUT-RISIKO: eine DHCP-Option beruehrt weder Routing noch Mgmt-Zugang;
Clients ziehen sie erst beim naechsten Lease-Renew (lease-time 1d, GUEST 12h).
"""
core_set = "\n".join([
':do { /ip dhcp-server network set [find] dns-server=10.40.20.30,10.40.20.31 } '
'on-error={ :log info "tp45-agh-dhcp: set geworfen" }',
':log info ("tp45-agh-dhcp: auf-neu=" . [:tostr [:len [/ip dhcp-server network '
'find where dns-server~"10.40.20.30"]]] . "/7")',
])
return [(["crs326-core"], core_set, "TP45-agh-dhcp")]
def _pool_set(vlan, ranges):
"""Zeilen, die `pool-v<vlan>` auf `ranges` ziehen -- mit gezaehltem Selektor.
MODIFY, kein add: der Pool existiert, die `add`-Zeile der intended config
wuerfe `already have such name`. Gleiche Form wie `job_tp45_agh_dhcp`.
🔴 Der Selektor wird GEZAEHLT, nicht geglaubt (Lehre vom 2026-09-21): ein
`find where`, das 0 trifft, sieht wie „nicht vorhanden" aus und nicht wie
„kaputt" -- ein blankes `set [find where name=…]` liefe ins Leere und der
Job meldete trotzdem Erfolg (dieselbe Klasse wie `dst-address=<bare IP>`
in TP23-agh-firewall.commands.rsc:7, das seit dem 08-25 immer 0 meldete).
🔴🔴 **JEDES Statement muss auf EINER Zeile klammer-vollstaendig sein.**
Erste Fassung hatte `:if (...) do={` am Zeilenende -- RouterOS geht dann in
den Fortsetzungs-Modus und zeigt einen ANDEREN Prompt, der netmiko-Treiber
verliert sein Muster und der Deploy stirbt mit
`E1015: Pattern not detected: (redacted)@crs326\\-core\\].*$|#.*$)`.
Der Plan stand danach auf `Failed`, **ohne** etwas geschrieben zu haben.
Deshalb ist jede Zeile hier ein vollstaendiges `… do={ …; … } else={ … }`.
"""
pool = f"pool-v{vlan}"
return "\n".join([
f':if ([:len [/ip pool find where name="{pool}"]] = 1) do={{ '
f'/ip pool set [find where name="{pool}"] ranges={ranges}; '
f':log info ("tp45-pool: {pool} -> " . [/ip pool get [find where name="{pool}"] ranges]) }} '
f'else={{ :log info ("tp45-pool: ABBRUCH, {pool} nicht eindeutig") }}',
])
def job_tp45_pool_v20():
"""TP45 (2026-09-21): pool-v20 von .100-.200 auf .200-.249 verengen.
Damit werden die Schema-Baender .100-.149 (Server-Hosts) und .150-.199
(App-Services) in VLAN20 echt frei. VLAN20 traegt KEINE DHCP-Reservierung
im alten Fenster (live geprueft: nur `nas-bf .20.10` in .10x) und 0
dynamische Leases -- die Verengung kostet hier nichts.
🔴 Warum ueberhaupt: `nautobot .154-.158`, `gitea .157`, `pve-mcp .173` und
`shelly-mcp .180` tragen ihre IP GERAETELOKAL und stehen in KEINEM
Lease-Eintrag -- der Core kann sie nicht schuetzen und einem DHCP-Client
.154 anbieten. Die Verengung ist hier sofort wirksam.
⚠️ VLAN30 gehoert NICHT hierher: dort liegen 35 statische Reservierungen IM
Fenster .200-.249 (26 Shellys .202-.226/.233, SwitchBot .227, Twinkly .228,
Withings .230/.231, lichterketten .236/.237, Nuki .241/.244, CCU .232).
Erst Schicht B zieht die um, DANN pool-v30.
"""
return [(["crs326-core"], _pool_set(20, "10.40.20.200-10.40.20.249"), "TP45-pool-v20")]
def _tp45_leases_module():
"""MOVES/REMOVE/ADDS aus `tp45-leases.py` laden.
🔴 **NICHT kopieren.** Diese Tabellen sind die SSoT des Umzugs. Eine zweite
Kopie hier liefe beim ersten Edit auseinander — und zwar still, weil beide
Seiten fuer sich plausibel aussehen; am Geraet faellt nur auf, dass eine
Adresse fehlt.
Der Dateiname traegt einen Bindestrich (Repo-Konvention fuer Skripte), ist
also nicht regulaer importierbar -> importlib ueber den Pfad. `__name__` ist
dann nicht `__main__`, das `main()`-Guard der Datei greift also nicht.
"""
spec = importlib.util.spec_from_file_location(
"tp45_leases", pathlib.Path(__file__).with_name("tp45-leases.py"))
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
def _lease_move(mac, soll):
"""Eine Umzugs-Zeile — EINZEILIG und klammer-vollstaendig (E1015-Lehre, s. _pool_set).
Der Selektor wird GEZAEHLT: ein `find where`, das 0 trifft, sieht wie
„nicht vorhanden" aus und nicht wie „kaputt", und ein blankes `set [find …]`
liefe ins Leere, waehrend der Job Erfolg meldet.
Absichtlich OHNE `address=<ist>` im Selektor: ein zweiter Lauf muss ein
No-Op sein, kein Fehler. Die Ist-Adresse wird stattdessen VOR dem Deploy
geprueft — `tp45-leases.py move` verlangt, dass das Soll genau `ist` traegt
und bricht sonst ab.
🔴🔴 **ZWEI VERSCHIEDENE Selektor-Formen, und das ist keine Kosmetik.**
Die erste Fassung schrieb ueberall die Argument-Form `[… [find where …]]`.
Die ist **Syntaxfehler**, sobald sie in `[:len …]` steht:
`expected command name (line 1 column 55)` (live gemessen 2026-09-21)
Der Deploy lief trotzdem als `Completed` durch, das Geraet blieb
**unveraendert**, und im Log stand nur die Schlusszeile — von den 38
`:if`-Statements hat **kein einziger** Zweig geloggt, also ist auch kein
`set` gelaufen.
* in `[:len …]` und direkt vor `find`: **`/ip dhcp-server lease find where …`**
(kein Klammerpaar um `find`) — Muster aus `_pool_set`/`job_tp45_agh_dhcp`
* als Argument einer Vollpfad-Kommandozeile: `set [find where …]`
— diese Form ist in `_pool_set` bewiesen und bleibt.
⚠️ **Merkregel:** `Completed` am Plan und `SUCCESS` am Job beweisen hier
nichts. Der Beweis ist die **Zahl der Log-Zeilen** (jeder Zweig loggt) oder
ein Geraete-Read. Beides gehoert zur Abnahme — genau wie beim
`pool-v20`-Deploy, der ohne Gegenprobe als gelungen gegolten haette.
"""
find = f'find where mac-address={mac}'
arg = f'[find where mac-address={mac}]'
return (f':if ([:len [/ip dhcp-server lease {find}]] = 1) do={{ '
f'/ip dhcp-server lease set {arg} address={soll}; '
f':log info ("tp45-v30: {mac} -> {soll}") }} '
f'else={{ :log info ("tp45-v30: {mac} NICHT EINDEUTIG -- nicht angefasst") }}')
def job_tp45_v30_leases():
"""TP45 Schicht B2 (2026-09-21): die VLAN30-Reservierungen ins Oktett-Schema.
36 Reservierungen wandern aus dem DHCP-Pool-Fenster (.202-.244, .5, .8) in die
Schema-Baender: `.11-.14` fest verbaute Infrastruktur, `.151-.176` Shelly-Block,
`.177-.196` App-Services. Dazu zwei Sonderfaelle:
* `pve-homematic-raspi-ccu` (MAC BC:24:11:8E:0A:57) wird ENTFERNT — eine
Leiche aus dem Core-Cutover (`status=waiting`, `last-seen=never`). Die CCU
ist live in VLAN20 (.20.232, ARP + HTTP 200 belegt, Caddys `ccu.bf` proxyt
dorthin); die VLAN30-Reservierung ist ein Zombie.
* `SONOFF-NSPanelPro` hat GAR KEINE Reservierung, nur eine dynamische Lease
auf `.249`. Wird per `make-static` gepinnt und auf `.12` gezogen.
⚠️ **Reihenfolge:** dieser Job gehoert VOR `tp45-pool-v30`. Die Verengung auf
`.200-.249` setzt voraus, dass keine Reservierung mehr im Schema-Band liegt —
sonst zieht der Pool Adressen, die schon vergeben sind.
⚠️ **Kein Ausfall, kein Lockout:** ueber DHCP-Reservierungen umzuziehen heisst,
dass die Geraete beim naechsten Lease-Renew selbst nachziehen (lease-time 1d).
Nur zwei der 36 sind im Moment ueberhaupt `bound` (SwitchBot, DTUBI); alle
anderen stehen auf `last-seen=never`. Nichts wird hart umgeschaltet.
⚠️ **`.150` (Ender3V3KE) und `.180` (espressif/Airfryer) bleiben, wo sie sind** —
sie liegen bereits im App-Band und werden bewusst nicht bewegt.
Rueckweg: `MOVES` traegt Ist UND Soll je MAC, das inverse `set` ist also
mechanisch; zusaetzlich liegt vor dem Deploy ein binaeres Backup auf dem Core.
"""
mod = _tp45_leases_module()
lines = [_lease_move(mac, soll) for mac, (_ist, soll) in sorted(mod.MOVES.items())]
for mac in sorted(mod.REMOVE):
find = f'find where mac-address={mac}'
arg = f'[find where mac-address={mac}]'
lines.append(f':if ([:len [/ip dhcp-server lease {find}]] = 1) do={{ '
f'/ip dhcp-server lease remove {arg}; '
f':log info ("tp45-v30: CCU-Leiche {mac} entfernt") }} '
f'else={{ :log info ("tp45-v30: CCU-Leiche schon weg") }}')
for add in mod.ADDS:
mac = re.search(r"mac-address=(\S+)", add).group(1)
ip = re.search(r"address=(\S+)", add).group(1)
cmt = re.search(r"comment=(\S+)", add).group(1)
find = f'find where mac-address={mac}'
arg = f'[find where mac-address={mac}]'
# make-static VOR set: auf einer dynamischen Lease ist `set address=` wirkungslos
# bzw. wird beim naechsten Renew ohnehin verworfen -- erst statisch, dann pinnen.
lines.append(f':if ([:len [/ip dhcp-server lease {find}]] = 1) do={{ '
f'/ip dhcp-server lease make-static {arg}; '
f'/ip dhcp-server lease set {arg} address={ip} comment="{cmt}"; '
f':log info ("tp45-v30: NSPanelPro statisch auf {ip}") }} '
f'else={{ :log info ("tp45-v30: NSPanelPro hat keine Lease -- spaeter nachziehen") }}')
# Abnahme-Zeile. `address=` ist ein echter Eigenschaftsvergleich (kein Regex) --
# bewusst NICHT `~"10.40.30.11"`, das traefe auch .110-.119.
lines.append(
':log info ("tp45-v30: .11=" . [:tostr [:len [/ip dhcp-server lease '
'find where address=10.40.30.11]]] . " .12=" . [:tostr [:len [/ip dhcp-server '
'lease find where address=10.40.30.12]]] . " .151=" . [:tostr [:len '
'[/ip dhcp-server lease find where address=10.40.30.151]]] . " .196=" . '
'[:tostr [:len [/ip dhcp-server lease find where address=10.40.30.196]]])')
return [(["crs326-core"], "\n".join(lines), "TP45-v30-leases")]
JOBS = {
"drift-cleanup": job_drift_cleanup,
"mgmt-acl": job_mgmt_acl,
"tp42-dhcp-domain": job_tp42_dhcp_domain,
"tp38-oob": job_tp38_oob,
"tp45-agh-fw": job_tp45_agh_fw,
"tp45-agh-dhcp": job_tp45_agh_dhcp,
"tp45-pool-v20": job_tp45_pool_v20,
"tp45-v30-leases": job_tp45_v30_leases,
}
# ------------------------------------------------------------------------ main

Some files were not shown because too many files have changed in this diff Show More