Preferences
The install form: pages, sections and inputs, and how the wizard runs it.
preferences describes the form a person fills in when installing or editing an instance. The
hub renders it as a wizard: one page at a time, with Back / Next and a progress bar.
const preferences = {
pages: [
{
id: 'devices',
title: 'Devices',
description: 'Pick the sensor and the lights it should control.', // optional banner
inputs: [
{ key: 'sensor', label: 'Motion sensor', type: 'entity', domainFilter: 'binary_sensor', required: true },
{ key: 'lights', label: 'Lights', type: 'entity', domainFilter: 'light', multiple: true, required: true },
],
},
{
id: 'timing',
title: 'Timing',
sections: [ // inputs can be grouped
{ id: 'delay', title: 'Delay', inputs: [
{ key: 'offAfterMinutes', label: 'Turn off after (minutes)', type: 'number', default: 1, minValue: 1, maxValue: 120 },
]},
{ id: 'night', title: 'Night only', inputs: [
{ key: 'nightOnly', label: 'Only run between sunset and sunrise', type: 'boolean', default: false },
]},
],
},
],
};Structure
- Pages have an
id, atitle, and eitherinputsdirectly orsectionsof inputs. Optionaldescriptionshows a banner above the inputs;loadingDescriptionis the spinner caption while the hub prepares the page (used by discovery wizards). A page or section with avisiblecondition is skipped when the condition is false. - Inputs have a
key(a valid JavaScript identifier; it becomes a global), alabel, atype, and type-specific options. All fields are listed on the Input types reference. - Static or dynamic.
preferencescan be the object above or a function(values) => ({ pages })that the hub calls with the answers so far. See Dynamic preferences.
Common input options
| Option | Purpose |
|---|---|
required | the wizard refuses to continue without a value |
default | pre-filled value in the form (not applied at run time — your code still handles undefined) |
description | help text under the input |
multiple | several picks for entity and enum |
options | choices for enum: [{ value, label, description? }] |
minValue / maxValue / unit | numeric bounds; unit (e.g. '°C') makes clients render in the home's units and store the canonical value |
domainFilter / deviceClassFilter | narrow an entity picker ('light', 'binary_sensor' + 'motion') |
placeholder, readonly, widget | presentation (widget: 'tiles' renders an enum as cards, 'textarea' a multi-line string) |
submitOnChange | re-run a dynamic preferences function as soon as this input changes |
visible | declarative show/hide condition — see Conditions and visibility |
Older examples use filter: { domain, deviceClass } and defaultValue. The hub still normalises the
legacy filter object into domainFilter / deviceClassFilter; defaultValue is ignored — use default.
Reading the answers in code
Every input's key becomes a global variable when its type supports it, and every answer is
available in settings[key]. Which types become globals, and in what shape, is on
Inputs to globals.
Validation
The wizard validates on each page: required inputs, numeric bounds, enum membership (a stored value
missing from options is dropped on re-save — keep options stable or merge stored values back in),
minItems / maxItems on arrays. The install only completes when the last page validates; then the
hub stores the settings and calls installed (or updated).