Personal Settings
Some UI settings can be overridden per user, so the same screen looks and behaves differently depending on who is signed in. A homeowner can have their own wallpaper and land on the dashboard, while a staff account on the same panel lands on the page they actually use.
How it resolves
A UI's settings are attribute rows on the ui target, resolved in three layers. Each layer overwrites the one before it:
| Layer | Where it lives | Scope |
|---|---|---|
| Shared default | ui target, ID 0 | Every UI on the system |
| Per-UI | ui target, the UI's ID | One UI |
| Per-user | auth_user target, the user's ID | One person, on every UI they sign in to |
A site with no per-user rows resolves exactly as it did before this feature existed. Absence means "inherit" — that is the only way to inherit, which is why clearing an override deletes the row rather than blanking it.
Which settings can be personalized
Only settings explicitly marked user overridable in the Attribute Registry. Today that is:
- Background Image — wallpaper
- Background Fit — how the wallpaper fills the screen
- Background Dim — darkening over the wallpaper, so text stays readable on a bright photo
- Theme
- Homepage and Mobile Homepage
- Default Weather Location
Everything else — protected routes, roam restrictions, scene-editing locks, backup configuration — is deliberately excluded and cannot be personalized. Those settings decide what someone may reach, and a user writes their own row, so an override would be self-granted permission. The exclusion is enforced when settings are read, not only when they are written: a row for a name that isn't on the list is ignored no matter how it got into the database.
Where users change their own
Tools → My Settings on the UIs screen, which opens the personalization page.
The entry only appears for a signed-in account. A shared wall panel runs a permanent session with no user attached to it, so there is nothing to personalize there — the panel shows the room's settings to everyone who walks up, which is the intended behavior.
Each field shows what it currently inherits and offers a Default choice that removes the override.
Where integrators set them
The Users page has a Personal Settings section on an existing account. It writes the same rows the user's own page does, through the same validation, so an integrator can commission a site without walking each person through the personalization screen.
These fields save as soon as they change — they are attribute rows, not part of the user record, so they do not wait for Update User.
Wallpaper
A background can be either:
- A file in the active theme's backgrounds folder, stored as a bare filename. Because it is stored by name rather than by path, the choice follows a theme switch as long as the new theme has an image with that name.
- A URL under the static web root —
/themes/…,/backgrounds/…or/images/….
To add images:
- Per theme — upload them in the Themes editor, under backgrounds. They appear in the picker whenever that theme is active.
- Theme-independent — drop them into
static/backgrounds/on the controller. These appear in the picker regardless of the active theme, and are the natural home for a client's own photos.
Filesystem paths outside the static web root are rejected. They cannot be served to a browser, so accepting one would store a setting that silently renders nothing.
Precedence against theme artwork
A theme can declare a wallpaper for the whole UI (*) and different artwork for specific pages. A personal background replaces the * wallpaper but not a background the theme declares for a specific page — a page an integrator deliberately dressed keeps its artwork.
Dim and fit
Dim layers a flat darkening over whatever wallpaper is showing, including theme artwork. It is the fix for a bright photo behind light text.
With no wallpaper in play at all — no personal background, and a theme that declares none for the page — there is nothing to dim, and the theme paints its own page ground instead of a flat grey. The official prodigy theme renders a slate gradient that flows out of the top nav; other themes fall back to whatever their stylesheet declares.
Fit controls how the image fills the screen:
| Fit | Behavior |
|---|---|
| Cover | Crops to fill the screen |
| Contain | Shows the whole image, letterboxed |
| Center | Native size, centered |
| Tile | Repeats |
| Stretch | Distorts to fit exactly |
Leaving Fit unset inherits whatever the theme's stylesheet declares.
Theme
A personal theme applies after sign-in. The login screen is themed before anyone is identified, so it uses the UI's theme and the personal one takes over once the session comes up — expect one re-theme as that happens.
Adding a new personalizable setting
Set user_overridable: true on the setting's row in lib/attribute_registry_seed.js and give it a value rule in lib/user_settings.js. Both are required: the flag decides which names may be written, and the rule decides which values may be. A flagged setting with no rule is refused, so flagging alone can never make something writable.
The personalization page and the admin section both render from the registry, so neither needs editing to pick up a new setting.