Skip to content

Configuration

cvrt-jh edited this page Aug 12, 2026 · 2 revisions

Configuration

deckd uses TOML configuration. Default path: /etc/deckd/config.toml.

Global Settings

[deckd]
brightness = 80              # Display brightness 0-100
reconnect_interval_ms = 2000 # USB reconnect interval
home_page = "home"           # Starting page

[deckd.defaults]
background = "#1a1a2e"       # Default button background
text_color = "#e0e0e0"       # Default text color
font_size = 14               # Default font size in pixels

Pages and Buttons

[pages.home]
name = "Home"

[[pages.home.buttons]]
key = 0                      # Key index 0-14
label = "Deploy"
icon = "icons/rocket.png"    # Relative to config dir
background = "#c0392b"       # Override default
on_press = { action = "http", method = "POST", url = "https://example.com/webhook" }

Key Layout (MK.2, 3x5)

 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14

Environment Variables

Use ${VAR} syntax in any string value:

headers = { "Authorization" = "Bearer ${HA_TOKEN}" }

Home Assistant Buttons

deckd polls Home Assistant every 5 seconds and re-renders, so buttons reflect changes made anywhere (app, voice, automation), not just presses on the deck.

If a fetch fails or times out, the last known value is held rather than being rendered as "off". Without that, a brief HA or DNS stall makes every stateful button flick to its off state and back on the next poll.

Stateful toggles

Swap colors based on an entity's on/off state:

[[pages.home.buttons]]
key = 0
label = "Printer"
background = "#000000"           # when OFF
text_color = "#FA6831"
on_background = "#FA6831"        # when ON
on_text_color = "#000000"
state_entity = "switch.printer"
on_press = { action = "http", method = "POST", url = "http://homeassistant.local:8123/api/services/switch/toggle", headers = { "Authorization" = "Bearer ${HA_TOKEN}", "Content-Type" = "application/json" }, body = "{\"entity_id\": \"switch.printer\"}" }

On press the color flips instantly (~50ms) without waiting for the network, then syncs with the real HA state after 3 seconds.

Keep state_entity and the entity in the action body the same. A button that tracks one entity and toggles another shows a state it does not control, and nothing reports the mismatch at runtime.

Sensor values

Render a live reading instead of a static label:

[[pages.home.buttons]]
key = 5
label = "Cellar\n{value}deg"
label_entity = "sensor.cellar_temperature"
precision = 1                    # decimal places (default 0)
unknown_text = "--"              # shown when unavailable
thresholds = [
  { min = -100.0, color = "#25AFF4" },   # cold
  { min = 21.0, color = "#FFFFFF" },     # comfortable
  { min = 25.0, color = "#E02B1D" },     # hot
]
Field Description
label_entity Entity whose state replaces {value} in the label
precision Decimal places for numeric values (default 0)
unknown_text Replaces {value} when unknown or unavailable (default --)
thresholds Bands of { min, color } overriding text_color

The highest band whose min is at or below the value wins, so the order in the file does not matter. Non-numeric states (unavailable, unknown) fall back to unknown_text and never trigger a threshold color.

Folders with an active count

A folder is a button that navigates to a sub-page. count_entities shows how many devices inside are on, and the active_* colors light it up:

[[pages.home.buttons]]
key = 4
label = "Plants\n{count}/{total}"
text_color = "#2E5233"           # dimmed when everything is off
active_text_color = "#4CAF50"    # lit while any device is on
count_entities = [
  "switch.plug_a",
  "switch.plug_b",
  "switch.plug_c",
]
on_press = { action = "navigate", page = "plants" }

[pages.plants]
name = "Plants"

# ... one stateful button per device ...

[[pages.plants.buttons]]
key = 14
label = "Back"
background = "#4CAF50"           # the folder's own color, as background
text_color = "#000000"
on_press = { action = "back" }
Field Description
count_entities Entities counted for {count}; {total} is how many are listed
active_text_color Text color while {count} > 0
active_background Background color while {count} > 0

{count} and {total} work without label_entity, so a folder needs no value entity of its own. Navigating back re-fetches state, so the badge is current as soon as the parent page reappears. Page nesting is arbitrary depth: back pops one level, home resets to the top.

Giving the Back button the folder's color as its background makes it read as an activated key, matching the filled look every toggle uses for "on": being inside the folder is the active state.

Choosing colors

A deck is read at a glance, so color carries meaning. Use one hue per device category, give idle states a darker variant of the same hue rather than a different hue, and keep saturated colors in a consistent lightness band so they match in apparent brightness against black.

Do not paste Material or Tailwind defaults from memory: they are tuned for white backgrounds and render too light on a black key.

Hot Reload

Edit the config file while deckd is running. Changes are automatically detected and applied without restart.

Clone this wiki locally