Declare disabled modes per YAML output and bind #130
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/yn-12-disabled-modes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
YAML outputs and binds take
disabled_modes(night, lights_out, away, travel; default none). On an output, entering a listed mode switches it off and it refuses to turn on until the mode ends; on a bind, presses and on-edges are ignored in a listed mode while off-edges still act. The hard-coded occupancy rule is gone (fromOccupancyremoved). Hand-written nodes keep themodeSwitchesOffsemantic-class default; a generated node always sets its mask, so an empty list means nothing is switched off. Shutdown stays a one-shot off.The endpoint lock sits in one place per endpoint type, where each turns its output on:
SwitchEndpoint::setOn,LevelEndpoint::requestandColourEndpoint::setBrightness. All bus commands, binds and local toggles end there.Spec 7 and 9.5 get one-sentence edits; schema regenerated; README gains a Modes section with the recommended lists; the c3 fixture uses the field on an endpoint and a bind.
Tested: native 607 -> 614 (new test_disabled_modes, colour lock test, YN-8 bind tests moved to masks plus a listed-press case); Python 39 -> 43 with jsonschema installed;
pio runand the c3 fixture build pass.YN-12
No blockers. Four small points.
@ -362,2 +362,3 @@`MODE_LIGHTS_OUT` stays on. Modes are an instruction at a moment in time, not apersistent lock. A node acts when the mode changes from the one it holds: apersistent lock. A node may, as local policy, hold an endpoint off for theduration of a mode it lists. A node acts when the mode changes from the one it holds: aThe inserted sentence leaves one over-long line; reflow the paragraph.
@ -61,6 +61,7 @@ void ColourEndpoint::loop(Node&, uint32_t now) {}void ColourEndpoint::setBrightness(uint8_t brightness) {if (brightness > 0 && locked_) return;When locked, ColourEndpoint::setOn still returns true (via transition()) and starts a transition. Switch and Level return false via refuse() and mark dirty. Make the colour path consistent.
Behaviour change for existing YAML nodes: every output now emits setDisabledModes(), even with an empty list. That switches off the semantic default, so a YAML light no longer goes off on lights_out/travel, and occupancy binds no longer skip away/travel/night, unless the YAML lists them. README says this is intended (empty by default). Confirm that is what you want, because existing node files change meaning silently.
parse_disabled_modes: duplicates (['away','away']) pass here but the schema has uniqueItems, so they disagree. A non-string entry such as x raises TypeError (unhashable in dict lookup) instead of a clean fail(). Check isinstance(mode, str) and reject duplicates.
@ -27,6 +27,7 @@ void SwitchEndpoint::applyOutput() {}bool SwitchEndpoint::setOn(bool on, uint32_t, uint16_t) {if (on && locked_) return refuse();This reads like it can be turned on in a locked state, but not off, is this correct?
@ -91,0 +100,4 @@]},"default": [],"description": "Modes in which the output is switched off and held off. Shutdown always switches it off."Remove "Shutdown always switches it off"