#!/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