CYD

CYD HAMon Config Generator

Configure your Cheap Yellow Display Home Assistant Monitor

Generated YAML uses the mipi_spi display platform (ILI9341). Minimum ESPHome: 2025.5.0. The legacy ili9xxx platform is superseded by mipi_spi. ESPHome 2025.5.0 release notes

Device Settings

Device GPIO config

Choose a board variant or set pins manually.

Standard CYD, backlight GPIO21

Display & backlight

Touch (SPI – XPT2046)

Display Settings

Visual and layout options for the device display.

Swap X/Y axes

Enable for most CYD boards. Disable if the display is rotated or only 4 sensors are visible with blank space.


Hide Clock

Adds an extra row for a 4×2 sensor grid on Screen 1.


Invert colours

Use if colours look inverted or negative on your panel.


Colour order

RGB or BGR. Use BGR if reds and blues are swapped.


Mirror X

Default on for most CYD boards. Turn off if the image is flipped horizontally.


Mirror Y

Default on for most CYD boards. Turn off if the image is flipped vertically.


On-device web server

Adds ESPHome web_server v3 so you can open the device IP to view entities and set backlight brightness.


0px

0 = square corners, 34 = fully rounded.


Icon Set

Icons used in the preview and generated YAML.

The same file must also exist on your ESPHome host at compile time (typically /config/esphome/images/). Images are compiled into flash at 240×320.

Sensor Configuration (Screen 1)

HAMon Device Preview

Click binary/light/switch sensors to toggle state. Click a numeric sensor value to enter a test number and see how thresholds affect the icon and colour.

CYD device preview

Generated YAML

