quickapp-ui
Skill1 starsChanged 15 days agoMITView on GitHub
HC3 QuickApp UI at runtime: self:updateView(...) for every element type (label, button, slider, switch, select, multi) — which properties and values each accepts (text, value, visible, disabled, image, min/max/step, color, options, selectedItem/selectedItems/values), the value rules (strings, select matching by option value, not text), the UI event contract (onReleased/onLongPress*/onToggleOn/onToggleOff/onChanged/onToggled and their event.values shapes), and how to assert or drive UI state in tests (self:getView(), _FLUA.uiEvent, /plugins/callUIEvent). USE FOR: changing UI elements at runtime, updating a label/slider/select from QA code, debugging why an updateView call does not show in the viewer, wiring UI callbacks.
In this repository18 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .github/copilot-instructions.mdCopilot instructions
- code-tourSkill
- flua-setupSkill
- flua-troubleshootingSkill
- hc3-lua-scenesSkill
- hc3-rest-apiSkill
- hc3-write-safetySkill
- lua-basicsSkill
- network-device-testSkill
- plua-migrationSkill
- quickapp-apiSkill
- quickapp-patternsSkill
- quickapp-testSkill
- quickapp-troubleshootingSkill
- quickapp-typesSkill
- qwikchildSkill
- skill-creatorSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 66
disabled: only disables buttons and sliders in the viewer.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
QuickApp UI at Runtime: updateView, Events, Viewer Semantics
How UI elements change while the QA runs. For the --%%u: directive syntax that
declares the elements, see /quickapp-types; this skill covers what happens
after that — self:updateView, the callback events, and how the flua viewer
renders each element. flua matches the HC3 5.221 behavior; where they differ,
it is called out below.
The one method: self:updateView
self:updateView(componentName, property, value)It writes value under property for the named component (HTTP
/plugins/updateView). The viewer merges this live state over the declared
element on every poll, and self:getView() returns the merged view — assert
UI state with it.
updateView reference per element
- label —
text(string, HTML allowed:<font color='red'>,<table>, …) - button —
text(string),image(named icon from the viewer's icon set; unknown names render text-only),disabled(bool) - slider —
value(string),min/max/step(strings),unit(string, rendered right of the value: "21 °C"),color(CSS color, sets the thumb),disabled(bool) - switch —
value("true"/"false"strings),text,image - select (single) —
selectedItem(scalar),options(full replacement of the option list),values(list; the 5.221 schema reads the first entry),text(the placeholder shown when nothing matches) - multi —
selectedItems(list of values),options,values,text - every element —
visible(bool;falsehides the element — it takes no row space)
self:updateView("statusLbl", "text", "Zone 1: 21.5°C")
self:updateView("setpoint", "value", "21.5")
self:updateView("autoSwitch", "value", "true")
self:updateView("modeSelect", "selectedItem", "eco")
self:updateView("modeSelect", "options", {{type='option',text='Eco',value='eco'},
{type='option',text='Manual',value='manual'}})
self:updateView("tagMulti", "selectedItems", {"1", "3"})
self:updateView("warnLbl", "visible", false)Value rules that bite
- Values are strings. Sliders and switches compare by string; always
tostring(n)numbers.updateView("s", "value", 75)renders but compares as"75"on the wire — pass strings deliberately. selectedItemmatches an option'svalue, not itstext. Setting the label (e.g."Partly cloudy"when the option values areclear,rain, …) selects nothing and the dropdown shows its placeholder. Normalize the value to the option-value vocabulary before the call.optionsreplaces the whole list — send the complete new list, not a delta. It is a structure change (the dropdown rebuilds).selectedItemsis a Lua table,selectedItema scalar. On the HC3, using"values"where the canonical property applies silently does nothing; preferselectedItem/selectedItems.disabledonly disables buttons and sliders in the viewer; switches and selects ignore it (HC3 UI parity — usevisibleto hide instead).- Viewer precedence: live
updateViewstate wins over the user's last click on the element, which wins over the declared directive value. The QA is not expected to echo the user's interaction back — but once the QA sets a live value, it wins until changed again.
The UI event contract
The viewer delivers interactions through event = {deviceId, eventType,
elementName, values}. Wire callbacks with the directive's event keys
(--%%u:{slider='s',text='S',onChanged='handler'}); the QA method receives
the event table.
- button —
onReleased,onLongPressDown,onLongPressReleased.event.valuesis empty (no value). - switch —
onReleased, plus the 5.221 split eventsonToggleOn/onToggleOff(sent when declared; the viewer prefers them). The value is a string:event.values[1] == "true"/"false"— not a boolean. - slider —
onChanged.event.values[1]is the value as a string;tonumber()it. - select —
onToggled.event.values[1]is the picked option value (string). - multi —
onToggled.event.values[1]is the list of picked values (flua restores the list; on the real HC3 they arrive comma-joined in the single value parameter).
function QuickApp:modeToggled(event)
self:updateView("modeSelect", "selectedItem", event.values[1]) -- echo the pick
endAsserting and driving UI state in tests
self:getView()— the QA's current rendered view including allupdateViewchanges; parse it to assert label texts, slider values,selectedItem, …_FLUA.uiEvent(elementName, eventType[, value])— inject a UI event from a test/verify QA, exactly like a tap on the real UI would deliver it.GET /plugins/callUIEvent?deviceID=<id>&elementName=<n>&eventType=<t>[&value=<v>]— the viewer's channel; drive it from outside the QA (curl, tests). POST with a JSON body is the proxy channel.
_FLUA.uiEvent("setpoint", "onChanged", "21.5")
local view = self:getView()
assert(tostring(view.body.sections.items[1].components[1].value) == "21.5")A runnable QA exercising every element's updateView and callbacks lives in
templates/updateview-demo.lua — run it
with flua --ui and watch the viewer, or drive it from a test QA.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

