DEV Community

Cover image for Home Assistant and ESP Home: How to use MQTT Integration for Dynamic Device Configuration
Sebastian
Sebastian

Posted on

Home Assistant and ESP Home: How to use MQTT Integration for Dynamic Device Configuration

An MQTT message broker is the standard way to transfer information between different IOT devices. Home Assistant has a powerful MQTT integration for receiving, sending, and processing data. One powerful feature is to use MQTT messages as configuration instructions. The basic idea: Retained messages on the queue are read by devices to change their configuration.

There are several use cases where this behavior is useful. Imagine that you have devices operating in deep sleep cycles and want to apply OTA updates via the ESPHome dashboard. Can you press the OTA update button in in time when the device is operational, and will the upload of the new firmware happen in time? This use-case, preventing and setting deep sleep mode, is the running example of this article.

Let’s get started. First, we will see how MQTT is enabled in Home Assistant and give a quick introduction to the available configurations. Then we enable MQTT on ESPHome controlled boards, and test that log messages are printed when messages are received. Once this is confirmed, the final step is to add Home Assistant Dashboard card that trigger the "OTA Update" function.

The technical context of this article is Home Assistant 2024.11 and ESPHome 2024.10, but it should work with newer versions as well.

This article originally appeared at my blog admantium.com.

Home Assistant MQTT Configuration

To add an MQTT configuration to Home Assistant, put this into the configuation.yaml file:

mqtt:
  broker: "192.168.3.178"
  port: 8883
  username: "USERNAME"
  password: "PASSWORD"
Enter fullscreen mode Exit fullscreen mode

After a restart, you will find the new integration MQTT from the GUI.

For a simple test, I created this Node Red flow that listens to homeassistant/status messages. HA itself will send messages that communicate when its started or when it is about to shutdown. These messages, and a custom message I send from within HA, could be seen:

This configuration only scratches the surface. There are many more parameters - check the official documentation. An there are many more MQTT related integrations, such as controlling Humidifier or vaccuum cleaner.

ESPHome MQTT Configuration

For ESPHome, the MQTT Configuration needs to be defined for each sensor.

First, on the top level of your configuration file, add the mqtt section with these values:

mqtt:
  broker: "192.168.3.178"
  port: 8883
  username: "USERNAME"
  password: "PASSWORD"
  birth_message:
    topic: esp/devices
    payload: 'Booting ESP32'
  will_message:
    topic: esp/devices
    payload: 'Shutdown ESP32'
  on_message: []
Enter fullscreen mode Exit fullscreen mode

Then, the the beahvior to listen to MQTT messages can be defined in two sections: Inside the on_messsage section shown above, or as a seperate mqtt_subscribe numeric sensor and text sensor

Since preventing and entering deep sleep is core behavior of the sensor, I like to put in the above section. The entries consist of thre values: the topic, the expected payload, and a then action. The configuration is this:

mqtt:
  on_message:
    - topic: esp/ota_mode
      payload: 'ON'
      then:
        - deep_sleep.prevent: deep_sleep_esp32
    - topic: esp/sleep_mode
      payload: 'ON'
      then:
        - deep_sleep.enter: deep_sleep_esp32
Enter fullscreen mode Exit fullscreen mode

Important: The value to deep_sleep.prevent and deep_sleep.enter must match the id value of the deep sleep configuration, just as this:

deep_sleep:
  id: deep_sleep_esp32
  run_duration: 2min
  sleep_duration: 28min
Enter fullscreen mode Exit fullscreen mode

Testing MQTT with ESPHome is simple. Upon booting, the sensor will log its configuration. Any error is explicitly shown. A correct configuration will produce messages such as follows:

[11:28:14][C][mqtt:061]: MQTT:
[11:28:14][C][mqtt:063]:   Server Address: 192.168.2.200:1883 (192.168.2.200)
[11:28:14][C][mqtt:064]:   Username: [redacted]
[11:28:14][C][mqtt:065]:   Client ID: [redacted]
[11:28:14][C][mqtt:070]:   Topic Prefix: 'terra'
[11:28:14][C][mqtt:072]:   Log Topic: 'terra/debug'
[11:28:14][C][mqtt:075]:   Availability: 'esp/devices'
Enter fullscreen mode Exit fullscreen mode

