ESPHome to KNX via Home Assistant: Sensors and Switch States

Bridge ESPHome devices to KNX through Home Assistant: expose ESP32 sensor values and switch states, accept KNX commands, map DPTs correctly and avoid feedback loops.

Home Assistant can bridge ESPHome devices into a KNX installation without adding KNX hardware to the ESP32 itself. ESPHome sends sensors and switch states to Home Assistant through its native API; Home Assistant then publishes those values to KNX group addresses through the KNX integration and a KNX/IP interface or router.

This is useful when you already have a KNX installation but want to add low-cost ESP32 sensors, relays or monitoring devices. A temperature sensor connected to an ESP32 can appear on the KNX bus as a normal DPT 9.001 value, while an ESPHome relay state can be exposed as a DPT 1 binary object. KNX push-buttons can also send commands back through Home Assistant to control the ESPHome switch.

The important design point is that Home Assistant is the bridge. ESPHome is not talking KNX directly. If Home Assistant or the IP connection is unavailable, the ESPHome and KNX sides cannot exchange new values through this path. Keep safety-critical or essential building functions inside the KNX installation rather than making them depend entirely on this bridge.

How the ESPHome-to-KNX Bridge Works

ESP32 + ESPHome
       │
       │ ESPHome native API over IP
       ▼
Home Assistant
       │
       │ Home Assistant KNX integration
       ▼
KNX/IP interface or router
       │
       ▼
KNX bus / group addresses

Home Assistant’s ESPHome integration maintains a persistent connection to the ESPHome node and receives entity changes as they occur. The KNX integration can then expose Home Assistant entity states to KNX group addresses. It also listens for KNX telegrams and can use those telegrams as automation triggers.

You therefore get two useful directions:

  • ESPHome → KNX: publish temperature, humidity, binary sensors, relay states and other Home Assistant entities to KNX group addresses.
  • KNX → ESPHome: receive a KNX command telegram in Home Assistant and call an ESPHome switch, light or other entity.

This is different from MQTT bridging. ESPHome can use MQTT, but for a normal Home Assistant installation the native ESPHome API is usually the simpler path because entities appear directly in Home Assistant without creating an additional message-broker layer.

What You Need

  • An ESP32 or other ESPHome-supported board with working sensors or outputs.
  • Home Assistant with the ESPHome integration configured.
  • A KNX installation.
  • A local KNX/IP interface or KNX/IP router reachable by Home Assistant.
  • Free KNX group addresses assigned in ETS for the values you want to exchange.

The KNX datapoint type must match the value you publish. A temperature should normally be DPT 9.001, humidity DPT 9.007, a percentage DPT 5.001 and a simple on/off state DPT 1. A matching group address created in ETS makes the installation much easier to understand and maintain.

Example ESPHome Device

Assume an ESP32 has one temperature sensor and one relay. Home Assistant sees them as:

sensor.boiler_room_temperature
switch.esp32_boiler_relay

The exact entity IDs depend on your ESPHome device name and entity names. Confirm them in Settings → Devices & services → ESPHome before writing the KNX configuration.

A minimal ESPHome configuration might look like this:

esphome:
  name: boiler-room-node
  friendly_name: Boiler Room Node

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

logger:

api:
  encryption:
    key: !secret esphome_api_key

ota:
  - platform: esphome

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

one_wire:
  - platform: gpio
    pin: GPIO4

sensor:
  - platform: dallas_temp
    name: "Boiler Room Temperature"
    update_interval: 30s

switch:
  - platform: gpio
    name: "Boiler Relay"
    pin: GPIO23
    restore_mode: RESTORE_DEFAULT_OFF

The KNX bridge does not require anything KNX-specific in this ESPHome YAML. Once the entities are working correctly in Home Assistant, the KNX integration can use them like entities from any other Home Assistant integration.

For basic ESPHome setup, see our ESP32 & Home Assistant guides. If you prefer MQTT instead of the native API, our ESP32 to Home Assistant via MQTT guide covers that architecture separately.

Connect Home Assistant to KNX

Add the KNX integration in Home Assistant and connect it to the local KNX/IP interface or router. The KNX connection itself is configured from the integration setup rather than by putting the KNX/IP address into each sensor definition.

Before bridging ESPHome entities, verify that Home Assistant can see normal KNX traffic. If the KNX integration cannot communicate reliably with the bus, adding ESPHome on top will only make troubleshooting harder.

