Skip to content

Say something the first time the device sends something we do not read - #40

Merged
matuszeg merged 1 commit into
mainfrom
map-unhandled-messages
Aug 25, 2026
Merged

matuszeg merged 1 commit into
mainfrom
map-unhandled-messages

Conversation

@matuszeg

Copy link
Copy Markdown
Owner

Two of the three message types in #13 are now decoded, from the shim's 14-day access log and the pcaps rather than from guessing.

GET /tm is a clock sync. The vendor answers {"utctime":1786659941836}. It fires on the four-hourly re-auth beat and in the device's reconnect burst, 516 times in 14 days, and it explains why the device's own timestamps sit within a second of ours.

POST /pump_outlet_alerts is not a pump event. All 12 occurrences in the same 14 days land inside that reconnect burst, in the same second as /tm, /oauth/token and /bbs_parameters. The one captured body is idPumpAlertType: 105, recordNumber: 0, value: 0 and the vendor replies {"numRows":-1}, so it reads as "nothing to report" for an outlet subsystem this hardware may not have. Type 3 pings were already decoded in the issue as motor current in amps.

No entities for any of them, which is the decision #13 asked for. Type 3 duplicates mamp, which we already record and already distrust after two identical self-tests reported 5.54 A and 11.83 A. Alert 105 carries a zero. /tm is a request for data rather than data.

What they do earn is being noticed. Pump alerts have parsed cleanly for months and then been dropped without a word; unread ping types vanish inside a comparison in apply_ping; the unknown-field warning was at INFO, which the live install never prints because it logs this integration at WARNING. core/novelty.py now warns on the first sighting of an unfamiliar path, ping type, alert type or bbs_json field, and drops to debug for every one after it. Loud enough to survive a production log level, quiet enough not to nag about something that arrives daily, and it doubles as a firmware-change alarm.

Two cases it deliberately stays quiet about. The four paths we answer rather than read (/tm, /oauth/token, /new_firmware, /bbs_parameters) are mapped, not mysterious, and warning about them would fire on every healthy install. And a body that failed to parse arrives here looking exactly like a path with no parser, so it is excluded by name: the parser has already warned about that, and "nothing here reads /bbs_json" would be false.

Also moved: parse_bbs_json used to log unknown fields itself and now carries them on the reading instead, so one thing decides what is worth saying and says it once.

Verified beyond the unit tests: the end-to-end test drives a real captured pump-alert body through the listener over a socket, twice, and asserts exactly one warning comes out. The cadence figures above are from /var/log/nginx/pumpspy.log on the shim, and the /tm response body is read out of pit_all.pcap.

Closes #13

Three message types have been sitting in the captures unexplained. Two of
them are now decoded, from the shim's access log and the pcaps rather
than from guessing.

/tm is a clock sync: the device asks what time it is and the vendor
answers {"utctime": <milliseconds>}. It rides the four-hourly re-auth
beat and the reconnect burst, 516 times in fourteen days, and it explains
why the device's own timestamps land within a second of ours.

/pump_outlet_alerts is not a pump event. All twelve occurrences in the
same fourteen days fall inside that reconnect burst, in the same second
as /tm and /oauth/token. The one captured body carries type 105, record
0, value 0, and the vendor replies {"numRows":-1}. Type 3 pings were
already decoded as motor current in amps.

None of the three earns an entity. Type 3 duplicates mamp, which is
already recorded and already distrusted; alert 105 carries a zero; /tm is
a request for data rather than data.

What they earn is being noticed. Pump alerts parsed cleanly and were then
dropped without a word, unread ping types vanished inside a comparison,
and the unknown-field line was at INFO, which the live install never
prints because it logs this integration at WARNING. So the first sighting
of anything unfamiliar now warns, and every one after it is a debug line:
audible where it matters, and not a daily nag for a message that arrives
daily. The four paths we answer rather than read stay quiet, because
warning about those would fire on every healthy install and say nothing.

Closes #13
@matuszeg
matuszeg merged commit d50b3b2 into main Aug 25, 2026
3 checks passed
@matuszeg
matuszeg deleted the map-unhandled-messages branch August 25, 2026 11:12
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.

Map the message types found in captures but not handled

1 participant