# ==============================================================================
#  CYD 2.8" HAMon - Home Assistant Monitor
#  A customisable clock & sensor dashboard for the ESP32 Cheap Yellow Display
#
#  Generated by CYD HAMon Config Generator
#  https://github.com/element-software/CYD-ESPHome-HA-Monitor
#
#  License: MIT
# ==============================================================================
#
#  SUBSTITUTIONS - Customise your dashboard by editing the values below.
#  Passwords and keys should be stored in your secrets.yaml file.
#
# ==============================================================================
substitutions:
  # --- Device ---
  device_name: "hamon"
  friendly_name: "HAMon"

  # --- Icon Glyphs ---
  # List each unique icon ONCE here. If you use the same icon multiple times below,
  # only include it once in this list to avoid "duplicate glyph" errors.
  icon_glyphs: "\uea0b\ueffc\ue1ff\ue8ac\ue7fd\ue0f0"

  # --- Color theme for Screen 1 ---
  s1_bg_color: "0x0F1419"
  s1_font_color: "0xFFFFFF"

  # ==============================================================================
  # Substitutions for Screen 1
  # ==============================================================================
  # --- Screen 1, R1C1 ---
  s1_r1c1_entity: "sensor.whole_home_energy_usage"
  s1_r1c1_type: "sensor"
  s1_r1c1_label: "Energy"
  s1_r1c1_icon: "\uea0b"
  s1_r1c1_icon_color: "0xFFA500"
  s1_r1c1_format: '%.0fW'
  s1_r1c1_thresh_0: "5000"
  s1_r1c1_thresh_0_color: "0xFF0000"
  s1_r1c1_thresh_1: "3000"
  s1_r1c1_thresh_1_color: "0xFFA500"
  s1_r1c1_thresh_2: "1000"
  s1_r1c1_thresh_2_color: "0x32CD32"

  # --- Screen 1, R1C2 ---
  s1_r1c2_entity: "binary_sensor.front_door_sensor_contact"
  s1_r1c2_type: "binary"
  s1_r1c2_label: "Front Door"
  s1_r1c2_icon: "\ueffc"
  s1_r1c2_icon_color: "0x32CD32"
  s1_r1c2_state_on: "Open"
  s1_r1c2_state_off: "Closed"
  s1_r1c2_icon_on: "\ueffc"
  s1_r1c2_icon_off: "\ueffc"
  s1_r1c2_color_on: "0xFF0000"
  s1_r1c2_color_off: "0x32CD32"
  s1_r1c2_color_on_text: "0x000000"

  # --- Screen 1, R2C1 ---
  s1_r2c1_entity: "sensor.office_presence_one_temperature"
  s1_r2c1_type: "sensor"
  s1_r2c1_label: "Office"
  s1_r2c1_icon: "\ue1ff"
  s1_r2c1_icon_color: "0x00BFFF"
  s1_r2c1_format: '%.1f°C'
  s1_r2c1_thresh_0: "30"
  s1_r2c1_thresh_0_color: "0xFF0000"
  s1_r2c1_thresh_1: "25"
  s1_r2c1_thresh_1_color: "0xFFA500"
  s1_r2c1_thresh_2: "15"
  s1_r2c1_thresh_2_color: "0x32CD32"

  # --- Screen 1, R2C2 ---
  s1_r2c2_entity: "switch.zigbee2mqtt_bridge_permit_join"
  s1_r2c2_type: "switch"
  s1_r2c2_label: "Z2M Join"
  s1_r2c2_icon: "\ue8ac"
  s1_r2c2_icon_color: "0x888888"
  s1_r2c2_state_on: "On"
  s1_r2c2_state_off: "Off"
  s1_r2c2_icon_on: "\ue8ac"
  s1_r2c2_icon_off: "\ue8ac"
  s1_r2c2_color_on: "0x4CAF50"
  s1_r2c2_color_off: "0x888888"
  s1_r2c2_color_on_text: "0x000000"

  # --- Screen 1, R3C1 ---
  s1_r3c1_entity: "binary_sensor.garden_pano_person_occupancy"
  s1_r3c1_type: "binary"
  s1_r3c1_label: "Garden"
  s1_r3c1_icon: "\ue7fd"
  s1_r3c1_icon_color: "0x32CD32"
  s1_r3c1_state_on: "Detected"
  s1_r3c1_state_off: "Clear"
  s1_r3c1_icon_on: "\ue7fd"
  s1_r3c1_icon_off: "\ue7fd"
  s1_r3c1_color_on: "0xFF0000"
  s1_r3c1_color_off: "0x32CD32"
  s1_r3c1_color_on_text: "0x000000"

  # --- Screen 1, R3C2 ---
  s1_r3c2_entity: "light.kitchen_downlights"
  s1_r3c2_type: "light"
  s1_r3c2_label: "Kitchen"
  s1_r3c2_icon: "\ue0f0"
  s1_r3c2_icon_color: "0x888888"
  s1_r3c2_state_on: "On"
  s1_r3c2_state_off: "Off"
  s1_r3c2_icon_on: "\ue0f0"
  s1_r3c2_icon_off: "\ue0f0"
  s1_r3c2_color_on: "0xFFE082"
  s1_r3c2_color_off: "0x888888"
  s1_r3c2_color_on_text: "0x000000"

# ------------------------------------------------------------------------------
# Display: platform mipi_spi (model ILI9341). The mipi_spi driver shipped in
# ESPHome 2025.5.0 — https://esphome.io/changelog/2025.5.0/
# Legacy ili9xxx/st7735 are deprecated in favor of mipi_spi; see
# https://github.com/esphome/esphome/pull/15416
#
# Minimum ESPHome: 2025.5.0. Deprecation warnings for ili9xxx/st7735 from 2026.4.0+.
# ------------------------------------------------------------------------------
# ==============================================================================
esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}

esp32:
  board: esp32dev
  framework:
    type: esp-idf

logger:

# Replace with the API encryption key provided by your ESPHome instance
api:
  encryption:
    key: !secret hamon_api_key

# Replace with the OTA password provided by your ESPHome instance
ota:
  - platform: esphome
    password: !secret hamon_ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "${friendly_name} Fallback"
    password: !secret hamon_ap_password

captive_portal:

web_server:
  port: 80
  version: 3

output:
  - platform: ledc
    pin: GPIO21
    id: backlight_pwm

