Skip to content

obd: stop posting "adapter asleep or car off" on every boot (#56, #31) - #65

Open
ThinkOffApp wants to merge 1 commit into
mainfrom
fix/no-data-post-on-every-boot
Open

ThinkOffApp wants to merge 1 commit into
mainfrom
fix/no-data-post-on-every-boot

Conversation

@ThinkOffApp

Copy link
Copy Markdown
Owner

Fixes #56. Also fixes #31, which is the same root cause.

@eclass sent petrus the identical line at 12:58Z and 13:06Z on 15 Sep, car parked at home.

Two faults, one cause

1. The epoch marker was a local variable. no_data_posted = False — obdwatch restarts on every boot and every rfcomm rebind, so each fresh process cleared the flag and re-sent the line.

This file already learned that lesson. A few lines above:

DEEP_STAMP is a PERSISTED once-per-day marker on disk, not an in-memory flag: the old in-memory deep_done reset on every wireless rfcomm0 flap, so the "one-time" scan re-ran mid-drive (claudemm, Aug 19).

Same failure, same file, not applied. The marker now lives on disk — that is #31.

2. It should not be sent on a cold boot at all. Waking up next to a parked car is not an event, it is the normal resting state, and it was arriving as a phone notification. Now gated on seen_data, so it fires only as a real data → lost transition, which is what #56 asks for. The resting fact still appears in the presence and preflight tiles, where a state belongs rather than an alert.

A suppressed post is logged, so the behaviour is visible in the journal instead of silent.

Safety

Stamp bookkeeping never raises — a read-only or missing state dir logs and carries on. Losing the read loop is worse than one duplicate post.

Tests

tests/test_no_data_post.py, 5 cases: persistence across a restart, clearing on a successful reading, clearing an absent marker, an unwritable stamp path, and an assertion that the seen_data gate is still present in the loop so a refactor cannot quietly drop it.

The suite's one failure on this branch is test_dash_loop's missing pytest, which is pre-existing on main and fixed separately in #64.

Not verified on the car

The car is not reachable right now (no vadelma node in tailscale). This is reasoned from the code path and the timestamps in the issue, and the tests exercise the marker directly — but the boot behaviour itself has not been observed on Vadelma.

🤖 Generated with Claude Code

@eclass sent petrus the identical line at 12:58Z and 13:06Z on 15 Sep with the
car parked at home. Two faults, one root cause.

`no_data_posted` was a local variable. obdwatch restarts on every boot and
every rfcomm rebind, so each fresh process started with the flag cleared and
re-sent the same line to his phone. This file already learned that lesson once
- DEEP_STAMP a few lines above is persisted precisely because the in-memory
`deep_done` reset on rfcomm flaps - and it was not applied here. The epoch
marker now lives on disk (#31).

The second fault is that the line should not be sent on a cold boot at all.
Waking up next to a parked car is not an event, it is the normal resting
state, and it was arriving as a notification. It is now gated on `seen_data`,
so it posts only as a genuine data -> lost TRANSITION, which is what #56 asks
for. The resting fact still shows in the presence and preflight tiles, where
a state belongs. A suppressed post is logged, so the behaviour is visible in
the journal rather than silent.

Stamp bookkeeping never raises: a read-only or missing state dir logs and
carries on, because losing the loop is worse than one duplicate post.

Tests cover persistence across a restart, clearing on a successful reading,
clearing an absent marker, an unwritable stamp path, and an assertion that the
`seen_data` gate is still in the loop so a refactor cannot quietly drop it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
carwatch-dev Ready Ready Preview Sep 18, 2026 4:34pm UTC

Request Review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-18T16:36:55.643380Z ea8f2a9 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ea8f2a91d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread carwatch/obdwatch.py
# made the "LIVE 29s" badge grow to a minute between updates).
else:
if not last_post_readings and not no_data_posted:
if not last_post_readings and not no_data_posted and seen_data:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Detect data loss despite the stored successful reading

When a successful poll is followed by result["ok"] == False while the adapter path remains present, last_post_readings still contains the successful line, so this condition is false regardless of seen_data. Because the persistent rfcomm service can leave /dev/rfcomm0 bound while the gateway stops answering, the intended data-to-lost transition can occur without any reconnect clearing this value, and the new alert is never posted.

Useful? React with 👍 / 👎.

Comment thread carwatch/obdwatch.py
Comment on lines +502 to +505
elif not last_post_readings and not seen_data:
print("obdwatch: no engine data and none seen this session "
"- not posting (car is simply off)", flush=True)
last_post_readings = "(failed)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the first success eligible after suppressing boot noise

On the targeted cold-boot path, an asleep car reaches this branch and stores the truthy "(failed)" sentinel. If the ignition subsequently wakes the gateway without /dev/rfcomm0 disappearing, the first successful poll has first == False, no previous DTC with which to detect a change, and no battery baseline for a milestone; therefore it is not posted, seen_data remains false, and the stamp is not cleared. Ordinary later successes remain in the same state, suppressing both the expected initial engine reading and future loss notifications for the lifetime of the process.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants