Skip to content

Back off from failed connections and test the firmware natively - #2

Merged
ni-c merged 1 commit into
mainfrom
fix/connection-backoff
Oct 20, 2026
Merged

ni-c merged 1 commit into
mainfrom
fix/connection-backoff

Conversation

@ni-c

@ni-c ni-c commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Refs #1. v1.1 fixed most of the drain; this covers what is left.

Why

v1.1 sleeps a fixed 6 hours after one failed WiFi attempt. Three problems remain:

  • 6 hours is longer than the ESP8266 can sleep at once. ESP.deepSleepMax() is 2³¹ RTC ticks, about 3.5 hours.
  • One router reboot at the wrong moment costs 6 hours of data.
  • If WiFi works but the MQTT broker does not answer, the device stays awake 25 seconds every 5 minutes, about 4.7 %/day by the numbers in Battery drains if WiFi is not available or working #1. The extended sleep never triggers in that case.

What

  • Backoff: failed attempts are counted in RTC memory. The wait doubles from 10 minutes to at most 2 hours (BACKOFF_MAX_SLEEPTIME). The first transmission after a failure returns to 5 minutes and reports connectFailures.
  • Single 5-minute sleeps: a wake that only counts down goes straight back to sleep with the radio and the sensor off. No sleep ever exceeds SLEEPTIME.
  • Broker timeout counts like a WiFi failure.
  • Early abort: in regular-connect mode, WL_NO_SSID_AVAIL, WL_CONNECT_FAILED and WL_WRONG_PASSWORD give up at once instead of after 20 s. The quick connect keeps its 5 s fallback.
  • OTA mode never waits, and a connection made in OTA mode resets the counters as well.
  • Battery percentage: an ADC value below 863 used to wrap around and gave a garbage percentage. The value is now computed in integers and clamped to 0..100, so a full battery reads 100 instead of 99.
  • ESPTEMP_VERSION is v1.2, and the platform is pinned to espressif8266@4.2.1 (core 3.1.2).

Tests and CI

src/main.cpp now also runs natively against small fakes of the Arduino core and its libraries (test/support/fakes). 23 Unity tests (pio test -e native) drive the real setup() and loop(): first boot, quick connect and its fallback, corrupt and unreadable RTC, the full 10/20/40/80/120/120-minute schedule, early abort per status, broker timeout, recovery, counter saturation, low-battery cutoff and its boundary, payload rounding and size, and OTA.

  • Coverage is 99.4 % of lines and 98 % of branches. The one line left is the closing brace after ESP.deepSleep().
  • Six deliberate mutations (no early abort, 6 h cap, no reset, no clamp, no broker backoff, OTA honouring the wait) each turn the suite red.
  • The new ci.yml runs the tests with a coverage floor (90 % lines, 80 % branches) and builds the firmware: RAM 36.6 %, flash 31.3 %.
  • Dependabot stays off in this repository. The actions are pinned by SHA.

Before merge

To test on hardware: switch WiFi off and watch the attempts at 10/20/40/80/120 minutes, then switch it on again (connectFailures in the next message). Stop the broker. Check normal operation and OTA.

When WiFi was down, v1.1 slept a fixed 6 hours after one failed
attempt. That is longer than the ESP8266 can sleep at once
(ESP.deepSleepMax(), about 3.5 hours), a single router reboot cost 6
hours of data, and a broker that does not answer was not covered at all:
the device stayed awake 25 seconds every 5 minutes.

Failed attempts are now counted in RTC memory, and the wait doubles
from 10 minutes to at most 2 hours (BACKOFF_MAX_SLEEPTIME). It is made
of single 5-minute deep sleeps; a wake that only counts down keeps the
radio and the sensor off. A broker timeout counts like a WiFi failure,
a connection the access point refuses outright is given up at once, the
first transmission reports the failures before it as connectFailures,
and OTA mode never waits. The battery percentage is clamped to 0..100
and computed in integers, so a full battery reads 100 instead of 99.

src/main.cpp now also runs on the build machine against fakes of the
Arduino core and its libraries (test/support/fakes); 23 Unity tests
drive the real setup() and loop() and cover 99 % of the lines. CI runs
them with a coverage floor and builds the firmware.
@ni-c ni-c added the bug Something isn't working label Oct 20, 2026
@ni-c ni-c self-assigned this Oct 20, 2026
@ni-c ni-c added the bug Something isn't working label Oct 20, 2026
@ni-c
ni-c merged commit c905d07 into main Oct 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant