docs: Edit-programs-in-HA how-to + side-panel reference + MDX fixes
New how-to walks through the Omni Programs side panel end-to-end:
list view, filters, the detail panel, compact-form editing, the
clausal chain editor, structured-AND with Arg2-as-object, known
limits, and the websocket commands the panel speaks. Five
embedded screenshots from a real .pca fixture.
reference/ha-entities.md picks up a short callout near the top so
readers browsing entity docs don't miss the side panel.
program-format.mdx had three pre-existing unescaped '<' characters
('firmware <3.0' and '(family << 8)' inside a table) that were
breaking the MDX build. Replaced with 'before 3.0' and escaped
operators.
This commit is contained in:
parent
7bbe1b4372
commit
de02f10be7
BIN
src/assets/screenshots/programs-detail.png
Normal file
BIN
src/assets/screenshots/programs-detail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 325 KiB |
BIN
src/assets/screenshots/programs-editor-chain.png
Normal file
BIN
src/assets/screenshots/programs-editor-chain.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 146 KiB |
BIN
src/assets/screenshots/programs-editor-compact.png
Normal file
BIN
src/assets/screenshots/programs-editor-compact.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 356 KiB |
BIN
src/assets/screenshots/programs-editor-structured.png
Normal file
BIN
src/assets/screenshots/programs-editor-structured.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
BIN
src/assets/screenshots/programs-list.png
Normal file
BIN
src/assets/screenshots/programs-list.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
206
src/content/docs/how-to/edit-programs-in-ha.mdx
Normal file
206
src/content/docs/how-to/edit-programs-in-ha.mdx
Normal file
@ -0,0 +1,206 @@
|
||||
---
|
||||
title: Edit panel programs from Home Assistant
|
||||
description: Browse, search, clone, and edit the panel's built-in automation programs from a Home Assistant side panel — no PC Access required.
|
||||
sidebar:
|
||||
order: 5
|
||||
---
|
||||
|
||||
import { Image } from 'astro:assets';
|
||||
import shotList from '../../../assets/screenshots/programs-list.png';
|
||||
import shotDetail from '../../../assets/screenshots/programs-detail.png';
|
||||
import shotCompact from '../../../assets/screenshots/programs-editor-compact.png';
|
||||
import shotChain from '../../../assets/screenshots/programs-editor-chain.png';
|
||||
import shotStructured from '../../../assets/screenshots/programs-editor-structured.png';
|
||||
|
||||
The integration registers a side-panel item called **Omni Programs**
|
||||
that lets you view and edit the panel's built-in automation programs
|
||||
without opening PC Access. These are the **panel-side** programs that
|
||||
run on the Omni controller itself (so they survive HA outages), as
|
||||
opposed to HA automations which run inside HA.
|
||||
|
||||
Open Home Assistant in your browser. **Omni Programs** appears in the
|
||||
left sidebar alongside Overview, Map, Energy, etc.
|
||||
|
||||
<Image src={shotList} alt="Omni Programs side panel showing a list of panel programs with WHEN/THEN summaries, trigger-type badges, and a search box" style="border: 1px solid color-mix(in srgb, currentColor 25%, transparent); border-radius: 6px; margin: 1rem 0;" />
|
||||
|
||||
## Browsing & filtering
|
||||
|
||||
The header shows the total program count (`330 programs` on the panel
|
||||
this screenshot was taken against). Each row is one program — for
|
||||
multi-record clausal chains the row shows the **head** slot and
|
||||
collapses the chain into a single summary line.
|
||||
|
||||
- **Search** — typing into the search box filters by any visible text
|
||||
in the summary (program names, object names, command labels).
|
||||
- **Trigger-type chips** — `TIMED` / `EVENT` / `YEARLY` / `WHEN` / `AT`
|
||||
/ `EVERY` / `REMARK`. Click to toggle each filter; combinations are
|
||||
OR'd. The right-edge badge on each row tells you the trigger type
|
||||
and condition count.
|
||||
- **References filter** — programs referencing a specific object
|
||||
(zone, unit, area, button, thermostat) can be filtered from the HA
|
||||
entity page: open any zone/unit/etc. entity, scroll to *Related*,
|
||||
and click the program count to jump into the side panel pre-filtered
|
||||
to that object.
|
||||
|
||||
The list updates in real time as the panel pushes program changes —
|
||||
no manual refresh needed.
|
||||
|
||||
## The detail panel
|
||||
|
||||
Click any row to open the detail panel on the right.
|
||||
|
||||
<Image src={shotDetail} alt="Detail panel for slot 1 showing structured-English breakdown 'WHEN OPEN BIG GAR is pressed AND IF Time clock 4 is disabled THEN Turn ON Unit 33025' and four action buttons: Fire now, Edit, Clone, Clear" style="border: 1px solid color-mix(in srgb, currentColor 25%, transparent); border-radius: 6px; margin: 1rem 0;" />
|
||||
|
||||
The structured-English breakdown is the same renderer that produces
|
||||
the row summary, but expanded — one clause per line, conditions in
|
||||
context.
|
||||
|
||||
Four actions:
|
||||
|
||||
- **Fire now** — executes the program's THEN action immediately,
|
||||
bypassing any conditions or schedule. Equivalent to PC Access's
|
||||
"Test" button.
|
||||
- **Edit** — opens the inline editor (see below).
|
||||
- **Clone…** — duplicates the program into a different slot. Prompts
|
||||
for the target slot number; refuses to overwrite a non-empty slot.
|
||||
- **Clear** — wipes the slot to all zeros (`FREE`). Confirmation
|
||||
required; this is sent to the panel as `DownloadProgram` with a
|
||||
zero body, matching PC Access's "Delete" behaviour.
|
||||
|
||||
## Editing a compact-form program
|
||||
|
||||
Compact-form programs (`TIMED`, `EVENT`, `YEARLY`, `REMARK`) fit
|
||||
entirely in one 14-byte record — the editor lays them out as a single
|
||||
form with trigger fields up top, the action in the middle, and up to
|
||||
two inline AND-IF conditions at the bottom.
|
||||
|
||||
<Image src={shotCompact} alt="Compact-form program editor for an EVENT-triggered program showing Category (Button press), Button (#1 OPEN BIG GAR), Action (Turn ON unit #33025), and an inline AND-IF on Time clock 4 disabled" style="border: 1px solid color-mix(in srgb, currentColor 25%, transparent); border-radius: 6px; margin: 1rem 0;" />
|
||||
|
||||
The form adapts to the trigger type:
|
||||
|
||||
- **TIMED** — hour / minute (or sunrise/sunset offset) + days-of-week
|
||||
bitmask.
|
||||
- **EVENT** — a category dropdown (Button press / Zone state change /
|
||||
Unit state change / Fixed event), then category-specific sub-fields.
|
||||
For example, *Button press* shows a button picker; *Zone state
|
||||
change* shows zone + becomes-state.
|
||||
- **YEARLY** — month + day-of-month picker.
|
||||
- **REMARK** — read-only in this release (see [known
|
||||
limits](#known-limits) below).
|
||||
|
||||
The action section is a command picker plus a parameter input whose
|
||||
shape follows the command. *Turn ON unit* shows a unit picker; *Arm
|
||||
area Night* shows an area picker; *Execute button* shows a button
|
||||
picker.
|
||||
|
||||
The two inline AND-IF slots each get a Family dropdown (Zone / Unit /
|
||||
Time clock / Misc / Area in security mode) and per-family sub-fields.
|
||||
|
||||
Hit **Save** to write the program back to the panel via
|
||||
`DownloadProgram`. The integration validates the form server-side
|
||||
before sending: bad ranges produce a structured error, not a corrupt
|
||||
program.
|
||||
|
||||
## Editing a multi-record chain
|
||||
|
||||
Programs with `prog_type` ≥ 5 (`WHEN` / `AT` / `EVERY`) are
|
||||
**clausal chains** — one record per visual line, occupying sequential
|
||||
slots in the program table. The editor presents the whole chain as
|
||||
one logical unit even though it's stored across multiple slots.
|
||||
|
||||
<Image src={shotChain} alt="Chain editor for a WHEN program showing the trigger header (Zone state change / FRONT_DOOR / not ready), a Conditions section with one AND IF row (Unit state / LIVING_LAMP / ON), and an Actions section with a THEN row (Turn ON unit / #2 KITCHEN_OVERHEAD)" style="border: 1px solid color-mix(in srgb, currentColor 25%, transparent); border-radius: 6px; margin: 1rem 0;" />
|
||||
|
||||
The editor has three sections:
|
||||
|
||||
- **Trigger header** (top) — the `WHEN` / `AT` / `EVERY` record.
|
||||
- **Conditions** — zero or more `AND IF` / `OR IF` rows. Use the
|
||||
`+ AND IF` button to add a row to the current group, or `+ OR IF` to
|
||||
start a new alternative group. Each row has an `×` button to remove
|
||||
it.
|
||||
- **Actions** — one or more `THEN` rows. Use `+ THEN` to add another
|
||||
action; chains can fire multiple actions in sequence.
|
||||
|
||||
**Anti-trample** — when you Save, the editor writes only the slots
|
||||
needed for the current chain layout. If you remove a condition or
|
||||
action, the slots it used to occupy are explicitly cleared so no
|
||||
half-stale records linger on the panel.
|
||||
|
||||
## Structured-AND conditions
|
||||
|
||||
Most AND IF rows use the **Traditional** form (family + instance +
|
||||
operand — "Zone 5 is SECURE", "Unit 12 is ON", etc). But the panel
|
||||
also supports **Structured** AND records that compare a typed field
|
||||
against either a constant or another typed field:
|
||||
|
||||
> AND IF Thermostat 1 Current temperature **>** Thermostat 2 Current temperature
|
||||
|
||||
The editor renders these as a dedicated form with operator picker
|
||||
and per-arg type pickers:
|
||||
|
||||
<Image src={shotStructured} alt="Structured-AND editor showing Arg1 (Thermostat #1 LIVING_ROOM Current temperature), Operator (>), and Arg2 (Thermostat #2 MASTER_BEDROOM Current temperature) — both sides are typed references rather than constants" style="border: 1px solid color-mix(in srgb, currentColor 25%, transparent); border-radius: 6px; margin: 1rem 0;" />
|
||||
|
||||
**Arg1** can be any of: Zone, Unit, Thermostat, Area, Time/Date.
|
||||
Each type has its own field selector — for Thermostat that's
|
||||
*Current temperature / Heat setpoint / Cool setpoint / System mode /
|
||||
Humidity / …*; for Zone it's *Loop reading / Current state / …*.
|
||||
|
||||
**Operator** is one of: `==`, `!=`, `<`, `>`, `is odd`, `is even`,
|
||||
`is multiple of`, `in (bitmask)`, `not in (bitmask)`. The unary
|
||||
operators (`is odd` / `is even`) hide the Arg2 controls entirely.
|
||||
|
||||
**Arg2** can be:
|
||||
|
||||
- **Constant** (default for new structured rows) — a 0..65535 value.
|
||||
Used for "TEMP > 70", "Zone.CurrentState == 1", etc.
|
||||
- **A typed reference** — Zone / Unit / Thermostat / Area / TimeDate
|
||||
with its own field selector. This is how you author cross-object
|
||||
comparisons like "Thermostat 1 temp > Thermostat 2 temp" or
|
||||
"Zone 1 reading > Zone 2 reading".
|
||||
|
||||
Switching Arg2 from Constant to a reference type re-populates the
|
||||
form with the appropriate picker; switching back preserves the
|
||||
numeric value.
|
||||
|
||||
For the wire format behind all this, see the
|
||||
[Program record format reference](/reference/program-format/#structured-op-and-records-op--0).
|
||||
|
||||
## Known limits
|
||||
|
||||
The editor covers the common cases but a few program shapes are
|
||||
deliberately presented read-only — they're preserved verbatim on
|
||||
Save, you just can't reshape them in the form:
|
||||
|
||||
- **REMARK programs** — read-only. The `remark_id` → text lookup
|
||||
table layout is documented but the editor doesn't expose it yet.
|
||||
- **Exotic Arg1/Arg2 types** on structured-AND — `UserSetting`,
|
||||
`Auxiliary`, `Audio`, `AccessControl`, `Message`, `System`. These
|
||||
show as a read-only banner with an `×` remove button.
|
||||
- **Non-zero `CompConst`** on structured-AND — rarely used; preserved
|
||||
but not exposed as a form control.
|
||||
- **Multi-panel installs** — the side panel currently shows the
|
||||
first configured panel. If you have multiple Omni panels, the
|
||||
other panels' programs aren't accessible from the side panel yet.
|
||||
|
||||
## Where the data lives
|
||||
|
||||
The side panel is a Lit web component (`<omni-panel-programs>`)
|
||||
registered via Home Assistant's `panel_custom` integration. It talks
|
||||
to the integration's websocket API directly — there's no separate
|
||||
state machine, no caching, no debouncing. Each user action becomes
|
||||
one websocket round-trip:
|
||||
|
||||
| Action | Websocket command |
|
||||
|---|---|
|
||||
| List view + filters | `omni_pca/programs/list` |
|
||||
| Open detail panel | `omni_pca/programs/get` |
|
||||
| Fire now | `omni_pca/programs/fire` |
|
||||
| Save (compact) | `omni_pca/programs/write` |
|
||||
| Save (chain) | `omni_pca/programs/write_chain` |
|
||||
| Clone… | `omni_pca/programs/clone` |
|
||||
| Clear | `omni_pca/programs/clear` |
|
||||
|
||||
All seven commands validate input server-side and produce structured
|
||||
errors (no opaque tracebacks) on bad input. The websocket layer's
|
||||
own tests cover the contract — see `tests/ha_integration/
|
||||
test_program_websocket.py` in the source tree if you want to extend
|
||||
the API surface.
|
||||
@ -10,6 +10,13 @@ refresh; live state propagates over the panel's unsolicited push channel
|
||||
within one TCP round-trip, with a 30-second poll backstopping anything that
|
||||
didn't push.
|
||||
|
||||
In addition to the entity catalogue below, the integration registers an
|
||||
**Omni Programs** sidebar item — a dedicated UI for browsing, editing,
|
||||
cloning, and firing the panel's built-in automation programs (the
|
||||
panel-side rules that run on the controller itself, distinct from HA
|
||||
automations). See the [edit-programs-in-ha
|
||||
how-to](/how-to/edit-programs-in-ha/) for the walkthrough.
|
||||
|
||||
| Platform | Entity | Per |
|
||||
|---|---|---|
|
||||
| `alarm_control_panel` | Area arm/disarm with code | discovered area |
|
||||
|
||||
@ -347,7 +347,7 @@ The block fits in **one** 14-byte record. `prog_type` is `TIMED`,
|
||||
- For `EVENT`, the event identifier replaces the calendar
|
||||
month/day at bytes 9-10 (see [the EVENT `Evt` u16 section](#also-for-event-bytes-910-are-an-event-identifier-not-a-date)).
|
||||
|
||||
This is how 100% of records in any panel running firmware <3.0 are
|
||||
This is how 100% of records in any panel running firmware before 3.0 are
|
||||
encoded. It is also how PC Access encodes any block that fits the
|
||||
constraints, even on firmware ≥3.0 — see the simplification rules
|
||||
in `frmAutomationEditBlock.cs:589 SimplifyLines`.
|
||||
@ -398,7 +398,7 @@ The firmware gate is `Features.Add(MultiLinePrograms, 196608u)` in
|
||||
`clsCapOMNI_PRO_II.cs:290` (the 24-bit value packs as
|
||||
`major*65536 + minor*256 + revision` → 3.0.0).
|
||||
|
||||
When MultiLinePrograms is OFF (firmware <3.0):
|
||||
When MultiLinePrograms is OFF (firmware before 3.0):
|
||||
|
||||
- PC Access's `Or` toolbar button and "Add Comment Block" menu item
|
||||
are disabled.
|
||||
@ -420,7 +420,7 @@ load on a real 2.16A panel.
|
||||
| Byte(s) | Field | Notes |
|
||||
| --- | --- | --- |
|
||||
| 0 | `prog_type` | = 5 |
|
||||
| 9-10 (BE u16) | event-id | `(family << 8) | instance` — same encoding as compact-form `EVENT`'s bytes 9-10 in wire form. **No** Mon/Day file-form swap. |
|
||||
| 9-10 (BE u16) | event-id | `(family \<\< 8) \| instance` — same encoding as compact-form `EVENT`'s bytes 9-10 in wire form. **No** Mon/Day file-form swap. |
|
||||
| 1-8, 11-13 | zeros | (action lives in a separate `THEN` record) |
|
||||
|
||||
#### `AT` (ProgType=6) — single-occurrence time trigger
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user