zigbee_esphome icon indicating copy to clipboard operation
zigbee_esphome copied to clipboard

Expose select device

Open skarab22 opened this issue 1 month ago • 2 comments

A few years ago, I designed an ESP8266-based PCB to control the pilot wire of my radiators using ESPHome. I recently created a new PCB to reduce its size and, most importantly, replace the ESP8266 with a Xiao C6.

The idea is to leverage the radiators placed throughout the house to create a strong Zigbee mesh network.

I successfully flashed the Xiao C6 with:

  • Wi-Fi and Zigbee support
  • Two exposed switches to control the two outputs for my pilot wire.

Here’s my code:

esphome:
  name: esphome-web-41db24
  friendly_name: ESPHome Web 41db24

external_components:
  - source: github://luar123/zigbee_esphome
    components: [zigbee]

esp32:
  variant: esp32c6
  framework:
    type: esp-idf
    version: recommended
  partitions: partitions_zb.csv

# Enable logging
logger:

api:

ota:
  - platform: esphome
    password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

web_server:

zigbee:
  id: zb
  router: true
  power_supply: 1
  components: all

output:
  - platform: gpio
    pin:
      number: GPIO15
      inverted: true  # <-- Add this line
    id: led_builtin_out
  - platform: gpio
    pin: GPIO1
    id: gpio1_output
  - platform: gpio
    pin: GPIO2
    id: gpio2_output

light:
  - platform: binary
    name: "Built-in LED"
    output: led_builtin_out
    id: led_builtin

select:
  - platform: template
    name: "Heating Mode"
    options:
      - "Off"
      - "Frost Protection"
      - "Eco"
      - "Comfort"
    id: mode_de_chauffage
    initial_option: "Off"
    optimistic: true
    on_value:
      then:
        - if:
            condition:
              lambda: 'return id(mode_de_chauffage).state == "Off";'
            then:
              - logger.log: "GPIO1: OFF, GPIO2: ON"
              - output.turn_on: gpio1_output
              - output.turn_off: gpio2_output
        - if:
            condition:
              lambda: 'return id(mode_de_chauffage).state == "Frost Protection";'
            then:
              - logger.log: "GPIO1: ON, GPIO2: OFF"
              - output.turn_off: gpio1_output
              - output.turn_on: gpio2_output
        - if:
            condition:
              lambda: 'return id(mode_de_chauffage).state == "Eco";'
            then:
              - logger.log: "GPIO1: ON, GPIO2: ON"
              - output.turn_on: gpio1_output
              - output.turn_on: gpio2_output
        - if:
            condition:
              lambda: 'return id(mode_de_chauffage).state == "Comfort";'
            then:
              - logger.log: "GPIO1: OFF, GPIO2: OFF"
              - output.turn_off: gpio1_output
              - output.turn_off: gpio2_output

What I’d like to do: Replace the two exposed switches with a single select or enum component offering the modes Comfort, Eco, Frost Protection, and Off. Do you know if this is possible? And if so, do you have any idea how to implement it?

skarab22 avatar Nov 16 '25 10:11 skarab22

There is a enum datatype in zigbee which could be used together with a custom cluster and custom converters in z2m/zha. I don't think this is can be done easily without these manual modifications. (There are also clusters for HVAC, but not sure if they cover your usecase).

Generally speaking, do you want to use wifi or zigbee for exposing? Using api+zigbee doesn't make a lot of sense and using wifi+zigbee router is not recommended as they will share one radio. You could still use wifi for OTA for example.

luar123 avatar Nov 16 '25 17:11 luar123

Actually there is the multistate output cluster that could be used, however, support in z2m and zha is missing: https://github.com/zigpy/zha/issues/479 Also adding this cluster through yaml is non-trivial as the string array datatype is not supported.

So, yes it is possible, but requires some work.

luar123 avatar Nov 16 '25 19:11 luar123