11 KiB
Atom HMI editing playbook
Updated 2026-10-20 (Edmonton). Read this before future Atom HMI work, together with SITE-STUDY.md, MANDEL-BUILD.md, and MANDEL-SETTINGS.md. Target for these experiments: https://dev.atomhmi.com/site_mandel/. Owner explicitly authorized simulation writes with restoration. Do not carry that assumption to production sites.
Fast editing: Copy/Paste works
- Open Configure Pages, select the page, wait for its Title and component tree.
- Click the Copy icon on the desired component. A root Row exports the whole subtree as plain-text JSON on the browser clipboard. Read the clipboard after the click completes; earlier empty reads were misleading.
- Save the original JSON as a backup before changes. Change the exported data and child structure, preserving component type IDs and register bindings.
- Write JSON to the browser clipboard, click Paste Element. It appends a root. An element's paste icon inserts a sibling after that element, rather than replacing it.
- Inspect the draft, remove the backed-up original root, then Save & Close. Deletions of draft elements can be discarded with Cancel before saving. Never delete the page itself as part of replacement.
- Wait for Create or Select Page and save confirmation before leaving. Open the actual runtime page and verify readings and actions.
Paste generates fresh element/data IDs. Critically, it regenerates setup behavior from the component type. Editing the exported data.setup does NOT install custom event behavior: a custom washer switch experiment reverted to its canonical switch implementation and was removed. Use native components with their supported data fields. Two-position switches write On/Off values to ONE register; separate Start and Stop command registers need two native buttons.
Reload Configure Pages between pages. Repeated live preview loads can produce Highcharts #16/JustGage errors and stale previews. Runtime verification is essential. Modal animations and controller polling create a delay: immediate checkbox/readout state is not proof of a completed PLC write. Wait for the actual output text, then restore and verify it.
Native style reference
The original Mandel Well page uses bordered equipment Rows (border border-secondary rounded my-1), compact numeric fields (my-1 col-12 col-sm-6 col-md-3, innerClasses: h-100, border + rounded, editable data w-100 btn-entry), and status pills (badge badge-pill bg-on / bg-off). Reused this on Main, Air Compressor, Chicken Coop, Pressure Washer, Ventilation, and Water Usage. Existing Well unchanged. Root JSON backups are in artifacts/mandel/before.json.
Verified simulation writes and restoration
| Register | Original | Temporary test | Verified result | Restored |
|---|---|---|---|---|
| main:g_coopHeatSP | 10 °C | 11 | readout 11 | 10 |
| main:g_coopCoolSP | 25 °C | 26 | readout 26 | 25 |
| main:g_coopDailyFanDur | 3,600,000 | 1.5 displayed hours | readout 1.5 h | 1 h |
| main:g_coopTemp_limits_hihi_in_sp | 35 °C | 36 | readout 36 | 35 |
| main:g_inLights | 0 | 1 | interior output On | 0; output Off |
| main:g_exLights | 0 | 1 | exterior output On | 0; output Off |
| main:g_pressureWasher_in_manOnMaxSP | 0 | 60000 | native Start made washer Running and valve Open | 0 |
| main:g_pressureWasher_in_autoMode | 0 Manual | 1 Auto | settled readback observed | 0 Manual |
Final native coop switches were individually tested On -> output On -> Off -> output Off. Heating/cooling/alarm entries write direct values. Daily fan duration divides by 3,600,000 for hours and writes value * 3600000 (tested through the runtime form). Preserve read/write conversion symmetry.
Washer Start/Stop command registers are momentary g_pressureWasher_in_manStart / ...in_manStop, each written 1 by its respective native button. They were enabled already and read back 0 after commands. Washer was stopped at completion; valve Closed, pump Stopped. Running it naturally increments runtime/history; do not reset accumulated operating history to disguise tests.
Chicken coop lighting
Enable polling for g_inLights and g_exLights (OPC UA addresses Home.g.inLights / Home.g.exLights). These are actual writable binary demand settings, verified against g_coopInteriorLights_out_val and g_coopExteriorLights_out_val. Native two-position switches: value/indicator expression is the corresponding command register, updateRegister the same register, On 1, Off 0. Separate indicators show physical/controller output feedback. Both commands left at 0.
Pressure washer findings
Owner clarified that a DIGITAL pressure limit switch is currently installed. Enabled and displayed main:g_pressureWasherPrsHi_out_val, a Debounced Input at OPC UA Home.g.pressureWasherPrsHi.out_val. Final observed value 1. Label it Input 0/1 until polarity and exact mechanical threshold are confirmed; do not infer a psi threshold or adjust a physical switch through analog alarm fields.
Analog g_pressureWasherPres_out_eu remains inactive (owner confirmed), observed -118.5 psi. Analog alarm limits are future commissioning settings and do not configure the digital pressure switch.
At original manual maximum run time 0, native Start did not sustain operation. With temporary 60000 and Manual mode, native Start produced Washer Running and Water Valve Open. Stop returned Washer Stopped; valve subsequently Closed. Pump remained Stopped during these brief tests. This does not establish the complete pump/interlock logic or demonstrate a successful pressure cycle. The digital limit input may be relevant, but that causal relationship is not proven.
Added editable Manual Run Time Limit using controller raw units. Its time unit has NOT been independently established, so do not label it seconds/minutes yet. Original 0 restored as requested; a suitable nonzero time limit is needed to repeat the observed manual-start test. Do not change seq_in_enable or other program-owned sequence inputs merely to force a run. Final page has native On · Start and Off · Stop buttons, Auto/Manual, separate washer/pump/valve/digital-limit status, and inactive-analog explanation.
Further work boundaries
Register descriptions and readback distinguish candidate settings from outputs, but are not a PLC program listing. Reads of raw/debounced DI values do not establish writable user settings. Expose actual configuration/command registers, preserve program-owned outputs and interlocks, and document unknown units/polarity rather than guessing. Alarm limit writes were tested on one representative coop threshold; other configured alarm targets have not all been individually exercised.
Current screenshots: artifacts/mandel/coop-final.jpg and washer-final.jpg. Register inventory and prior settings/alarm audits remain in that directory.
Cleanup, confirmed units, and non-latching alarms
Updated October 20, 2026 after owner feedback:
- Removed obsolete Temperature page (root backup
temperature-removed-backup.json) and its navigation. Removed Hot Tub navigation; there was no Hot Tub page in the page catalog. - Rebuilt Main/overview as six native equipment cards with live readings/status and direct links. Removed obsolete undefined Table and its stale shop/hot-tub bindings. Backups include
overview-before-cleanup.jsonandmain-before-cleanup.json. - Owner confirmed house volumes are gallons and flow/flow alarm limits are gpm. Water Usage and overview now show gal/gpm.
- Owner confirmed fan output is 0–10 V. Fan speed demand remains 0–100%. Updated voltage labels without scaling values.
- Chose pascals (Pa) for negative differential pressure, including its chart axis, thresholds, and hysteresis labels. Owner will scale the controller. Existing numeric readings/limits were not rescaled or changed.
- Refreshed Well header, subtitle, detail panel, charts and alarm heading; replaced broken page_wells link with Water Usage. Preserved the separate site-information/map/report root and moved it below operating controls. No Well metadata or thresholds changed.
- Set HMI Latching OFF on all 80 Main alarm definitions and the one Global alarm, Stale-Alm. Preserved calculation, enabled state, delays, severity and notification groups. The audit
nonlatching-audit.jsonrecords 81 IDs and observed before state (some false entries are verification after an earlier change). Global Stale-Alm was reopened and confirmed false. Earlier Main entries were reopened and confirmed false after a browser interruption. This changes HMI alarm latching, not any independently latched PLC source logic. - Final runtime verification: overview populated six equipment cards; Water Usage displayed gal and gpm; ventilation displayed V and Pa; Well showed live flow, totals, settings and both trends. Screenshots: overview-cleanup.jpg, water-cleanup.jpg, ventilation-cleanup.jpg, well-cleanup.jpg, nonlatching-proof.jpg.
Navigation editor caution: after deleting an entry, reload before another mutation. Its table can display new rows while event handlers still refer to prior row positions. A removed Ventilation entry was corrected during verification; final navigation has Compressor, Well, Washer, Ventilation, Coop, Water Usage and Device Status, with no Temperature/Hot Tub.
Page roots matter: Copy on the first root does not capture additional roots. Read the DOM-backed root list before replacements; preserve unrelated site-information roots. A pasted replacement appends at the bottom; use the root Up arrow to restore desired order.
Read-only context inspection, verified October 21, 2026
Use the relevant KAV-GUIDE.md, LONE-PINE-GUIDE.md, LAZY-B-GUIDE.md or SWEET-GRASS-GUIDE.md first; then inspect only the current target page/subtree. The full baseline survey need not be repeated for every task.
Native Copy succeeded in production on all four site families. Exported JSON has id, name, type, data and nested elements. Validate the copied root's identity against the current tree before interpreting the clipboard; an empty/stale clipboard is not evidence that Copy uses an internal-only format. The older SITE-STUDY.md inference has been corrected.
For a large page, enumerate top-level editor roots from the visible DOM and copy each required root separately. Resolve the direct Copy button under that root's header, rather than searching all descendant buttons. This allowed Sweet Grass Motors (1,435 elements) and old Motors (1,246) to be inspected. Do not infer a complete page from the first copied root.
Reload clean Configure Pages between previews, particularly after large charts/motor pages. On timeout, inspect current UI and clipboard identity before retrying. Keep survey batches small and record verified findings immediately; a browser-tool session reset can discard in-memory analysis.
For bindings, record display value, editable flag, updateRegister, writeValue/updateValue, limits flag and units independently. A read-only field can retain a stale write target. Legacy (Dont Use) components can have both register and updateRegister keys; behavior is not established by an internal name alone. Limit values do not enforce anything when limits=false.
This survey used Copy only and discarded editors. No production paste, Save, register command, device action or alarm test was performed. Earlier Mandel development tests remain separate evidence with separate authorization.