For a routed installation, make sure the KNX topology and router filter tables allow the group addresses Home Assistant will use. For KNX Secure installations, configure the appropriate secure credentials in the Home Assistant KNX integration.

Expose an ESPHome Temperature Sensor to KNX

The simplest direction is ESPHome → Home Assistant → KNX. Home Assistant’s KNX expose feature publishes an entity state to a group address whenever it changes and can respond to GroupValueRead requests for that address.

Assume ETS contains this group address:

PurposeGroup addressDPT
Boiler room temperature5/1/10DPT 9.001 Temperature

Add this under the top-level knx: section in Home Assistant:

knx:
  expose:
    - type: temperature
      entity_id: sensor.boiler_room_temperature
      address: "5/1/10"
      send_on_init: true

Home Assistant now sends the ESPHome temperature to group address 5/1/10. Because type: temperature is used, the value is encoded as the KNX temperature datapoint type rather than as a text string or arbitrary number.

send_on_init: true causes the first valid value learned by the exposure after startup to be sent to the KNX bus. Without it, Home Assistant learns the value locally and can answer reads, but does not immediately transmit that first value purely because the integration started.

Expose Temperature and Humidity Together

An ESPHome SHT31, SHT40, BME280 or similar environmental node usually exposes separate Home Assistant entities. Give each KNX value its own group address and correct DPT.

knx:
  expose:
    - type: temperature
      entity_id: sensor.living_room_temperature
      address: "5/2/1"
      send_on_init: true

    - type: humidity
      entity_id: sensor.living_room_humidity
      address: "5/2/2"
      send_on_init: true

On the KNX side, temperature maps to DPT 9.001 and humidity to DPT 9.007. The ETS group objects linked to these addresses should use matching datapoint types.

If the sensor updates very frequently, use cooldown rather than forwarding every tiny variation to the KNX bus:

knx:
  expose:
    - type: temperature
      entity_id: sensor.living_room_temperature
      address: "5/2/1"
      send_on_init: true
      cooldown: 30
      periodic_send:
        minutes: 30

cooldown limits how often changes are transmitted; the most recent value is retained during that period. periodic_send can retransmit the current value at a longer interval even when it has not changed. Do not use a very short periodic interval simply to make the bus look active.

Expose an ESPHome Binary Sensor to KNX

Door contacts, occupancy sensors, leak alarms and many other ESPHome entities are binary. Expose them as DPT 1 values:

knx:
  expose:
    - type: binary
      entity_id: binary_sensor.garage_door_contact
      address: "6/1/5"
      send_on_init: true

A KNX visualisation, logic controller or other bus device can now use that group address as a normal binary status object. Home Assistant also answers GroupValueRead requests on an entity exposure by default.

For a practical ESPHome contact-sensor example, see our ESP32 reed-switch Home Assistant guide.

Expose the Actual ESPHome Switch State

For outputs, treat command and state as two different pieces of information. This is the same design principle used by many native KNX actuators.

PurposeGroup addressDPT
Boiler relay command4/1/1DPT 1
Boiler relay state4/1/2DPT 1

First expose the real ESPHome switch state to the feedback address:

knx:
  expose:
    - type: binary
      entity_id: switch.esp32_boiler_relay
      address: "4/1/2"
      send_on_init: true

If the relay is switched from Home Assistant, an ESPHome button, an ESPHome automation or a KNX command, the entity’s final state is what gets published to 4/1/2. That makes the state group address more useful than simply echoing the last KNX command.

Our ESP32 smart relay with ESPHome guide covers the ESPHome side, including relay state handling and restore behaviour.

Control an ESPHome Switch from KNX

An entity exposure publishes state, but it does not turn the exposed Home Assistant entity into a writable KNX actuator. To accept a KNX command, listen for a telegram on the command group address and call the ESPHome switch from a Home Assistant automation.

For a DPT 1 on/off command at 4/1/1:

automation:
  - alias: "KNX controls ESPHome boiler relay"
    triggers:
      - trigger: knx.telegram
        destination: "4/1/1"
        group_value_read: false
        group_value_response: false
        outgoing: false

    actions:
      - choose:
          - conditions: "{{ trigger.payload == 1 }}"
            sequence:
              - action: switch.turn_on
                target:
                  entity_id: switch.esp32_boiler_relay

          - conditions: "{{ trigger.payload == 0 }}"
            sequence:
              - action: switch.turn_off
                target:
                  entity_id: switch.esp32_boiler_relay

