diff --git a/docs/tp25-gehweg-auswertung.py b/docs/tp25-gehweg-auswertung.py index 0759682..5f30a95 100644 --- a/docs/tp25-gehweg-auswertung.py +++ b/docs/tp25-gehweg-auswertung.py @@ -26,16 +26,37 @@ AP = {"cap-wifi1": "ap1/5GHz", "cap-wifi2": "ap1/2,4GHz", "cap-wifi3": "ap2/5GHz", "cap-wifi4": "ap2/2,4GHz"} +def ros_ms(v): + """RouterOS-Dauer in Millisekunden. Schreibweisen: "12ms", "3ms441us", "529us", "1s200ms".""" + total = 0.0 + for zahl, einheit in re.findall(r"(\d+)(us|ms|s)", v): + total += int(zahl) * {"us": 0.001, "ms": 1.0, "s": 1000.0}[einheit] + return total + + def main(): ap = argparse.ArgumentParser() ap.add_argument("--dir", required=True) a = ap.parse_args() pings = [] - for line in open(os.path.join(a.dir, "walk-ping.log")): - m = re.match(r"(\d\d:\d\d:\d\d) 64 bytes.*icmp_seq=(\d+).*time=([\d.]+)", line) - if m: - pings.append((sec(m.group(1)), int(m.group(2)), float(m.group(3)))) + csv_path = os.path.join(a.dir, "walk-ping.csv") + if os.path.exists(csv_path): + # Neues Format: Ping vom Core, "ts_local,seq,ms" — leeres ms = Verlust. + for r in csv.DictReader(open(csv_path)): + if not (r.get("seq") or "").isdigit(): + continue # RECONNECT-Zeilen + ms = (r.get("ms") or "").strip() + if ms: + pings.append((sec(r["ts_local"]), int(r["seq"]), ros_ms(ms))) + else: + # Altes Format: BSD-ping vom Laptop. + for line in open(os.path.join(a.dir, "walk-ping.log")): + m = re.match(r"(\d\d:\d\d:\d\d) 64 bytes.*icmp_seq=(\d+).*time=([\d.]+)", line) + if m: + pings.append((sec(m.group(1)), int(m.group(2)), float(m.group(3)))) + if not pings: + raise SystemExit("Keine Ping-Antworten gefunden.") rows = [r for r in csv.DictReader(open(os.path.join(a.dir, "sampler.csv"))) if r.get("sta_signal")] diff --git a/docs/tp25-walk-messung.sh b/docs/tp25-walk-messung.sh index 5339c7b..1fe3824 100755 --- a/docs/tp25-walk-messung.sh +++ b/docs/tp25-walk-messung.sh @@ -7,6 +7,9 @@ # Neuanmeldung ohnehin bei null. Ein Ping AUF das Telefon trennt beides: # Paketverlust = echte Funkstille · kein Verlust = die 4 s waren Buchhaltung. # +# Gepingt wird VOM CORE aus (Kabel bis zum AP), damit der Verlust eindeutig dem Telefon +# gehoert und nicht der Funkstrecke des messenden Laptops. +# # Braucht KEINEN Call. Misst nur, aendert nichts. # # bash docs/tp25-walk-messung.sh # laeuft bis Ctrl-C bzw. bis "Stoppen" geklickt wird @@ -28,7 +31,7 @@ mkdir -p "$RUN_DIR" # Frueheren Lauf beiseitelegen, statt ihn zu ueberschreiben. if [[ -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.log ping-dauerlauf.log; do + 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/" done echo "ts_epoch,ts_local,marker" > "$MARKERS" @@ -53,14 +56,43 @@ state "Kein Call nötig. 🚶 drücken, wenn du losgehst, 📍 wen bash "$HERE/docs/tp6-monitor-core.sh" --out "$RUN_DIR/sampler.csv" --mac "$PHONE_MAC" --interval 1 \ > "$RUN_DIR/sampler.out" 2>&1 & SAMPLER=$! -# 5 Pings/s auf das Telefon, mit lokalem Zeitstempel je Zeile -ping -i 0.2 "$PHONE" | while IFS= read -r l; do - printf '%s %s\n' "$(date +%H:%M:%S)" "$l" -done > "$RUN_DIR/walk-ping.log" 2>&1 & PINGER=$! +# 5 Pings/s auf das Telefon — GEPINGT WIRD VOM CORE, nicht von diesem Rechner. +# 🔴 Der Grund: pingt der Laptop, laeuft der Weg ueber ZWEI Funkstrecken (Laptop -> AP -> +# Core -> AP -> Telefon). Fehlt dann ein Paket, ist nicht entscheidbar, welches der +# beiden Geraete weg war. Vom Core aus ist die Strecke bis zum AP durchgehend Kabel, +# also misst der Verlust genau das, was er messen soll: den Funk zum Telefon. +# (Aufgefallen am 2026-08-21, als das MacBook waehrend einer Messung vom Dock ans +# WLAN wechselte und dabei auch noch die IP wechselte.) +PW="$(grep -m1 '^CRS326_CORE_PASS=' ~/.secrets/credentials.env | cut -d= -f2- | sed 's/^["'"'"'"'"'"']//; s/["'"'"'"'"'"']$//')" +echo "ts_local,seq,ms" > "$RUN_DIR/walk-ping.csv" +( + while true; do + sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 \ + -o ServerAliveInterval=15 admin@10.40.99.1 \ + "/ping $PHONE interval=200ms count=100000" 2>/dev/null \ + | while IFS= read -r l; do + l="${l%$'\r'}" + case "$l" in + *SEQ*HOST*) continue ;; + esac + seq="$(printf '%s' "$l" | awk '{print $1}')" + case "$seq" in + ''|*[!0-9]*) continue ;; + esac + case "$l" in + *timeout*) printf '%s,%s,\n' "$(date +%H:%M:%S)" "$seq" ;; + *) printf '%s,%s,%s\n' "$(date +%H:%M:%S)" "$seq" \ + "$(printf '%s' "$l" | awk '{print $NF}')" ;; + esac + done >> "$RUN_DIR/walk-ping.csv" + printf '%s,,RECONNECT\n' "$(date +%H:%M:%S)" >> "$RUN_DIR/walk-ping.csv" + sleep 2 + done +) & PINGER=$! -trap 'kill $SAMPLER $PINGER 2>/dev/null; pkill -f "ping -i 0.2 $PHONE" 2>/dev/null; state "Aufzeichnung gestoppt."; echo; echo "Gestoppt."' EXIT +trap 'kill $SAMPLER $PINGER 2>/dev/null; pkill -f "ping $PHONE interval=200ms" 2>/dev/null; state "Aufzeichnung gestoppt."; echo; echo "Gestoppt."' EXIT echo "Gehweg-Messung laeuft." echo " Funk -> $RUN_DIR/sampler.csv" -echo " Ping -> $RUN_DIR/walk-ping.log" +echo " Ping -> $RUN_DIR/walk-ping.csv (Quelle: crs326-core)" while true; do touch "$STATE" 2>/dev/null; sleep 5; done