Generate node firmware from YAML #120

Open
Claude wants to merge 74 commits from feat/yaml-nodes into main
Collaborator

A node can now be described in nodes/*.yaml and built with NODE=nodes/x.yaml pio run -e gen_xiao_c3|gen_xiao_s3|gen_lolin32. Endpoints react to other endpoints, local or on another node, through binds (toggle/follow) in the runtime, with a strategy per target endpoint type; a mode bind on a button broadcasts SYS_MODE. Outputs and binds declare the modes that disable them with disabled_modes. Settings (toggle, duration, percentage) are remembered across restarts and can gate an input's binds (enabled_by), tune an occupancy hold, a follow bind's on_delay and run_time, or a dimmer's night_brightness; each of those also takes a plain literal. Format and ID rules are in nodes/README.md; spec section 4 reserves wire IDs 0–10, section 7 defines lights and fans by semantic class and lets a node hold a listed endpoint off for a mode's duration, and section 9.5 covers binds, follow timing, the night level and mode binds. nodes/node.schema.json is a JSON Schema generated from the generator's tables, for front ends; CI fails if it is stale. nodes/ holds no node yet; test nodes live in scripts/tests/fixtures/.

Types: light, fan, load, dimmable_light, variable_fan, colour_light (WS2805 strip), switch, touch, occupancy, temperature, toggle, duration, percentage.

Merges #117 (docs), #118 (runtime binds, SwitchInput), #119 (generator), #121 (schema), #122 (script tests moved to scripts/tests/), #123 (sample node moved to the fixtures), #124 and #125 (output types; mode rules by semantic class), #126 (occupancy binds suppressed in modes, since replaced), #127 (pins list on PWM outputs), #128 (strapping pins warn instead of failing), #129 (bind strategy per target type), #130 (disabled_modes), #131 (touch), #132 (colour_light), #134 (toggle and duration settings, enabled_by), #133 (follow on_delay and run_time), #135 (percentage and night_brightness) and #136 (mode binds).

Behaviour changes to existing code: SwitchEndpoint writes its off level before pinMode and takes an optional invert; modeSwitchesOff decides by semantic class rather than endpoint type; Node::addBind returns whether the bind was accepted; LevelEndpoint::request takes a remember flag, default true; the SYS_MODE handler is now Node::applyMode, so a node can set its own mode. No existing node's behaviour changes; the water heater's final pin level is unchanged.

Tested in CI: native suite, the generator and schema unit tests, and a build of every test fixture on its board's env (C3, S3, LOLIN32). Not run on hardware; dimmer PWM resolution is calculated, not bench-checked.

YN-1 to YN-18.

A node can now be described in `nodes/*.yaml` and built with `NODE=nodes/x.yaml pio run -e gen_xiao_c3|gen_xiao_s3|gen_lolin32`. Endpoints react to other endpoints, local or on another node, through binds (`toggle`/`follow`) in the runtime, with a strategy per target endpoint type; a `mode` bind on a button broadcasts `SYS_MODE`. Outputs and binds declare the modes that disable them with `disabled_modes`. Settings (`toggle`, `duration`, `percentage`) are remembered across restarts and can gate an input's binds (`enabled_by`), tune an occupancy `hold`, a follow bind's `on_delay` and `run_time`, or a dimmer's `night_brightness`; each of those also takes a plain literal. Format and ID rules are in `nodes/README.md`; spec section 4 reserves wire IDs 0–10, section 7 defines lights and fans by semantic class and lets a node hold a listed endpoint off for a mode's duration, and section 9.5 covers binds, follow timing, the night level and mode binds. `nodes/node.schema.json` is a JSON Schema generated from the generator's tables, for front ends; CI fails if it is stale. `nodes/` holds no node yet; test nodes live in `scripts/tests/fixtures/`. Types: `light`, `fan`, `load`, `dimmable_light`, `variable_fan`, `colour_light` (WS2805 strip), `switch`, `touch`, `occupancy`, `temperature`, `toggle`, `duration`, `percentage`. Merges #117 (docs), #118 (runtime binds, `SwitchInput`), #119 (generator), #121 (schema), #122 (script tests moved to `scripts/tests/`), #123 (sample node moved to the fixtures), #124 and #125 (output types; mode rules by semantic class), #126 (occupancy binds suppressed in modes, since replaced), #127 (`pins` list on PWM outputs), #128 (strapping pins warn instead of failing), #129 (bind strategy per target type), #130 (`disabled_modes`), #131 (`touch`), #132 (`colour_light`), #134 (`toggle` and `duration` settings, `enabled_by`), #133 (follow `on_delay` and `run_time`), #135 (`percentage` and `night_brightness`) and #136 (`mode` binds). Behaviour changes to existing code: `SwitchEndpoint` writes its off level before `pinMode` and takes an optional `invert`; `modeSwitchesOff` decides by semantic class rather than endpoint type; `Node::addBind` returns whether the bind was accepted; `LevelEndpoint::request` takes a `remember` flag, default true; the `SYS_MODE` handler is now `Node::applyMode`, so a node can set its own mode. No existing node's behaviour changes; the water heater's final pin level is unchanged. Tested in CI: native suite, the generator and schema unit tests, and a build of every test fixture on its board's env (C3, S3, LOLIN32). Not run on hardware; dimmer PWM resolution is calculated, not bench-checked. YN-1 to YN-18.
Document YAML nodes
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
6cbb123122
Fix bind ID wording in the YAML nodes README
All checks were successful
Build and test / build (pull_request) Successful in 1m38s
Build and test / release (pull_request) Has been skipped
c244558b78
Match the YAML nodes README example to the agreed shape
All checks were successful
Build and test / build (pull_request) Successful in 1m43s
Build and test / release (pull_request) Has been skipped
fc1a2bb6bf
Add endpoint binds and a switch input to the node runtime
All checks were successful
Build and test / build (pull_request) Successful in 1m51s
Build and test / release (pull_request) Has been skipped
edc0623f55
Ignore a source already on at first contact for toggle binds
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
f21e5f9a33
Track bind sync from level reports, not any frame
All checks were successful
Build and test / build (pull_request) Successful in 1m39s
Build and test / release (pull_request) Has been skipped
0153b30659
Fix follow after a quiet source and a fresh first press
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
beb8ff226d
Skip the failsafe while another follow source is on
All checks were successful
Build and test / build (pull_request) Successful in 1m41s
Build and test / release (pull_request) Has been skipped
d38492d531
Generate node firmware from a YAML file at build time
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
9baf9b75d8
Build generator fixtures in CI and write the off level before the pin mode
All checks were successful
Build and test / build (pull_request) Successful in 2m1s
Build and test / release (pull_request) Has been skipped
2bf3424bf5
Merge pull request 'Generate node firmware from a YAML file at build time' (#119) from feat/yaml-generator into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 5m8s
Build and test / release (pull_request) Has been skipped
c6580261e2
Publish a JSON Schema for node YAML
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
8017ddd541
Cover binds and limits in the schema tests
All checks were successful
Build and test / build (pull_request) Successful in 5m10s
Build and test / release (pull_request) Has been skipped
8b67eed4cf
Merge pull request 'Publish a JSON Schema for node YAML' (#121) from feat/yaml-schema into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 1m59s
Build and test / release (pull_request) Has been skipped
702359a872
Move the YAML node script tests into scripts/tests
All checks were successful
Build and test / build (pull_request) Successful in 5m8s
Build and test / release (pull_request) Has been skipped
5b7a36f344
Merge pull request 'Move the YAML node script tests into scripts/tests' (#122) from chore/yaml-test-folder into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m1s
Build and test / release (pull_request) Has been skipped
b3e41087ce
Move the shed sample node into the test fixtures
All checks were successful
Build and test / build (pull_request) Successful in 5m8s
Build and test / release (pull_request) Has been skipped
28a79669be
Merge pull request 'Move the shed sample node into the test fixtures' (#123) from chore/shed-to-fixtures into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 5m18s
Build and test / release (pull_request) Has been skipped
6a19bbecf6
Let modes reach relay lights and fans via what an output drives
All checks were successful
Build and test / build (pull_request) Successful in 5m9s
Build and test / release (pull_request) Has been skipped
24edf4b1ea
Drop the EndpointType overload of modeSwitchesOff
All checks were successful
Build and test / build (pull_request) Successful in 2m4s
Build and test / release (pull_request) Has been skipped
ffdb3208c2
Replace relay, dimmer and drives with light, fan and load output types
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
773936a9d9
Tidy the output type tables and fixture label
All checks were successful
Build and test / build (pull_request) Successful in 1m59s
Build and test / release (pull_request) Has been skipped
cc0ecb6704
Merge pull request 'Let modes reach relay lights and fans through output types' (#124) from feat/yaml-drives into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m22s
Build and test / release (pull_request) Has been skipped
25313b40de
Rename dimmable_fan to variable_fan
All checks were successful
Build and test / build (pull_request) Successful in 5m49s
Build and test / release (pull_request) Has been skipped
c8cf41a2b5
Merge pull request 'Rename dimmable_fan to variable_fan' (#125) from chore/variable-fan into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m10s
Build and test / release (pull_request) Has been skipped
365d613a17
Suppress occupancy binds in Away, Travel and Night fans
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
acbaefaef5
Keep suppressed occupancy out of follow state and change toggles
All checks were successful
Build and test / build (pull_request) Successful in 5m18s
Build and test / release (pull_request) Has been skipped
bec36c63fe
Merge pull request 'Suppress occupancy binds in Away, Travel and Night fans' (#126) from feat/yn-8-suppress-occupancy-binds into feat/yaml-nodes
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
81ec9de458
Let PWM outputs drive several pins with a pins list
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
7dbebc445f
Require unique pins in the schema and drop the parallel field list
All checks were successful
Build and test / build (pull_request) Successful in 5m10s
Build and test / release (pull_request) Has been skipped
669d77a31c
Merge pull request 'Let PWM outputs drive several pins with a pins list' (#127) from feat/yaml-pins-list into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 5m9s
Build and test / release (pull_request) Has been skipped
7b3c71344a
Warn on strapping pins instead of rejecting them
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
325389674e
Tidy the strapping note in the schema generator
All checks were successful
Build and test / build (pull_request) Successful in 5m12s
Build and test / release (pull_request) Has been skipped
e4ea477abc
Merge pull request 'Warn on strapping pins instead of rejecting them' (#128) from feat/yaml-strapping-warning into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m3s
Build and test / release (pull_request) Has been skipped
461d5b29d9
Move bind actions into a per-target-type strategy
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
e5af0a1a63
Return whether Node::addBind accepted the bind
All checks were successful
Build and test / build (pull_request) Successful in 5m14s
Build and test / release (pull_request) Has been skipped
149c9d6353
Return the decoded bind source event by value
All checks were successful
Build and test / build (pull_request) Successful in 2m6s
Build and test / release (pull_request) Has been skipped
077a1752bc
Merge pull request 'Move bind actions into a per-target-type strategy' (#129) from feat/yn-11-bind-strategy into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 5m56s
Build and test / release (pull_request) Has been skipped
0e92ec45d3
Declare disabled modes on YAML outputs and binds
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
c572d664e5
Reflow the section 7 mode paragraph
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
2b7d0e1f22
Drop the shutdown sentence from the disabled_modes description
All checks were successful
Build and test / build (pull_request) Successful in 2m1s
Build and test / release (pull_request) Has been skipped
3db19a1b1a
Merge pull request 'Declare disabled modes per YAML output and bind' (#130) from feat/yn-12-disabled-modes into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 1m59s
Build and test / release (pull_request) Has been skipped
939a8e85ac
Add a touch input type to YAML nodes
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
709a0a64a5
Reject non-finite touch thresholds and share the report interval
All checks were successful
Build and test / build (pull_request) Successful in 5m13s
Build and test / release (pull_request) Has been skipped
aabea8fba6
Merge pull request 'Add a touch input type to YAML nodes' (#131) from feat/yaml-touch into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m3s
Build and test / release (pull_request) Has been skipped
dd6c2076d0
Add a colour_light type for an addressable strip
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
40db24b5f0
Drop the unused endpoint type from the colour_light entry
All checks were successful
Build and test / build (pull_request) Successful in 5m10s
Build and test / release (pull_request) Has been skipped
003db30a63
Merge pull request 'Add a colour_light type for an addressable strip' (#132) from feat/yaml-colour-light into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m4s
Build and test / release (pull_request) Has been skipped
c17b321df0
Add duration and toggle setting types to YAML nodes
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
6eb5c29dda
Say when a duration default is missing and that enabled_by has no effect yet
All checks were successful
Build and test / build (pull_request) Successful in 5m12s
Build and test / release (pull_request) Has been skipped
21e4e14c6a
Gate binds on an input's enabled_by toggle
All checks were successful
Build and test / build (pull_request) Successful in 2m2s
Build and test / release (pull_request) Has been skipped
4e58d80719
Keep tracking a gated bind's source and skip only the action
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
eb5c84f0e8
Reset the gate between bind tests
All checks were successful
Build and test / build (pull_request) Successful in 2m49s
Build and test / release (pull_request) Has been skipped
1ad97076cf
Merge pull request 'Add duration and toggle setting types to YAML nodes' (#134) from feat/yaml-settings into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 5m37s
Build and test / release (pull_request) Has been skipped
c77345f65a
Drop a pending turn-on when the mode or gate has since disabled it
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
df07a0f825
Add on_delay and run_time to YAML follow binds
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
7f0da75a55
Keep a pending turn-on out of the follow sources that count as on
All checks were successful
Build and test / build (pull_request) Successful in 2m3s
Build and test / release (pull_request) Has been skipped
894f7113d5
Merge pull request 'Add on-delay and run time to follow binds' (#133) from feat/yn-16-follow-timing into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m4s
Build and test / release (pull_request) Has been skipped
91003b71fe
Add night_brightness and a percentage setting to YAML nodes
Some checks failed
Build and test / release (pull_request) Has been cancelled
Build and test / build (pull_request) Has been cancelled
e9f194989a
Keep the remembered level when a bind turns on at the night level
All checks were successful
Build and test / build (pull_request) Successful in 5m18s
Build and test / release (pull_request) Has been skipped
4ec6c01aa0
Merge pull request 'Add night_brightness to dimmable lights and a percentage setting' (#135) from feat/yn-17-night-brightness into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 2m5s
Build and test / release (pull_request) Has been skipped
3331744c95
Add mode binds to YAML switch and touch endpoints
Some checks failed
Build and test / build (pull_request) Has been cancelled
Build and test / release (pull_request) Has been cancelled
a92252e173
Cover the mode bind gate and share the mode names
All checks were successful
Build and test / build (pull_request) Successful in 5m19s
Build and test / release (pull_request) Has been skipped
564c6e5492
Merge pull request 'Add a mode bind action that broadcasts SYS_MODE from a button' (#136) from feat/yn-18-mode-bind into feat/yaml-nodes
All checks were successful
Build and test / build (pull_request) Successful in 5m22s
Build and test / release (pull_request) Has been skipped
124cc9c9cb
All checks were successful
Build and test / build (pull_request) Successful in 5m22s
Required
Details
Build and test / release (pull_request) Has been skipped
Required
Details
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin "feat/yaml-nodes:feat/yaml-nodes"
git switch "feat/yaml-nodes"
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
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!120
No description provided.