spi:
  - id: tft
    clk_pin: GPIO14
    mosi_pin: GPIO13
    miso_pin: GPIO12

  - id: touch
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

display:
  - platform: mipi_spi
    id: my_display
    model: ILI9341
    spi_id: tft
    cs_pin: GPIO15
    dc_pin: GPIO2
    auto_clear_enabled: false
    invert_colors: false
    color_order: RGB
    dimensions:
      width: 240
      height: 320
      offset_width: 0
      offset_height: 0
      pad_width: 0
      pad_height: 0
    transform:
      swap_xy: true
      mirror_y: true
      mirror_x: true

touchscreen:
  platform: xpt2046
  id: my_touchscreen
  spi_id: touch
  cs_pin: GPIO33
  calibration:
    x_min: 220
    x_max: 3756
    y_min: 394
    y_max: 3749
  transform:
    swap_xy: false
    mirror_x: true
    mirror_y: false
  on_touch:
    - lambda: |-
        ESP_LOGI("touch", "Touch at LVGL (%d, %d)", touch.x, touch.y);


# --- FONTS ---
font:
  - file: "gfonts://Roboto"
    id: clock_font
    size: 48
    glyphs: '0123456789: '
  - file: "gfonts://Roboto"
    id: date_font
    size: 20
    glyphs: "0123456789/- abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  - file: "gfonts://Material Icons"
    id: icon_font
    size: 28
    glyphs: "${icon_glyphs}"
  - file: "gfonts://Roboto"
    id: state_font
    size: 18
    glyphs: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz .°%-/³µμÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
  - file: "gfonts://Roboto"
    id: label_font
    size: 11
    glyphs: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz .°%-/³µμÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ"

