omni-pca/custom_components
Ryan Malloy 9ca4da98e8
Some checks are pending
Validate / HACS validation (push) Waiting to run
Validate / Hassfest (push) Waiting to run
panel: clausal chain editor (WHEN/AT/EVERY + AND/OR/THEN)
Multi-record clausal programs are now editable end-to-end. A chain
spans N consecutive slots — head (WHEN/AT/EVERY) + zero-or-more
AND/OR condition records + one-or-more THEN action records — so
"editing" means rewriting the whole run, validating that any
expansion doesn't trample adjacent programs, and clearing any old
slots when the chain shrinks.

H1 — backend:

* programs/get for chains now returns chain_members[] with each
  member's slot + role + raw fields. The editor uses this to seed
  one editable form-row per slot.
* New programs/chain/write command: takes head_slot + head dict +
  conditions[] + actions[], does N sequential download_program
  calls, then clears any old chain slots that fell outside the new
  range. Validates:
    - head_slot + new_len doesn't extend past slot 1500
    - any expansion-into slot not already part of THIS chain is FREE
      (anti-trample: refuse rather than overwrite an adjacent program)
    - at least one THEN action present (empty chain rejected)
  Updates coordinator.data.programs immediately so subsequent list
  calls reflect the edit before the next poll.

H2 — TS helpers:

* AND-record encoding mirrors compact-form cond family bytes
  (0x04 ZONE / 0x08 CTRL / 0x0C TIME / 0x00 OTHER + 0x10+ SEC) but
  with a slightly different bit layout: the family byte lives at
  fields.cond & 0xFF (disk byte 1) and the instance at
  (fields.cond2 >> 8) & 0xFF (disk byte 3). The selector bit is
  family's bit 0x02 instead of cond's 0x0200. decodeAndCondition /
  encodeAndCondition handle both directions; round-trip exact.
* isStructuredAnd helper detects records with OP > 0 (TEMP > N
  comparisons etc.); those render read-only in the chain editor
  with a warning banner.
* emptyAndRecord / emptyOrRecord / emptyThenRecord helpers for
  the add-condition / add-action buttons.

H3 — chain editor UI:

* New _chainDraft state (parallel to _editingDraft for compact form)
  with head + conditions[] + actions[] arrays. Mutation helpers
  preserve immutability via array-copy-then-patch.
* "Edit" button on chain detail now opens the chain editor instead
  of returning early (previous read-only behaviour).
* Three sub-renderers: trigger section dispatches on prog_type
  (WHEN→event-id builder reusing the EVENT helpers, AT→time+days
  reusing TIMED layout, EVERY→single seconds input that packs into
  cond+cond2), conditions section with per-row add/remove (separate
  + AND IF and + OR IF buttons in the legend), actions section with
  per-row add/remove (+ THEN button; at least one action enforced).
* Structured-OP AND records render with an explanatory read-only
  banner and a × button to drop the row entirely — preserves the
  data when the user doesn't touch it, lets them remove it cleanly
  when they want to.
* Each row picks objects via _bucketWithPreserve so out-of-range
  zone/unit/area indices stay safe.

5 new HA integration tests:
* get-chain returns chain_members with correct roles + raw fields
* chain/write in-place rewrite preserves footprint, updates bytes
* chain/write shrink clears the trailing old slots
* chain/write refuses to trample an adjacent program on expansion
* chain/write rejects zero-actions submission

Live screenshot 11-chain-editor.png: state injection into the side
panel (real panel has no chains) shows the editor rendering a sample
WHEN zone-state → AND IF unit ON → 2x THEN action chain with every
control populated and functional.

Full suite: 653 passed, 1 skipped (up from 648, 5 new chain tests).
Frontend bundle: 82 KB minified (up from 63 KB).
2026-05-17 02:09:04 -06:00
..