Add NODE_WATER_HEATER (0x41) firmware #69

Merged
rob merged 3 commits from feat/water-heater-node into main 2026-09-22 09:50:41 +00:00
Collaborator

Adds a controller for the immersion element: one EP_SWITCH endpoint driving a 12 V relay module through a 2N7000 open-drain on D1, failsafe FS_OFF.

The runtime only had LevelEndpoint, which accepts CMD_LEVEL and drives PWM — not something a mains relay coil should be able to receive. This adds ctrl::SwitchEndpoint, a plain digital output modelled on LevelEndpoint but without dimming, fading or CMD_LEVEL handling.

Node allocated at 0x41 in the water range, following CONTRIBUTING.md's "Allocating a node" checklist: node_ids.h, the spec's node table, node_water_heater/main.cpp, the [env:], and the README's controllers and pin tables.

Tested with pio test -e native (443 cases, including the new test_switch_endpoint suite) and pio run -e node_water_heater.

Adds a controller for the immersion element: one `EP_SWITCH` endpoint driving a 12 V relay module through a 2N7000 open-drain on D1, failsafe `FS_OFF`. The runtime only had `LevelEndpoint`, which accepts `CMD_LEVEL` and drives PWM — not something a mains relay coil should be able to receive. This adds `ctrl::SwitchEndpoint`, a plain digital output modelled on `LevelEndpoint` but without dimming, fading or `CMD_LEVEL` handling. Node allocated at `0x41` in the water range, following CONTRIBUTING.md's "Allocating a node" checklist: `node_ids.h`, the spec's node table, `node_water_heater/main.cpp`, the `[env:]`, and the README's controllers and pin tables. Tested with `pio test -e native` (443 cases, including the new `test_switch_endpoint` suite) and `pio run -e node_water_heater`.
Add NODE_WATER_HEATER (0x41) firmware
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
cb40c5c140
Claude left a comment

Checked SwitchEndpoint against docs/can-protocol.md 5.1/5.2/8.3/8.4/9.3 (EP_SWITCH, CMD_SWITCH, STATE_SWITCH, failsafe) and the manual-lockout/failsafe/forward-compat invariants in CLAUDE.md — all consistent. node_ids.h's sources list, the spec's node table, README's controller and pin tables, and platformio.ini's default_envs/[env:node_water_heater] all stayed in lockstep, and 0x41 is a valid allocation in the Water range (0x40–0x5F) per CONTRIBUTING.md. main.cpp matches node_kitchen/node_bathroom's shape with nothing extra (no settings, no timer). Comments explain why, not what. pio test -e native -f test_switch_endpoint and clang-format --dry-run --Werror both pass clean.

test_switch_endpoint.cpp genuinely exercises the behaviour asked for: CMD_SWITCH on/off/toggle with STATE_SWITCH decode, 0xFF addressing, CMD_LEVEL correctly returning unhandled, the lockout rejecting Automation and Remote origins while still marking the endpoint dirty for re-broadcast, failsafe Off switching off on bus loss (even while inside an active lockout) and setting the failsafe flag, and MODE_SHUTDOWN switching it off.

One non-blocking nit: the tests construct the shared ctrl::Node node with can::node::water (0x40) rather than can::node::waterHeater (0x41) — cosmetic only, doesn't affect what's being exercised.

No other findings — approving would be my own PR, which Forgejo blocks, so leaving this as a comment review instead.

Checked SwitchEndpoint against docs/can-protocol.md 5.1/5.2/8.3/8.4/9.3 (EP_SWITCH, CMD_SWITCH, STATE_SWITCH, failsafe) and the manual-lockout/failsafe/forward-compat invariants in CLAUDE.md — all consistent. node_ids.h's `sources` list, the spec's node table, README's controller and pin tables, and platformio.ini's `default_envs`/`[env:node_water_heater]` all stayed in lockstep, and 0x41 is a valid allocation in the Water range (0x40–0x5F) per CONTRIBUTING.md. `main.cpp` matches node_kitchen/node_bathroom's shape with nothing extra (no settings, no timer). Comments explain why, not what. `pio test -e native -f test_switch_endpoint` and `clang-format --dry-run --Werror` both pass clean. test_switch_endpoint.cpp genuinely exercises the behaviour asked for: CMD_SWITCH on/off/toggle with STATE_SWITCH decode, 0xFF addressing, CMD_LEVEL correctly returning unhandled, the lockout rejecting Automation and Remote origins while still marking the endpoint dirty for re-broadcast, failsafe Off switching off on bus loss (even while inside an active lockout) and setting the failsafe flag, and MODE_SHUTDOWN switching it off. One non-blocking nit: the tests construct the shared `ctrl::Node node` with `can::node::water` (0x40) rather than `can::node::waterHeater` (0x41) — cosmetic only, doesn't affect what's being exercised. No other findings — approving would be my own PR, which Forgejo blocks, so leaving this as a comment review instead.
Use the water heater node id in its own test
All checks were successful
Build and test / build (pull_request) Successful in 1m12s
Build and test / release (pull_request) Has been skipped
1174169de5
Claude left a comment

Nit fix confirmed. 1174169 replaces every can::node::water with can::node::waterHeater across all four sites in test_switch_endpoint.cpp (the shared node, switchCommand, the level-command test, and localNode in the failsafe test). Grepped the file afterwards: no remaining can::node::water references. The commit is a clean rename, nothing else changed.

Re-ran pio test -e native: 443/443 pass, including test_switch_endpoint. clang-format clean on all touched files. Glanced over the rest of the branch diff (node_ids.h, platformio.ini, README, spec, SwitchEndpoint, node_water_heater/main.cpp) — nothing new since the last pass.

Clean to merge (can't self-approve, so leaving this as a comment review rather than APPROVED).

Nit fix confirmed. `1174169` replaces every `can::node::water` with `can::node::waterHeater` across all four sites in test_switch_endpoint.cpp (the shared `node`, `switchCommand`, the level-command test, and `localNode` in the failsafe test). Grepped the file afterwards: no remaining `can::node::water` references. The commit is a clean rename, nothing else changed. Re-ran `pio test -e native`: 443/443 pass, including `test_switch_endpoint`. clang-format clean on all touched files. Glanced over the rest of the branch diff (node_ids.h, platformio.ini, README, spec, SwitchEndpoint, node_water_heater/main.cpp) — nothing new since the last pass. Clean to merge (can't self-approve, so leaving this as a comment review rather than APPROVED).
rob merged commit c4b30d4dd3 into main 2026-09-22 09:50:41 +00:00
rob deleted branch feat/water-heater-node 2026-09-22 09:50:41 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rob/CampervanControlSystems!69
No description provided.