For DPT 1, the raw telegram payload is available as an integer. In this example 1 turns the relay on and 0 turns it off. If Home Assistant has KNX project data for the address, trigger.value may also provide the decoded value, but using the raw DPT 1 payload avoids depending on project-data decoding for this simple case.

outgoing: false is important. It limits the trigger to incoming telegrams rather than also reacting to telegrams sent by Home Assistant. We also disable GroupValueRead and GroupValueResponse triggers because the automation should react only to write commands.

Why Separate Command and Feedback Group Addresses?

You can sometimes use one KNX group address for both control and state, but a separate command address and feedback address is cleaner for an ESPHome bridge.

  • The command address represents what a KNX device wants the relay to do.
  • The state address represents what Home Assistant says the ESPHome entity is actually doing.
  • A failed ESPHome node does not produce a false state simply because the KNX command was sent.
  • Home Assistant is less likely to react to its own state telegram and create a loop.
  • The ETS project remains understandable to somebody maintaining the KNX installation later.

This becomes particularly useful when a relay can change state from several sources: a physical ESPHome input, Home Assistant automation, dashboard control and KNX wall switch.

Complete Sensor and Relay Example

Here is a compact Home Assistant configuration combining an ESPHome temperature, humidity and relay state:

knx:
  expose:
    - type: temperature
      entity_id: sensor.boiler_room_temperature
      address: "5/1/10"
      send_on_init: true
      cooldown: 30

    - type: humidity
      entity_id: sensor.boiler_room_humidity
      address: "5/1/11"
      send_on_init: true
      cooldown: 30

    - type: binary
      entity_id: switch.esp32_boiler_relay
      address: "4/1/2"
      send_on_init: true

automation:
  - alias: "KNX boiler relay command"
    triggers:
      - trigger: knx.telegram
        destination: "4/1/1"
        group_value_read: false
        group_value_response: false
        outgoing: false

    actions:
      - choose:
          - conditions: "{{ trigger.payload == 1 }}"
            sequence:
              - action: switch.turn_on
                target:
                  entity_id: switch.esp32_boiler_relay

          - conditions: "{{ trigger.payload == 0 }}"
            sequence:
              - action: switch.turn_off
                target:
                  entity_id: switch.esp32_boiler_relay

The data flow is now:

  • ESPHome temperature → Home Assistant → KNX 5/1/10.
  • ESPHome humidity → Home Assistant → KNX 5/1/11.
  • KNX command 4/1/1 → Home Assistant automation → ESPHome relay.
  • Actual ESPHome relay state → Home Assistant → KNX 4/1/2.

Using the Correct KNX Datapoint Type

KNX is typed. The group address does not simply carry a generic JSON number. Both ends need to agree on how the payload is encoded.

ESPHome / Home Assistant valueHome Assistant KNX typeTypical KNX DPT
On/off statebinaryDPT 1
TemperaturetemperatureDPT 9.001
Relative humidityhumidityDPT 9.007
0–100% valuepercentDPT 5.001
IlluminanceilluminanceDPT 9.004
CO₂ concentrationppmDPT 9.008

If the DPT is wrong, the telegram can still physically reach the bus while the receiving device interprets the bytes incorrectly. A temperature of 21.5 °C should not be published using a generic percentage or integer datapoint simply because both appear numeric in Home Assistant.

Avoiding Feedback Loops

Bridging two event-driven systems makes feedback loops possible. A typical bad sequence is:

KNX command
→ Home Assistant
→ ESPHome switch changes
→ Home Assistant sends KNX state
→ automation sees its own outgoing telegram
→ ESPHome switch is called again

The configuration above avoids this in three ways:

  • Use a separate command GA and state GA.
  • Use outgoing: false on the KNX telegram trigger.
  • Trigger only on GroupValueWrite, not reads or responses.

Also avoid creating a second Home Assistant automation that blindly copies the state GA back to the command GA. The KNX exposure already handles publishing the actual ESPHome state.

What Happens After a Home Assistant Restart?

ESPHome reconnects to Home Assistant through its native API and reports its entity states. A KNX exposure with send_on_init: true can then send the first valid state it learns to the KNX bus.

This makes sense for status objects such as temperature and relay feedback, but do not use restart behaviour as a substitute for proper fail-safe design. The ESPHome relay should have an appropriate restore_mode, and the KNX side should not assume a bridged device is healthy merely because an old group value exists.

What Happens if the ESP32 Goes Offline?

