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