Skip to content

Auto-recover a wedged radio, fix SMS send timeout (v0.9.0) - #22

Merged
samplec0de merged 1 commit into
mainfrom
fix/auto-recover-registration
Aug 24, 2026
Merged

Auto-recover a wedged radio, fix SMS send timeout (v0.9.0)#22
samplec0de merged 1 commit into
mainfrom
fix/auto-recover-registration

Conversation

@samplec0de

Copy link
Copy Markdown
Owner

The problem

A SIM800C that the network de-registers can settle into AT+CREG? state 0not registered, not searching — and stay there indefinitely, while the signal sensor keeps reporting a healthy value. AT+COPS=0 answers ERROR in that state; only a radio power-cycle re-attaches the module. Seen in the wild: six days unregistered, noticed only when a scheduled SMS failed with NotRegistered.

Recovering by hand then exposed a second bug: the wait for +CMGS was 15s, but the network needs 16–25s to accept a multi-part UCS2 (Cyrillic) message. On timeout the modem stayed in text-entry mode and swallowed every subsequent AT command, so all three retries — and the call poll with them — failed against a modem that looked completely dead.

Changes

  • Modem.reset_radio()AT+CFUN=0 → settle → AT+CFUN=1, then poll AT+CREG? for up to 90s. Re-runs initialize() on success, because AT+CFUN resets SMS text mode and caller-ID reporting.
  • ModemHub.async_check_registration() — registration watchdog, run every minute from the existing monitor loop; triggers recovery after 10 minutes down.
  • ModemHub.async_recover_registration() — guarded recovery: single-flight lock, 30-minute cooldown, skipped while a call is in progress.
  • sim800c.send_sms makes one recovery attempt on NotRegistered and retries the message once, instead of surfacing the error immediately.
  • Send path: +CMGS timeout 15s → 60s, and any failure inside the transaction sends ESC so the modem leaves text-entry mode.

sensor.sim800c_network now refreshes once a minute as a side effect (previously only on the 5-minute sensor poll).

Testing

99 passed (9 new), ruff check and ruff format --check clean. New tests cover the CFUN sequence and its re-initialization, the re-registration timeout, the watchdog's grace period / cooldown / call guard, and both send-path outcomes. The manual CFUN cycle and the 16–23s +CMGS timings were verified against real hardware (SIM800 R14.18, MegaFon).

https://claude.ai/code/session_01M4WjTTexBxNnym1Gq79pLV

A SIM800C that the network de-registers can settle into AT+CREG? state 0
(not registered, not searching) and stay there indefinitely while still
reporting a healthy signal. AT+COPS=0 answers ERROR in that state; only a
radio power-cycle re-attaches the module. Observed in the wild: six days
unregistered, noticed only when an SMS failed.

The background monitor now re-reads registration every minute and cycles
the radio (AT+CFUN=0/1) once it has been down for 10 minutes, waiting up
to 90s for re-registration and re-running initialize() afterwards, since
AT+CFUN resets SMS text mode and caller-ID reporting. Cycles are spaced
30 minutes apart and skipped during a call. send_sms makes one recovery
attempt of its own before giving up.

Also fixes the send path that turned this into a dead modem: the wait for
+CMGS was 15s against a network that needs 16-25s for a multi-part UCS2
message, and on timeout the modem stayed in text-entry mode, swallowing
every later AT command. The timeout is now 60s and any failure inside the
transaction sends ESC to leave text-entry mode.

Claude-Session: https://claude.ai/code/session_01M4WjTTexBxNnym1Gq79pLV
@samplec0de
samplec0de merged commit 55327dc into main Aug 24, 2026
3 checks passed
@samplec0de
samplec0de deleted the fix/auto-recover-registration branch August 24, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant