fix: make remote soft wake idempotent#83
Conversation
tadelv
left a comment
There was a problem hiding this comment.
Approve. The threading footgun (#1) is respected: the WS handler (AsyncTCP task) and BLE handler (BLE host task) defer via wsReplacePending/remoteReplacePending and never call wakeScaleFromSoftSleep/scale.powerUp()/digitalWrite(PWR_CTRL,…)/u8g2.setPowerSave directly — everything drains from processWsPendingCmds on loop(). The USB path runs on the loop task, so its direct hw calls are safe there. Mirrors the existing button-wake idempotency guard. b_softSleep/b_u8g2Sleep are volatile. Consistent guard across all three transports. Correctly fixes the v3.1.12 0.0g blip.
Minor (non-blocking):
- WS/BLE else-branch doesn't clear
WSP_SLEEP_ON. The real-wake branch doeswsReplacePending(WSP_SLEEP_OFF, WSP_SLEEP_ON)(clears a concurrent sleep-on); the else-branch doeswsReplacePending(WSP_DISPLAY_ON, WSP_DISPLAY_OFF)which leaves a concurrently-queued SLEEP_ON alive. Very narrow race and low impact, but for symmetry considerwsReplacePending(WSP_DISPLAY_ON, WSP_DISPLAY_OFF | WSP_SLEEP_ON). - The test is static source-shape (ordered snippet matching), not runtime — fine as a contract guard, just be honest that it doesn't exercise the duplicate-while-awake path.
Suggestion (separate from this PR): same note as on #81 — these contract tests grep source structure rather than run the logic. Pulling the wake/state-machine into a pure, host-compilable unit and asserting real behavior (no hardware) would be stronger and would let the firmware logic be tested independently of the device.
Summary
Fixes the brief
0.0gweight blip seen afterv3.1.12when a BLE or WiFi client repeatedly sends a wake / soft-sleep-off command while the scale is already awake.Why It Happens
v3.1.12added ADS1232 recovery on real soft-sleep wake so the scale does not stay stale or stuck after the ADC power rail comes back. That was correct for an actual transition from sleep to awake.The Decent BLE command
030A04 00is also sent by clients as a keep-awake style command. Inv3.1.11, duplicate wake commands only turned the display / power rails on, so they did not affect the current weight. Inv3.1.12, the same duplicate command went throughwakeScaleFromSoftSleep(), which callsscale.powerUp(), refreshes the ADS dataset, and resets the public displayed weight. That left a short window where BLE / WiFi could report0.0gbefore the next ADC sample restored the real weight.What This Fixes
Wake commands are now idempotent:
b_softSleepis true, this is a real wake and the ADS wake / refresh path still runs.b_softSleepis false, the scale is already awake, so duplicate wake commands only restore the display state and do not refresh/reset the ADS output.The fix covers BLE,
/snapshotWebSocket, and USB command paths so the same protocol behavior stays consistent across transports.Validation
python tools\test_soft_sleep_ads_wake.pyrtk proxy pio run -e esp32s3/snapshotsmoke: realsoft_sleep on/soft_sleep offstill works.soft_sleep offno longer logsremote soft wake dataset refreshed, confirming the ADS refresh path is skipped while already awake.