Dynamic preferences
Build the form from the answers so far, from live device data, or from the service catalog.
preferences may be a function. The hub calls it (inside the isolate, so every global helper
works) with the values collected so far and renders whatever pages it returns. Combine it with
submitOnChange on the inputs that should re-shape the form.
const preferences = (values) => ({
pages: [
{
id: 'pick',
title: 'What to control',
inputs: [
{ key: 'domain', label: 'Device type', type: 'enum', submitOnChange: true, required: true,
options: getActionDomains() }, // from the hub's catalog
{ key: 'device', label: 'Device', type: 'entity', required: true,
domainFilter: values.domain, visible: { input: 'domain', operator: 'truthy' } },
],
},
{
id: 'action',
title: 'Action',
visible: { input: 'device', operator: 'truthy' },
inputs: [
{ key: 'service', label: 'Do', type: 'enum', required: true, submitOnChange: true,
options: getServicesForDomain(values.domain ?? '') },
...parameterInputs(values),
],
},
],
});
function parameterInputs(values) {
if (!values.domain || !values.service) return [];
return getServiceParameters(values.domain, values.service).map((p) => ({
key: `param_${p.key}`, label: p.label, type: p.type, required: p.required,
minValue: p.min, maxValue: p.max, options: p.options, description: p.description,
}));
}What you can use inside
- The catalog introspection functions, for domain, service and parameter pickers that stay in sync with the hub.
new EntityWrapper(id).getAttributes()to enumerate a picked device's attributes (wrap intry/catch: the device may be offline at edit time).listSmartAppInstances()to offer other apps as options,getPlacePresenceOptions()for places,getHvacModeOptions()/getFanModeOptions()for thermostats.
Do not subscribe, schedule or call services from preferences; it runs during editing, not
installation, and may run many times.
Keep stored values valid
The form engine drops an enum value that is missing from the current options. When options are
computed from live data (an offline device returns no attributes), merge the stored value back in so
a re-save does not silently clear the field.
Page flow
Pages render in array order; a page whose visible condition is false is skipped. The wizard shows
progress across the visible pages and lets people go back; going back and changing an answer re-runs
your function with the new values.