Repository navigation
Add a network watchdog that recovers a WiFi link that stopped carrying traffic - #1282
Merged
Merged
Conversation
…g traffic A device can stay associated to the AP (WiFi.status() == WL_CONNECTED) while nothing it sends gets through, for instance on a marginal link where beacons are still heard but data frames are not. Nothing noticed this state, so a device could stay unreachable for days with a long uptime, until it was physically moved. Ping the gateway once a minute (3 echo requests). When it stops answering, restart WiFi with a full scan after 3 minutes, then with a doubling backoff (6, 12, 24, 48 minutes), and reboot after an hour with the new reboot cause REBOOT_CAUSE_NETWORK_UNREACHABLE. On ESP32 a watchdog restart also allows 802.11b rates until the next reboot, which are more robust on a marginal link. The watchdog is only armed once the gateway has answered after boot, so a gateway that blocks ping or a network that never comes up can not cause restarts or reboot loops. It only runs in WiFi client mode and is paused during firmware upgrades. The number of restarts, the longest outage, and the AP, channel and RSSI when the gateway stopped answering are kept in the reset data container (survives software reboots on ESP32) and exposed in sysinfo.json together with the current AP and channel. The policy is a plain class tested on native (pio test -e native_watchdog); the ping is a thin wrapper around ping_sock on ESP32 and the SDK ping on ESP8266. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔧 PR Build ArtifactsVersion: All environments built successfully. Download the zip files:
|
Contributor
|
Flott forbedring! Regner med dette er hos Goman. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Two HAN-powered Pow-U+ units (ESP32-S2, v2.5.7) at the same site went silent while still running. One had a long uptime but was unreachable on the LAN and sent nothing to the cloud. It came back the moment it was physically moved 50 cm. The second went silent a few days later in what looks like the same state.
The firmware only trusts
WiFi.status(). The driver keeps reportingWL_CONNECTEDas long as it hears the AP, even when none of the device's own frames get through, which happens on a marginal link with 802.11b disabled. The only existing recovery is the MQTT auto-reboot, and MQTT wasn't configured on these units, so nothing ever acted.What it does
disconnect(), so the next connect does an all-channel scan and skips the pinned last-AP retry from Reduce WiFi connect current draw on bus powered devices #1272, because the current AP is the suspect;WiFiClientConnectionHandler::allow11b()), since those rates are more robust on a marginal link;REBOOT_CAUSE_NETWORK_UNREACHABLE(14).ResetDataContainer(no-init RAM, so they survive software reboots on ESP32): watchdog restarts, the longest outage, and the AP, channel and RSSI when the gateway first stopped answering. They're exposed insysinfo.jsonnext to the current AP and channel:Structure
NetworkWatchdog: the policy only (timing, arming, escalation, stats). No Arduino or ping code; unit tested on native.GatewayPing: a non-blocking ping usingping_sockon ESP32 and the SDKping_start()on ESP8266.handleNetworkWatchdog()in the main sketch wires the two together and does the logging and the actions.Notes for review
ResetDataContainergained fields aftermagic, and the magic is bumped from0x4ato0x4bso leftovers from older firmware are cleared. As a result, the first boot after upgrading reports no previous reboot cause.connect(), and I haven't verified how to undo them safely.ex_causeas a raw number, so the new cause 14 needs no UI or translation change.sysinfo.jsongained a field, which may matter for the public API docs.Testing
pio test -e native_watchdog: 7 tests, covering never arming, the probe interval, a healthy network, the 3/6/12/24/48 → 60 min schedule, the reset on recovery, and outage recording. It's added to both CI workflows.pio test -e nativeandnative_configstill pass.pio runfor esp32s2, esp32 and esp8266 builds.wifi.wdinsysinfo.jsonfilling in.ex_cause14 with the stats preserved.🤖 Generated with Claude Code