In addition, let's see this message in NodeRed and confirm that the MQTT configuration works as well:

Home Assistant Lovelace Card to Trigger MQTT Messages

In principle, you can use any MQTT client library or programs like NodeRed to send MQTT messages. But wouldn't it be cooler to send them directly from the Home Assistant dashboard with the click on a button?

In Home Assistant, the MQTT Publish service allows sending messages. And that sending can be triggered by a custom dashboard card as explained in this Home Assistant community thread.

Got to the main Dashboard, click on the button "Add New Card", and then in the new dialogue, fill in the values as follows:

The resulting configuration yaml is this:

type: button
tap_action:
  action: call-service
  service: mqtt.publish
  service_data:
    topic: esp/ota_mode
    payload: 'ON'
  target: {}
name: ESP Enable OTA Mode
icon: hass:radio-tower
icon_height: 50px
Enter fullscreen mode Exit fullscreen mode

This configuration define a tap_action that will call the service mqtt.publish. We define the topic and the simple text payload. The button is shown in the dashboard immediately.

Let’s also add a similar button for entering the deep sleep mode:

type: button
tap_action:
  action: call-service
  service: mqtt.publish
  service_data:
    topic: esp/sleep_mode
    payload: 'ON'
    retain: 'true'
  target: {}
icon: hass:sleep
Enter fullscreen mode Exit fullscreen mode

Testing works - kinda. Immediately when this button is pressed, the device goes into deep sleep mode immediately, without any further warning!

[20:08:26][D][api:095]: Accepted 192.168.2.200
[20:08:26][D][api.connection:727]: Home Assistant 2021.9.7 (192.168.2.200): Connected successfully
INFO 192.168.3.212: Ping Failed!
INFO Disconnected from ESPHome API for 192.168.3.212
WARNING Disconnected from API
INFO 192.168.3.212: Unexpected error while reading incoming messages: 0 bytes read on a total of 56 expected bytes
Traceback (most recent call last):
Enter fullscreen mode Exit fullscreen mode

Without further warning, the device goes to sleep mode. Let make this better and print a custom log message beforehand. Change the MQTT subscribe configuration as follows:

mqtt:
  on_message:
    - topic: esp/ota_mode
      payload: 'ON'
      then:
        - lambda: |-
            ESP_LOGD("INFO", "Enabling OTA Mode");
            delay(100):
        - deep_sleep.prevent: deep_sleep_esp32
    - topic: esp/sleep_mode
      payload: 'ON'
      then:
        - lambda: |-
            ESP_LOGD("INFO", "Enabling Sleep Mode");
            delay(100):
        - deep_sleep.enter: deep_sleep_esp32
Enter fullscreen mode Exit fullscreen mode

That better: A small log message is printed beforehand:

[20:08:26][INFO]: "Enabling Sleep Mode"
Enter fullscreen mode Exit fullscreen mode

As another test, I set the "OTA Mode" and then waited for a deep sleep device to come online again. The log files showed the following messages, and the device stayed online, exactly as required.

[09:50:50][I][mqtt:212]: MQTT Connected!
[09:50:50][D][INFO:061]: Deep Sleep Disabled
Enter fullscreen mode Exit fullscreen mode

All things done. You can now enable OTA and sleep mode for your ESP devices with a button press from your Home Assistant Dashboard.

Next Steps

This article showed how to use MQTT to dynamically disable and enable the sleep mode for ESP Home sensors. This is particularly useful when you want to the do OTA updates. There are three steps: a) enable the MQTT integration in Home Assistant by adding parameters to the central configuration file, b) Add MQTT integration to each ESPHome controlled sensors and the behavior to be triggered when an MQTT message is received, and finally c) Define custom Home Assistant Dashboard cards that will send the MQTT messages. The article showed all configuration details and how to test them.

Top comments (0)