Home Assistant cannot publish a new physical sensor reading if the ESPHome device is unavailable. The last KNX value may remain on visualisations or devices that retain their previous state.

For values where stale data matters, add separate availability logic rather than assuming every number on the KNX bus is current. For example, an ESPHome device’s connectivity can be monitored in Home Assistant and exposed to a separate KNX binary alarm/status object.

This matters more for temperatures used in control logic than for informational values. A stale wall-display temperature is inconvenient; stale data controlling heating, pumps or ventilation can be a design problem.

KNX Bus Traffic: Do Not Send Every Sensor Update

ESPHome makes it easy to update sensors every second. That does not mean every change should be forwarded onto KNX.

For ordinary room temperature and humidity, update intervals of tens of seconds are already responsive. On the Home Assistant side, the KNX exposure cooldown option can further reduce traffic. Use periodic_send only when there is a reason for periodic refreshes.

For rapidly changing values such as power, flow or light level, consider filtering or rate-limiting on the ESPHome side before the value reaches Home Assistant. That reduces traffic across both the ESPHome API and KNX bridge.

Can KNX Read the Current ESPHome Value?

Yes. Home Assistant’s KNX entity exposure responds to GroupValueRead requests on the configured exposure address by default. That makes Home Assistant act as the value provider for that group address.

This is particularly useful after a KNX device restarts. It can request the current group value instead of waiting for the ESPHome sensor to change again. For critical status, you can combine readable exposure with send_on_init and a sensible periodic refresh.

Home Assistant KNX Exposure vs knx.send

Home Assistant also provides a knx.send action, but it is not the best first choice for continuously mirroring an ESPHome entity.

MethodBest use
knx: expose:Keep a Home Assistant entity state available on a KNX group address
knx.sendSend an explicit telegram from an automation or script
knx.telegram triggerReact to incoming or outgoing KNX telegrams
KNX entity platformRepresent a real KNX device as a Home Assistant entity

For ESPHome sensor states and relay feedback, expose is normally cleaner because Home Assistant automatically tracks the entity, sends changes and responds to reads.

Troubleshooting ESPHome to KNX

ProblemFirst checks
ESPHome value appears in Home Assistant but not KNXCheck KNX connection, group address, DPT and exposure YAML.
KNX device shows a nonsense numberConfirm ETS DPT matches the Home Assistant KNX type.
Relay command reaches Home Assistant but relay does not changeCheck the ESPHome entity ID and automation trace.
Relay switches repeatedly or automation fires twiceUse separate command/state GAs and set outgoing: false.
KNX read receives no valueCheck that the address is configured as an exposure and that the Home Assistant entity has a valid state.
Temperature floods the KNX busAdd an ESPHome filter, increase update interval or use KNX exposure cooldown.
State is wrong after a restartCheck ESPHome restore mode, actual device state and whether send_on_init is appropriate.
Nothing crosses a KNX routerCheck topology, router filter tables and that Home Assistant’s group addresses are permitted.

When This Architecture Makes Sense

This bridge is a strong fit for adding supplementary sensors to an existing KNX house: utility temperatures, humidity, air-quality sensors, water meters, energy monitoring, plant-room measurements, garage status or non-critical relays.

It is especially attractive when the information already exists in Home Assistant. You do not need a KNX transceiver on every ESP32, and you can choose inexpensive ESPHome-compatible sensor hardware while still making selected values available to KNX touch panels, logic modules or visualisations.

It is less suitable when the function must continue independently of Home Assistant. A KNX wall switch controlling a critical light, heating actuator or safety function is better kept as a native KNX path. Home Assistant can supervise or augment it without becoming the only route for basic operation.

Recommended Design

For most ESPHome-to-KNX projects, keep the design simple:

  • Let ESPHome own the physical sensor or relay.
  • Use the ESPHome native API to Home Assistant.
  • Expose sensor values and actual output states with the KNX expose feature.
  • Use a separate KNX command group address for writable outputs.
  • Use knx.telegram automations for commands from KNX to ESPHome.
  • Match every group address to the correct KNX datapoint type.
  • Rate-limit fast-changing sensors.
  • Do not make essential KNX functions depend entirely on Home Assistant.

That gives you a clean boundary between the systems: ESPHome handles inexpensive distributed I/O, Home Assistant handles translation and automation, and KNX continues to use normal group addresses and DPTs.

Related ESP32 and Home Assistant Guides

External Resources

Share your love