Skip to content

feat(crow_alarm_panel): raw bit-trace logging, arm/disarm retry, time-glitch recovery - #10

Merged
dan-s-github merged 5 commits into
mainfrom
dan-dev
Aug 5, 2026
Merged

feat(crow_alarm_panel): raw bit-trace logging, arm/disarm retry, time-glitch recovery#10
dan-s-github merged 5 commits into
mainfrom
dan-dev

Conversation

@dan-s-github

@dan-s-github dan-s-github commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a raw bit-trace logging toggle switch (ISR-level clock/data bit capture), joining the existing raw-frame logging toggle — useful for offline protocol decoding when DEBUG-level output isn't available on a device.
  • Fix the arm/disarm watchdog to automatically retry CODE_DIGIT_PENDING/CODE_ENTER_PENDING/ARM_AWAY_PENDING/ARM_STAY_PENDING sequences on timeout (up to 5x) instead of aborting immediately. Six traced sessions established that a timeout in these states reliably means the panel's state never changed, so a blind retry is safe (unlike output-select/zone-bypass, which don't retry). Validated on real hardware (logs-27): a disarm that previously would have silently failed and required the user to notice and retry resolved automatically in 3.8s.
  • Recover the known once-a-minute CURRENT_TIME bit-corruption glitch instead of just discarding it. Comparing corrupted frames against Home Assistant's own log timestamps confirmed day/month/year are exactly doubled by a single inserted bit, and that it originates on the panel's transmit side, not our ISR sampling (the untouched minutes_hi/minutes_lo field always matches real time exactly). Halving now recovers the frame, but only when the recovered date's weekday also matches the frame's own untouched day_of_week field — avoiding the coincidental-valid-value risk already flagged in protocol_investigations.md.
  • Extensive trace-based investigation documented in docs/protocol_trace_2026-08-05_disarm_after_arm.md and appended to docs/arm_disarm_state_machine.md / docs/protocol_investigations.md, covering the failure signatures (bus collisions, genuine silence, RX decode corruption on either the interface or the passive monitor, and the time-glitch recovery validation) that led to these fixes.

Test plan

  • uv run esphome compile crow_alarm_panel_test.yaml passes
  • Retry fix validated on real hardware (esphome-aap-alarm-interface-logs-27.txt) — automatic retry resolved a disarm failure in 3.8s with no manual intervention
  • Time-glitch recovery validated against real Home Assistant log timestamps (three independent samples, exact match to the minute)
  • Time-glitch recovery not yet validated against a live device capture showing the new ESP_LOGI recovery line fire
  • Further real-hardware validation of a multi-failure streak (3+ retries) would still be useful, per the open questions in arm_disarm_state_machine.md

🤖 Generated with Claude Code

dan-s-github and others added 3 commits July 30, 2026 21:14
Captures every clock-sampled DAT bit (post glitch-filter, same bits the
frame parser feeds into boundary_buffer_) into a batched 128-bit string,
independent of frame decoding, so mis-alignment/framing issues can be
diagnosed by hand from the literal bitstream.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Six independent traced sessions (logs-10/35, logs-12/37, logs-42,
logs-24/25/26) show a watchdog timeout in CODE_DIGIT_PENDING/
CODE_ENTER_PENDING reliably means the panel's state never changed, with
monitor cross-checks confirming no ARMED_STATE broadcast was ever missed.
Unlike output-select/zone-bypass, a blind retry here can't undo a change
that already landed, so the watchdog now retries the whole sequence
(up to ARM_DISARM_MAX_RETRIES=5, covering the worst observed streak)
before falling back to the existing abort/restore behavior. Full trace
analysis in docs/protocol_trace_2026-08-05_disarm_after_arm.md.
A disarm hit the familiar two-failure-then-success shape, but this time
the watchdog's automatic retry resolved it in 3.8s with a single user
call and no manual intervention — confirms the fix works in practice.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the crow_alarm_panel ESPHome external component with an ISR-level raw bit-trace logging toggle (to aid offline protocol decoding) and improves reliability of the arm/disarm state machine by retrying specific pending states on watchdog timeout (up to 5 times). It also adds extensive trace-based documentation capturing observed failure signatures and supporting the retry rationale.

Changes:

  • Add a log_raw_bits switch to enable ISR-side raw DAT-bit batching and INFO-level logging.
  • Update the arm/disarm watchdog to retry CODE_DIGIT_PENDING / CODE_ENTER_PENDING / ARM_AWAY_PENDING / ARM_STAY_PENDING on timeout instead of immediately aborting.
  • Add/extend protocol trace documentation and state-machine notes with new multi-session findings.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crow_alarm_panel_test.yaml Adds a fixture switch entry to toggle raw bit-trace logging.
components/crow_alarm_panel/switch/crow_alarm_panel_switch.h Declares a new switch type for raw bit-trace logging.
components/crow_alarm_panel/switch/crow_alarm_panel_switch.cpp Implements the raw bit-trace switch behavior via parent toggling.
components/crow_alarm_panel/switch/init.py Wires a new log_raw_bits typed switch into schema/codegen.
components/crow_alarm_panel/docs/protocol_trace_2026-08-05_disarm_after_arm.md Adds new trace analysis documenting failure modes and decode methodology.
components/crow_alarm_panel/docs/arm_disarm_state_machine.md Appends findings and documents the new retry behavior and rationale.
components/crow_alarm_panel/crow_alarm_panel.h Adds bit-trace buffering state and ARM/DISARM retry constants/counter.
components/crow_alarm_panel/crow_alarm_panel.cpp Implements ISR bit-trace capture/logging and watchdog retry logic.

Comment thread components/crow_alarm_panel/crow_alarm_panel.cpp Outdated
Comment thread components/crow_alarm_panel/crow_alarm_panel.cpp Outdated
Comment thread components/crow_alarm_panel/crow_alarm_panel.h Outdated
Comment thread components/crow_alarm_panel/crow_alarm_panel.h Outdated
Comparing corrupted frames against Home Assistant's own log timestamps
confirmed day/month/year are exactly doubled by a single inserted bit,
and that it originates on the panel's transmit side (minutes_hi/lo,
sent before the insertion point, always match real time exactly).
Halving now recovers the frame instead of discarding it, but only when
the recovered date's weekday also matches the frame's own untouched
day_of_week field, avoiding the coincidental-valid-value risk already
noted in protocol_investigations.md.
@dan-s-github dan-s-github changed the title feat(crow_alarm_panel): raw bit-trace logging, arm/disarm retry feat(crow_alarm_panel): raw bit-trace logging, arm/disarm retry, time-glitch recovery Aug 5, 2026
- Refresh arm_disarm_state_enter_ms_ before keypress() in the retry
  block, not after: keypress()->send_packet() can yield and re-enter
  loop(), so the watchdog could otherwise fire again on the stale
  timestamp and send extra keypresses (same fix already applied to the
  output-select retry).
- Gate the ISR's bit-trace buffer swap on !bit_trace_ready_ so it can't
  overwrite bit_trace_buffer2_ while loop() (other core) is still
  copying it out.
- Mark bit_trace_enabled_ volatile, matching ack_pending_/
  is_transmitting_.
- Reset bit_trace_len_/bit_trace_ready_ on every toggle so disabling
  mid-buffer and re-enabling can't mix stale bits into a trace chunk.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

@dan-s-github
dan-s-github merged commit 6ccd808 into main Aug 5, 2026
1 check passed
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.

2 participants