IoT

ESP32 and Home Assistant: A Practical Integration Model

ESP32 devices can feed sensors and controls into Home Assistant through a local integration architecture while keeping device responsibilities explicit.

  • esp32
  • iot

Divide responsibilities

Keep hardware-facing logic on the ESP32 and use Home Assistant for visualization, orchestration and higher-level automation. Basic safe device behavior should not depend on the dashboard being available.

One reproducible path: manual MQTT sensors

This documentation-based example uses synthetic messages, not a hardware experiment performed by ITHutir. Start with the MQTT article’s two-client check. Use a private broker compatible with your Home Assistant release and configure the MQTT integration under Settings > Devices & services > Add Integration > MQTT. Keep broker credentials in the private integration settings.

This path manually defines entities in YAML. MQTT discovery is a separate mechanism that publishes entity configuration to discovery topics; ordinary telemetry alone does not create an entity. Do not also discover duplicate copies of these example sensors.

Example entity and state mapping

In configuration.yaml, merge these sensor entries into your existing mqtt configuration; do not create a second mqtt key or replace existing sensors. These example entities are read-only. Check the configuration using your installation’s supported validation workflow and restart Home Assistant to apply it.

The temperature template reads temperature_c; the second sensor exposes quality as text. A 60-second receipt timeout makes silence visible. The fixed sampled_at field is deliberately not used for expiry: receipt freshness is different from measurement freshness. This minimal example does not reject invalid quality or stale timestamps and must not drive an actuator.

Expected states after the example publication
Entity namePayload fieldExpected state
Example ESP32 Temperaturetemperature_c23.5, unit °C; then 24.0 after the changed sample
Example ESP32 Qualityqualityexample; this describes synthetic input, not online status
mqtt:
  sensor:
    - name: "Example ESP32 Temperature"
      unique_id: "ithutir_example_esp32_temperature"
      state_topic: "ithutir/example/esp32-node-01/telemetry"
      value_template: "{{ value_json.temperature_c }}"
      unit_of_measurement: "°C"
      expire_after: 60
    - name: "Example ESP32 Quality"
      unique_id: "ithutir_example_esp32_quality"
      state_topic: "ithutir/example/esp32-node-01/telemetry"
      value_template: "{{ value_json.quality }}"
      expire_after: 60

Verify receipt and entity state separately

In the MQTT integration’s topic listener, subscribe to ithutir/example/esp32-node-01/telemetry before publishing the MQTT article’s JSON with retain disabled. Then inspect both entities in Developer tools > States. Find them by their configured names and actual entity IDs; IDs can differ if names already exist. Do not use Set state to simulate success: that changes Home Assistant’s representation, not the MQTT input.

  • Publish the synthetic sample: expect temperature 23.5 °C and quality example. Publish temperature_c = 24.0 next and verify the temperature changes; display formatting may omit the trailing zero.
  • Stop publishing for more than 60 seconds: both sensors should become unavailable. Publish again to restore their states. The timeout is an example policy, not a measured device interval; retain stays disabled so replay cannot make stale samples appear newly received.
  • No topic-listener message points to broker connectivity, the exact topic or ACL permissions. A message visible in the listener but an unknown or unchanged entity points to unloaded configuration, the wrong entity/topic, missing JSON fields or a template error; inspect Home Assistant logs.
  • A numeric temperature alongside quality invalid is not a safe reading. This demonstration exposes quality but does not enforce it. Real automation needs validated quality, timestamps, calibrated limits and device-local fail-safe logic.

Expose state, not just commands

Expose measured state and actuator state, not only commands. A command is not proof that the physical action succeeded; add feedback or fault detection where the hardware requires it.

Local-first behavior

A local Home Assistant + MQTT architecture can operate without making basic device function depend on a cloud service. Validate the real driver, default state and failure behavior before automating a valve or other load.

These are verified external purchasing options relevant to this article. Check the current price, availability and exact specifications before buying.

Back to Blog