Real-hardware finding: netwatch repeatedly reported 'home WiFi not found' 4 times over 13min while sitting right next to the router. Root cause: a plain 'nmcli con up home-wifi' straight out of AP mode relies on NM's scan cache for wlan0, which is stale/empty coming out of AP mode (the radio can't scan while acting as an AP). A single con-up attempt didn't wait for a fresh scan to land before giving up. Fix: explicitly drop the AP connection first to free the radio, force a fresh scan with a settle delay, and retry the connect attempt (longer 30s timeout) up to 2 times before conceding and restoring the hotspot. Bumped the systemd unit's TimeoutStartSec to 180s to give the retry loop enough headroom (was defaulting to 90s). Co-authored-by: Copilot <[email protected]>
71 lines
2.8 KiB
Bash
Executable File
71 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# yaris-netwatch.sh
|
|
#
|
|
# Runs periodically via yaris-netwatch.timer. If wlan0 is currently in
|
|
# AP/hotspot mode, briefly attempts to reconnect to the known home WiFi.
|
|
# If that succeeds, we're back on home WiFi (used for syncing itinerary/
|
|
# dashcam data to the remote server). If it fails (still out of range),
|
|
# reactivates the hotspot so the web UI stays reachable locally in the car.
|
|
#
|
|
# The Pi's onboard WiFi radio (BCM43438) cannot act as an AP and scan for
|
|
# client networks at the same time, so this brief switch-and-check is the
|
|
# only way to detect "home WiFi is back in range" while sitting in AP mode.
|
|
# The reverse direction (home WiFi -> hotspot, i.e. leaving range) is handled
|
|
# automatically by NetworkManager's own autoconnect-priority mechanism and
|
|
# needs no watcher: the "home-wifi" profile has a higher
|
|
# connection.autoconnect-priority than Hotspot, so NM tries it first whenever
|
|
# the device needs to reconnect, and falls through to Hotspot on its own once
|
|
# home WiFi drops out of range.
|
|
|
|
set -u
|
|
|
|
LOG_TAG="yaris-netwatch"
|
|
HOME_CON="home-wifi"
|
|
AP_CON="Hotspot"
|
|
IFACE="wlan0"
|
|
LAST_LOG="/tmp/yaris-netwatch-last.log"
|
|
|
|
active_con() {
|
|
nmcli -t -f DEVICE,CONNECTION device status | awk -F: -v d="$IFACE" '$1==d {print $2}'
|
|
}
|
|
|
|
current="$(active_con)"
|
|
|
|
if [ "$current" != "$AP_CON" ]; then
|
|
# Already on home WiFi (or something else) - nothing to do.
|
|
logger -t "$LOG_TAG" "wlan0 is on '$current', no action needed"
|
|
exit 0
|
|
fi
|
|
|
|
logger -t "$LOG_TAG" "wlan0 is on hotspot, checking for home WiFi ($HOME_CON)..."
|
|
|
|
# Real-hardware finding: a plain "nmcli con up home-wifi" straight out of AP
|
|
# mode reliably reports "not found" even when actually in range, repeatedly
|
|
# (confirmed: 4 failures in a row over 13min while sitting right next to the
|
|
# router). NM's scan cache for wlan0 is stale/empty coming out of AP mode
|
|
# (the radio literally can't scan while acting as an AP - see comment above),
|
|
# and a single con-up attempt doesn't wait for a fresh scan to land before
|
|
# giving up. Fix: explicitly drop the AP connection first to free the radio,
|
|
# force a fresh scan and give it a few seconds to populate, then retry the
|
|
# connect attempt with a longer timeout up to 2 times before conceding and
|
|
# restoring the hotspot.
|
|
nmcli con down "$AP_CON" >"$LAST_LOG" 2>&1
|
|
|
|
connected=false
|
|
for attempt in 1 2; do
|
|
nmcli device wifi rescan ifname "$IFACE" >>"$LAST_LOG" 2>&1
|
|
sleep 5
|
|
if nmcli --wait 30 con up "$HOME_CON" >>"$LAST_LOG" 2>&1; then
|
|
connected=true
|
|
break
|
|
fi
|
|
logger -t "$LOG_TAG" "home WiFi attempt $attempt failed, retrying..."
|
|
done
|
|
|
|
if [ "$connected" = true ]; then
|
|
logger -t "$LOG_TAG" "home WiFi found, switched to '$HOME_CON'"
|
|
else
|
|
logger -t "$LOG_TAG" "home WiFi not found after retries, restoring hotspot"
|
|
nmcli con up "$AP_CON" >>"$LAST_LOG" 2>&1
|
|
fi
|