Conversation
The v1 ESP-NOW sync packet carries timing only, so a node's identity on the mesh is inferred rather than stated, and its condition is not reported at all. Two consequences: the server guesses which node a sync came from, and a node that is overheating, has rebooted, or is running low on heap looks identical to a healthy one until it stops responding entirely. v2 extends the packet to 38 bytes, adding the node's own MAC and a NodeHealth block: die temperature, thermal state, transmit power, minimum heap seen, and the reset reason. The reset reason is the useful part operationally. reset_reason_name() renders it, and rebooted_badly() distinguishes a panic or watchdog reset from a deliberate software restart -- a node that reboots quietly and rejoins looks healthy from the outside, and the distinction is what separates "somebody updated it" from "it is crashing". Version-gated so a v1 node keeps parsing exactly as before, and a padded v1 packet explicitly yields no MAC rather than reading whatever happened to sit in those bytes. Both cases are covered by tests. Co-Authored-By: claude-flow <ruv@ruv.net>
These boards sit on walls with no console attached. Until now a panic, a
watchdog reset, a brownout or a thermal trip was written to a serial port
nobody is reading, so from the operator's side an unhealthy node was
indistinguishable from a healthy one.
The ESP-NOW sync packet already reaches the host every beacon interval and had
reserved bytes free, so the health fields ride along at no extra cost -- no new
socket, no polling, no additional airtime on a channel already at 86%.
Adds to NodeSyncSnapshot:
health the parsed NodeHealth from the sync packet
reset_reason human-readable form, so a dashboard need not carry its own
copy of the esp_reset_reason_t table. Owned rather than
borrowed: the snapshot is Deserialize and a &'static str
cannot round-trip through JSON.
rebooted_badly true for a panic, watchdog or brownout -- the cases worth
surfacing without being asked
Receiver half only, deliberately. A node on older firmware leaves the
formerly-reserved bytes zeroed and simply reports no health, so this is safe to
deploy ahead of the firmware that populates them. The firmware side is a
separate change.
Co-Authored-By: claude-flow <ruv@ruv.net>
rywg8tcyrc-droid
approved these changes
Sep 5, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
These boards sit on walls with no console attached. Until now a panic, a
watchdog reset, a brownout or a thermal trip was written to a serial port
nobody is reading, so from the operator's side an unhealthy node was
indistinguishable from a healthy one.
The ESP-NOW sync packet already reaches the host every beacon interval and had
reserved bytes free, so the health fields ride along at no extra cost -- no new
socket, no polling, no additional airtime on a channel already at 86%.
Adds to NodeSyncSnapshot:
health the parsed NodeHealth from the sync packet
reset_reason human-readable form, so a dashboard need not carry its own
copy of the esp_reset_reason_t table. Owned rather than
borrowed: the snapshot is Deserialize and a &'static str
cannot round-trip through JSON.
rebooted_badly true for a panic, watchdog or brownout -- the cases worth
surfacing without being asked
Receiver half only, deliberately. A node on older firmware leaves the
formerly-reserved bytes zeroed and simply reports no health, so this is safe to
deploy ahead of the firmware that populates them. The firmware side is a
separate change.
Rebased onto current
mainbefore opening: staged before today's seven merges, so it needed replaying to avoid reading as a revert of them. Clean rebase, no files deleted.