Configuration: panels.yaml¶
The runtime reads one YAML file (default: ./panels.yaml, add-on mode: /config/panels.yaml).
Use the web editor to manage this file. For a complete starting configuration, see your first panel. Snippets in the card and screensaver references belong under nspanels.<panel_name>. Do not wrap them in AppDaemon module, class, or config keys.
Top-level keys¶
| key | required | type | default | description |
|---|---|---|---|---|
nspanels |
yes | object | none | Map of panel definitions. |
home_assistant_address |
recommended | string | none | Home Assistant base URL. In add-on mode it is auto-filled as http://supervisor if missing. |
home_assistant_token |
recommended | string | none | Long-lived token or Supervisor token. |
mqtt_server |
required in MQTT mode | string | from env | MQTT host. |
mqtt_port |
required in MQTT mode | int | from env | MQTT port. |
mqtt_username |
required in MQTT mode | string | from env | MQTT username. |
mqtt_password |
required in MQTT mode | string | from env | MQTT password. |
use_ha_api |
optional | boolean | false |
When true, MQTT input mode is disabled and HA event mode is used. |
timeZone |
optional | string | Europe/Berlin |
Global fallback for panel timeZone. |
hiddenCards |
optional | list | [] |
Global fallback for panel hiddenCards. |
Panel keys (nspanels.<name>)¶
| key | required | type | default | description |
|---|---|---|---|---|
panelRecvTopic |
yes | string | none | Receive channel for panel events. |
panelSendTopic |
yes | string | none | Send channel for panel commands. |
locale |
yes | string | none | Locale used for translations and date formatting. |
timeZone |
recommended | string | from top-level timeZone |
Time zone for clock. |
timeFormat |
yes | string | none | Python strftime format. |
dateFormat |
yes | string | none | Babel date format (example: full, medium). |
timeAdditionalTemplate |
optional | template | none | Text below the screensaver time, as in AppDaemon. The ha: prefix is optional. Updates when the result changes. |
dateAdditionalTemplate |
optional | template | none | Text appended directly to the date. With dateFormat: '' only this text is shown. |
model |
optional | string | eu |
Panel model (eu, us-p, us-l). |
temp_unit |
optional | string | celsius |
Thermostat card unit (celsius or fahrenheit). |
sleepTimeout |
optional | int | 20 |
Seconds before screensaver. |
sleepBrightness |
optional | int, entity_id, or schedule | 10 |
Screensaver brightness. |
screenBrightness |
optional | int, entity_id, or schedule | 100 |
Active-screen brightness. |
sleepTracking |
optional | entity_id | none | Forces sleep brightness to 0 when entity state matches sleepTrackingZones. |
sleepTrackingZones |
optional | list | ["not_home", "off"] |
States that trigger forced dimming. |
sleepOverride |
optional | object | none | Override sleep brightness when entity is on/true/home. |
defaultBackgroundColor |
optional | string | ha-dark |
ha-dark or black. |
featExperimentalSliders |
optional | int | 0 |
Forwarded in dimmode command. |
defaultCard |
optional | string | none | Default card when leaving screensaver (navigate.<key>). |
screensaver |
yes | object | none | Screensaver definition. |
cards |
yes | list | none | At least one supported top-level card is required when saving in the editor. |
hiddenCards |
optional | list | [] |
Hidden cards addressable through navigate.<key>. |
Brightness behavior¶
- Integer values are used directly.
- Entity values read Home Assistant state and cast to number.
- Daily time/value schedules are supported for both sleep and active-screen brightness.
Example:
sleepBrightness: input_number.nspanel_sleep
screenBrightness: input_number.nspanel_awake
sleepTracking: person.john
sleepTrackingZones: ["not_home", "off"]
sleepOverride:
entity: light.bedroom
brightness: 30
Web editor (Home Assistant add-on)¶
From add-on version 4.8.0, Open Web UI provides a visual panel/card/entity editor and a full YAML editor. Import existing add-on or AppDaemon YAML into a draft, review warnings, and save to apply. Saves create panels.yaml.bak and reload the backend; stale browser drafts cannot overwrite newer disk revisions. Home Assistant ingress is the default access mode. Standalone Docker installations can opt into direct access with WEB_STANDALONE=true and WEB_PASSWORD; see the standalone guide.
TFT firmware updates (4.8.1+)¶
At panel startup, the backend checks the reported TFT version and model against its pinned firmware target (currently protocol version 55, release v4.8.11). It does not query the latest GitHub release. A backend release can advance this target separately from its add-on version.
Set TFT firmware updates in the visual editor, or add the following under your panel:
updateMode: auto-notify
auto-notify(default): show an Install/Dismiss dialog on the physical panel when an update is needed.auto: start an update automatically when the installed version is older. A model change still requires confirmation.manual: do not offer or start TFT updates.
Dismissing a prompt suppresses further prompts until the backend restarts. A newer TFT on the same model is not downgraded. The backend sends at most one flash request per panel per backend run; check device logs before restarting to retry a failed transfer. Keep power connected while flashing. A new startup message reports the resulting version; no startup after ten minutes is logged as an unconfirmed update, not success.
Tasmota installations need the Berry driver with FlashNextion support and a panelSendTopic ending in /CustomSend. Compatible ESPHome installations use the existing nspanelui_api_call service with command 255; support depends on the installed ESPHome component. TFTs older than protocol version 16 require manual flashing. Berry driver updates remain manual.
Advanced YAML options retain the AppDaemon names displayURL-EU, displayURL-US-P, and displayURL-US-L. Only the URL for the selected model is used. Custom URLs must use HTTP and be reachable from the panel. Set displayFirmwareVersion to the protocol version embedded in a custom TFT (not its release string), for example:
updateMode: auto-notify
displayURL-EU: http://homeassistant.local:8123/local/nspanel.tft
displayFirmwareVersion: 53
Dynamic brightness¶
Set the following under your panel in the YAML editor (or All panel options using JSON):
timeZone: Europe/Berlin
sleepBrightness:
- time: "07:00"
value: 35
- time: "22:00"
value: 0
This uses brightness 35 during the day and 0 overnight. Times are daily local wall-clock times in the panel's timeZone; quote them in YAML. HH:MM and HH:MM:SS are accepted, also with a one-digit hour. Entries may be unordered but must have unique times and integer values from 0 to 100. The last entry from the previous day applies before the first entry, including after a restart. The backend checks schedules every second and sends a brightness command only when the resolved settings change. The same schedule format is supported by screenBrightness.
AppDaemon-style sunrise and sunset times are supported, optionally with an offset such as "sunset + 1:00:00" or "sunrise - 0:30":
sleepBrightness:
- time: "sunrise"
value: 20
- time: "sunset"
value: 1
Sun times come from the next_rising and next_setting attributes of Home Assistant's sun.sun entity (Sun integration). While it is unavailable, sun entries are skipped; if no entry is left, the default brightness applies. After an event has passed, today's time is estimated from the next day's, which can differ by a few minutes.
For illumination-driven control, set sleepBrightness: input_number.nspanel_sleep and use a Home Assistant automation to update that helper from your illuminance sensor. A numeric sensor entity can also be used directly if its state already represents a desired brightness percentage. Values are clamped to 0–100; raw lux is not automatically converted into a brightness curve. Entity changes update the panel without a restart.
sleepTracking still forces sleep brightness to zero when its configured state matches; an active sleepOverride takes precedence over that and the schedule. An override brightness of zero is supported.