# --- TIME ---
time:
  - platform: homeassistant
    id: esptime
    on_time:
      - seconds: 0
        then:
          - lvgl.label.update:
              id: label_clock
              text: !lambda 'return id(esptime).now().strftime("%H:%M");'
          - lvgl.label.update:
              id: label_date
              text: !lambda |-
                static const char *const dias[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
                auto now = id(esptime).now();
                return str_sprintf("%s %02d/%02d", dias[now.day_of_week - 1], now.day_of_month, now.month);

# --- DISPLAY PAGE CONFIG ---
lvgl:
  displays:
    - my_display
  touchscreens:
    - my_touchscreen
  pages:
    - id: page_s1
      bg_color: ${s1_bg_color}
      widgets:

        - label:
            id: label_clock
            text: "--:--"
            text_font: clock_font
            text_color: ${s1_font_color}
            align: TOP_MID
            y: 15
        - label:
            id: label_date
            text: "--- --/--"
            text_font: date_font
            text_color: ${s1_font_color}
            align: TOP_MID
            y: 65

        # ====== ROW 1 ======

        - button:
            x: 2
            y: 100
            id: button_s1_r1c1
            width: 117
            height: 68
            bg_opa: TRANSP
            border_width: 0
            shadow_width: 0
            radius: 0
            press_lock: false
            scrollbar_mode: "OFF"
            widgets:
              - label:
                  id: icon_s1_r1c1
                  text: "${s1_r1c1_icon}"
                  text_font: icon_font
                  text_color: ${s1_r1c1_icon_color}
                  align: LEFT_MID
                  x: 0
                  clickable: false
              - label:
                  id: lbl_s1_r1c1
                  text: "${s1_r1c1_label}"
                  text_font: label_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: -10
                  clickable: false
              - label:
                  id: val_s1_r1c1
                  text: "--"
                  text_font: state_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: 10
                  clickable: false

        - button:
            x: 121
            y: 100
            id: button_s1_r1c2
            width: 117
            height: 68
            bg_opa: TRANSP
            border_width: 0
            shadow_width: 0
            radius: 0
            press_lock: false
            scrollbar_mode: "OFF"
            widgets:
              - label:
                  id: icon_s1_r1c2
                  text: "${s1_r1c2_icon}"
                  text_font: icon_font
                  text_color: ${s1_r1c2_icon_color}
                  align: LEFT_MID
                  x: 0
                  clickable: false
              - label:
                  id: lbl_s1_r1c2
                  text: "${s1_r1c2_label}"
                  text_font: label_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: -10
                  clickable: false
              - label:
                  id: val_s1_r1c2
                  text: "--"
                  text_font: state_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: 10
                  clickable: false
        # ====== ROW 2 ======

        - button:
            x: 2
            y: 170
            id: button_s1_r2c1
            width: 117
            height: 68
            bg_opa: TRANSP
            border_width: 0
            shadow_width: 0
            radius: 0
            press_lock: false
            scrollbar_mode: "OFF"
            widgets:
              - label:
                  id: icon_s1_r2c1
                  text: "${s1_r2c1_icon}"
                  text_font: icon_font
                  text_color: ${s1_r2c1_icon_color}
                  align: LEFT_MID
                  x: 0
                  clickable: false
              - label:
                  id: lbl_s1_r2c1
                  text: "${s1_r2c1_label}"
                  text_font: label_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: -10
                  clickable: false
              - label:
                  id: val_s1_r2c1
                  text: "--"
                  text_font: state_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: 10
                  clickable: false

        - button:
            x: 121
            y: 170
            id: button_s1_r2c2
            width: 117
            height: 68
            bg_opa: TRANSP
            border_width: 0
            shadow_width: 0
            radius: 0
            press_lock: false
            scrollbar_mode: "OFF"
            on_click:
              - homeassistant.action:
                  action: switch.toggle
                  data:
                    entity_id: "switch.zigbee2mqtt_bridge_permit_join"
            widgets:
              - label:
                  id: icon_s1_r2c2
                  text: "${s1_r2c2_icon}"
                  text_font: icon_font
                  text_color: ${s1_r2c2_icon_color}
                  align: LEFT_MID
                  x: 0
                  clickable: false
              - label:
                  id: lbl_s1_r2c2
                  text: "${s1_r2c2_label}"
                  text_font: label_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: -10
                  clickable: false
              - label:
                  id: val_s1_r2c2
                  text: "--"
                  text_font: state_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: 10
                  clickable: false
        # ====== ROW 3 ======

        - button:
            x: 2
            y: 240
            id: button_s1_r3c1
            width: 117
            height: 68
            bg_opa: TRANSP
            border_width: 0
            shadow_width: 0
            radius: 0
            press_lock: false
            scrollbar_mode: "OFF"
            widgets:
              - label:
                  id: icon_s1_r3c1
                  text: "${s1_r3c1_icon}"
                  text_font: icon_font
                  text_color: ${s1_r3c1_icon_color}
                  align: LEFT_MID
                  x: 0
                  clickable: false
              - label:
                  id: lbl_s1_r3c1
                  text: "${s1_r3c1_label}"
                  text_font: label_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: -10
                  clickable: false
              - label:
                  id: val_s1_r3c1
                  text: "--"
                  text_font: state_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: 10
                  clickable: false

        - button:
            x: 121
            y: 240
            id: button_s1_r3c2
            width: 117
            height: 68
            bg_opa: TRANSP
            border_width: 0
            shadow_width: 0
            radius: 0
            press_lock: false
            scrollbar_mode: "OFF"
            on_click:
              - homeassistant.action:
                  action: light.toggle
                  data:
                    entity_id: "light.kitchen_downlights"
            widgets:
              - label:
                  id: icon_s1_r3c2
                  text: "${s1_r3c2_icon}"
                  text_font: icon_font
                  text_color: ${s1_r3c2_icon_color}
                  align: LEFT_MID
                  x: 0
                  clickable: false
              - label:
                  id: lbl_s1_r3c2
                  text: "${s1_r3c2_label}"
                  text_font: label_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: -10
                  clickable: false
              - label:
                  id: val_s1_r3c2
                  text: "--"
                  text_font: state_font
                  text_color: ${s1_font_color}
                  align: LEFT_MID
                  x: 32
                  y: 10
                  clickable: false

# --- BINARY SENSOR, LIGHT & INPUT BOOLEAN ENTITY STATE ---
# Binary sensors, HA light entities, and input_boolean helpers (on/off state); icon color follows state (color_on / color_off).
binary_sensor:
  - platform: homeassistant
    id: ha_s1_r1c2
    entity_id: ${s1_r1c2_entity}
    trigger_on_initial_state: true
    on_state:
      then:
        - lvgl.label.update:
            id: icon_s1_r1c2
            text: !lambda |-
              if (id(ha_s1_r1c2).state) return "${s1_r1c2_icon_on}";
              return "${s1_r1c2_icon_off}";
        - lvgl.widget.update:
            id: icon_s1_r1c2
            text_color: !lambda |-
              if (id(ha_s1_r1c2).state) return lv_color_hex((uint32_t)${s1_r1c2_color_on});
              return lv_color_hex((uint32_t)${s1_r1c2_color_off});
        - lvgl.label.update:
            id: val_s1_r1c2
            text: !lambda |-
              if (id(ha_s1_r1c2).state) return "${s1_r1c2_state_on}";
              return "${s1_r1c2_state_off}";
        - lvgl.widget.update:
            id: val_s1_r1c2
            text_color: !lambda |-
              if (id(ha_s1_r1c2).state) return lv_color_hex((uint32_t)${s1_r1c2_color_on});
              return lv_color_hex((uint32_t)${s1_r1c2_color_off});

  - platform: homeassistant
    id: ha_s1_r3c1
    entity_id: ${s1_r3c1_entity}
    trigger_on_initial_state: true
    on_state:
      then:
        - lvgl.label.update:
            id: icon_s1_r3c1
            text: !lambda |-
              if (id(ha_s1_r3c1).state) return "${s1_r3c1_icon_on}";
              return "${s1_r3c1_icon_off}";
        - lvgl.widget.update:
            id: icon_s1_r3c1
            text_color: !lambda |-
              if (id(ha_s1_r3c1).state) return lv_color_hex((uint32_t)${s1_r3c1_color_on});
              return lv_color_hex((uint32_t)${s1_r3c1_color_off});
        - lvgl.label.update:
            id: val_s1_r3c1
            text: !lambda |-
              if (id(ha_s1_r3c1).state) return "${s1_r3c1_state_on}";
              return "${s1_r3c1_state_off}";
        - lvgl.widget.update:
            id: val_s1_r3c1
            text_color: !lambda |-
              if (id(ha_s1_r3c1).state) return lv_color_hex((uint32_t)${s1_r3c1_color_on});
              return lv_color_hex((uint32_t)${s1_r3c1_color_off});

  - platform: homeassistant
    id: ha_s1_r3c2
    entity_id: ${s1_r3c2_entity}
    trigger_on_initial_state: true
    on_state:
      then:
        - lvgl.label.update:
            id: icon_s1_r3c2
            text: !lambda |-
              if (id(ha_s1_r3c2).state) return "${s1_r3c2_icon_on}";
              return "${s1_r3c2_icon_off}";
        - lvgl.widget.update:
            id: icon_s1_r3c2
            text_color: !lambda |-
              if (id(ha_s1_r3c2).state) return lv_color_hex((uint32_t)${s1_r3c2_color_on_text});
              return lv_color_hex((uint32_t)${s1_r3c2_color_off});
        - lvgl.label.update:
            id: val_s1_r3c2
            text: !lambda |-
              if (id(ha_s1_r3c2).state) return "${s1_r3c2_state_on}";
              return "${s1_r3c2_state_off}";
        - lvgl.widget.update:
            id: val_s1_r3c2
            text_color: !lambda |-
              if (id(ha_s1_r3c2).state) return lv_color_hex((uint32_t)${s1_r3c2_color_on_text});
              return lv_color_hex((uint32_t)${s1_r3c2_color_off});
        - if:
            condition:
              lambda: return id(ha_s1_r3c2).state;
            then:
              - lvgl.widget.update:
                  id: button_s1_r3c2
                  bg_color: ${s1_r3c2_color_on}
                  bg_opa: COVER
            else:
              - lvgl.widget.update:
                  id: button_s1_r3c2
                  bg_opa: TRANSP


# --- SWITCH ENTITY STATE ---
# HA switch entities (on/off state with tap-to-toggle).
switch:
  - platform: homeassistant
    id: ha_s1_r2c2
    entity_id: ${s1_r2c2_entity}
    on_state:
      then:
        - lvgl.label.update:
            id: icon_s1_r2c2
            text: !lambda |-
              if (id(ha_s1_r2c2).state) return "${s1_r2c2_icon_on}";
              return "${s1_r2c2_icon_off}";
        - lvgl.widget.update:
            id: icon_s1_r2c2
            text_color: !lambda |-
              if (id(ha_s1_r2c2).state) return lv_color_hex((uint32_t)${s1_r2c2_color_on_text});
              return lv_color_hex((uint32_t)${s1_r2c2_color_off});
        - lvgl.label.update:
            id: val_s1_r2c2
            text: !lambda |-
              if (id(ha_s1_r2c2).state) return "${s1_r2c2_state_on}";
              return "${s1_r2c2_state_off}";
        - lvgl.widget.update:
            id: val_s1_r2c2
            text_color: !lambda |-
              if (id(ha_s1_r2c2).state) return lv_color_hex((uint32_t)${s1_r2c2_color_on_text});
              return lv_color_hex((uint32_t)${s1_r2c2_color_off});
        - if:
            condition:
              lambda: return id(ha_s1_r2c2).state;
            then:
              - lvgl.widget.update:
                  id: button_s1_r2c2
                  bg_color: ${s1_r2c2_color_on}
                  bg_opa: COVER
            else:
              - lvgl.widget.update:
                  id: button_s1_r2c2
                  bg_opa: TRANSP


# --- LIGHT CONFIG (display backlight) ---
light:
  - platform: monochromatic
    output: backlight_pwm
    name: Display Backlight
    id: backlight
    restore_mode: ALWAYS_ON
    default_transition_length: 0.5s

# --- NUMERIC SENSOR CONFIG ---
sensor:
  - platform: homeassistant
    id: ha_s1_r1c1
    entity_id: ${s1_r1c1_entity}
    on_value:
      then:
        - lvgl.label.update:
            id: val_s1_r1c1
            text: !lambda |-
              return str_sprintf("${s1_r1c1_format}", x);
        - lvgl.widget.update:
            id: icon_s1_r1c1
            text_color: !lambda |-
              if (x > ${s1_r1c1_thresh_0}) return lv_color_hex(${s1_r1c1_thresh_0_color});
              if (x > ${s1_r1c1_thresh_1}) return lv_color_hex(${s1_r1c1_thresh_1_color});
              return lv_color_hex(${s1_r1c1_thresh_2_color});

  - platform: homeassistant
    id: ha_s1_r2c1
    entity_id: ${s1_r2c1_entity}
    on_value:
      then:
        - lvgl.label.update:
            id: val_s1_r2c1
            text: !lambda |-
              return str_sprintf("${s1_r2c1_format}", x);
        - lvgl.widget.update:
            id: icon_s1_r2c1
            text_color: !lambda |-
              if (x > ${s1_r2c1_thresh_0}) return lv_color_hex(${s1_r2c1_thresh_0_color});
              if (x > ${s1_r2c1_thresh_1}) return lv_color_hex(${s1_r2c1_thresh_1_color});
              return lv_color_hex(${s1_r2c1_thresh_2_color});

What’s new

The config generator can now build multi-page dashboards with themes and extra display options.

  • Optional extra screens (up to 6) with swipe between pages
  • Per-page colours, themes, and optional background images
  • Enable or disable individual slots
  • Invert colours, BGR, mirrors, and an optional ESPHome web server
  • Dark mode for this generator

Thank you to jchisholm59 for contributing these features.