esphome-docs/components/mqtt.rst

558 lines
19 KiB
ReStructuredText
Raw Normal View History

2018-05-13 11:37:02 +02:00
MQTT Client Component
=====================
2018-11-14 22:12:27 +01:00
.. seo::
2019-02-16 23:25:23 +01:00
:description: Instructions for setting up the MQTT client to communicate with the local network in ESPHome.
2018-11-14 22:12:27 +01:00
:image: mqtt.png
:keywords: MQTT
2018-05-13 11:37:02 +02:00
The MQTT Client Component sets up the MQTT connection to your broker and
2019-02-16 23:25:23 +01:00
is currently required for ESPHome to work. In most cases, you will
2018-05-13 11:37:02 +02:00
just be able to copy over the `MQTT
section <https://www.home-assistant.io/components/mqtt/>`__ of your Home
Assistant configuration.
2019-03-11 13:31:12 +01:00
.. warning::
When enabling MQTT and you do *not* use the "native API" for Home Assistant, you must
remove the ``api:`` line from your ESPHome configuration, otherwise the ESP will
reboot every 5 minutes because no client connected to the native API.
.. code-block:: yaml
2018-05-13 11:37:02 +02:00
# Example configuration entry
mqtt:
broker: 10.0.0.2
username: livingroom
password: MyMQTTPassword
Configuration variables:
2018-08-24 22:44:01 +02:00
------------------------
2018-05-13 11:37:02 +02:00
2018-06-01 18:10:00 +02:00
- **broker** (**Required**, string): The host of your MQTT broker.
- **port** (*Optional*, int): The port to connect to. Defaults to 1883.
- **username** (*Optional*, string): The username to use for
authentication. Empty (the default) means no authentication.
- **password** (*Optional*, string): The password to use for
authentication. Empty (the default) means no authentication.
- **client_id** (*Optional*, string): The client id to use for opening
connections. See :ref:`mqtt-defaults` for more information.
- **discovery** (*Optional*, boolean): If Home Assistant automatic
discovery should be enabled. Defaults to ``True``.
- **discovery_retain** (*Optional*, boolean): Whether to retain MQTT
discovery messages so that entities are added automatically on Home
Assistant restart. Defaults to ``True``.
- **discovery_prefix** (*Optional*, string): The prefix to use for Home
Assistants MQTT discovery. Should not contain trailing slash.
Defaults to ``homeassistant``.
- **topic_prefix** (*Optional*, string): The prefix used for all MQTT
messages. Should not contain trailing slash. Defaults to
``<APP_NAME>``.
- **log_topic** (*Optional*, :ref:`mqtt-message`) The topic to send MQTT log
messages to.
- **birth_message** (*Optional*, :ref:`mqtt-message`): The message to send when
a connection to the broker is established. See :ref:`mqtt-last_will_birth` for more information.
- **will_message** (*Optional*, :ref:`mqtt-message`): The message to send when
the MQTT connection is dropped. See :ref:`mqtt-last_will_birth` for more information.
2018-08-27 13:21:30 +02:00
- **shutdown_message** (*Optional*, :ref:`mqtt-message`): The message to send when
the node shuts down and the connection is closed cleanly. See :ref:`mqtt-last_will_birth` for more information.
2018-06-01 18:10:00 +02:00
- **ssl_fingerprints** (*Optional*, list): Only on ESP8266. A list of SHA1 hashes used
for verifying SSL connections. See :ref:`mqtt-ssl_fingerprints`
for more information.
2018-06-13 22:38:49 +02:00
- **reboot_timeout** (*Optional*, :ref:`time <config-time>`): The amount of time to wait before rebooting when no
2019-07-28 12:41:15 +02:00
MQTT connection exists. Can be disabled by setting this to ``0s``. Defaults to ``15min``.
2018-06-01 18:10:00 +02:00
- **keepalive** (*Optional*, :ref:`config-time`): The time
to keep the MQTT socket alive, decreasing this can help with overall stability due to more
WiFi traffic with more pings. Defaults to 15 seconds.
- **on_message** (*Optional*, :ref:`Automation <automation>`): An action to be
performed when a message on a specific MQTT topic is received. See :ref:`mqtt-on_message`.
- **on_json_message** (*Optional*, :ref:`Automation <automation>`): An action to be
performed when a JSON message on a specific MQTT topic is received. See :ref:`mqtt-on_json_message`.
2018-06-01 18:10:00 +02:00
- **id** (*Optional*, :ref:`config-id`): Manually specify the ID used for code generation.
.. _mqtt-message:
2018-05-13 11:37:02 +02:00
MQTTMessage
2018-08-24 22:44:01 +02:00
-----------
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
With the MQTT Message schema you can tell ESPHome how a specific MQTT message should be sent.
2018-05-13 11:37:02 +02:00
It is used in several places like last will and birth messages or MQTT log options.
.. code-block:: yaml
2018-05-13 11:37:02 +02:00
# Simple:
some_option: topic/to/send/to
# Disable:
some_option:
# Advanced:
some_option:
topic: topic/to/send/to
payload: online
qos: 0
retain: True
Configuration options:
- **topic** (**Required**, string): The MQTT topic to publish the message.
- **payload** (**Required**, string): The message content. Will be filled by the actual payload with some
2018-05-13 11:37:02 +02:00
options, like log_topic.
- **qos** (*Optional*, int): The `Quality of
Service <https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels>`__
level of the topic. Defaults to 0.
- **retain** (*Optional*, boolean): If the published message should
have a retain flag on or not. Defaults to ``True``.
The ``log_topic`` has an additional configuration option:
- **level** (*Optional*, string): The log level to use for MQTT logs. See
:ref:`logger-log_levels` for options.
2018-11-03 16:21:10 +01:00
.. _mqtt-using_with_home_assistant:
2018-05-13 11:37:02 +02:00
Using with Home Assistant
2018-08-24 22:44:01 +02:00
-------------------------
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
Using ESPHome with Home Assistant is easy, simply setup an MQTT
2018-05-13 11:37:02 +02:00
broker (like `mosquitto <https://mosquitto.org/>`__) and point both your
2019-02-16 23:25:23 +01:00
Home Assistant installation and ESPHome to that broker. Next, enable
2018-05-13 11:37:02 +02:00
discovery in your Home Assistant configuration with the following:
.. code-block:: yaml
2018-05-13 11:37:02 +02:00
# Example Home Assistant configuration.yaml entry
mqtt:
broker: ...
discovery: True
2019-02-16 23:25:23 +01:00
And that should already be it 🎉 All devices defined through ESPHome should show up automatically
in the entities section of Home Assistant.
2018-05-13 11:37:02 +02:00
When adding new entities, you might run into trouble with old entities
still appearing in Home Assistants front-end. This is because in order
to have Home Assistant “discover” your devices on restart, all discovery
MQTT messages need to be retained. Therefore the old entities will also
re-appear on every Home Assistant restart even though theyre in
2019-02-16 23:25:23 +01:00
ESPHome anymore.
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
To fix this, ESPHome has a simple helper script that purges stale
2018-05-13 11:37:02 +02:00
retained messages for you:
.. code-block:: bash
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
esphome configuration.yaml clean-mqtt
2018-05-13 11:37:02 +02:00
With Docker:
.. code-block:: bash
docker run --rm -v "${PWD}":/config -it esphome/esphome configuration.yaml clean-mqtt
2018-05-13 11:37:02 +02:00
This will remove all retained messages with the topic
``<DISCOVERY_PREFIX>/+/NODE_NAME/#``. If you want to purge on another
topic, simply add ``--topic <your_topic>`` to the command.
2018-06-01 18:10:00 +02:00
.. _mqtt-defaults:
2018-05-13 11:37:02 +02:00
Defaults
2018-08-24 22:44:01 +02:00
--------
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
By default, ESPHome will prefix all messages with your node name or
2018-05-13 11:37:02 +02:00
``topic_prefix`` if you have specified it manually. The client id will
automatically be generated by using your node name and adding the MAC
address of your device to it. Next, discovery is enabled by default with
Home Assistants default prefix ``homeassistant``.
If you want to prefix all MQTT messages with a different prefix, like
``home/living_room``, you can specify a custom ``topic_prefix`` in the
configuration. That way, you can use your existing wildcards like
2019-02-16 23:25:23 +01:00
``home/+/#`` together with ESPHome. All other features of ESPHome
2018-06-05 21:08:00 +02:00
(like availability) should still work correctly.
2018-05-13 11:37:02 +02:00
2018-06-01 18:10:00 +02:00
.. _mqtt-last_will_birth:
2018-05-13 11:37:02 +02:00
Last Will And Birth Messages
2018-08-24 22:44:01 +02:00
----------------------------
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
ESPHome uses the `last will
2018-05-13 11:37:02 +02:00
testament <https://www.hivemq.com/blog/mqtt-essentials-part-9-last-will-and-testament>`__
2018-06-07 23:01:07 +02:00
and birth message feature of MQTT to achieve availability reporting for
2018-05-13 11:37:02 +02:00
Home Assistant. If the node is not connected to MQTT, Home Assistant
will show all its entities as unavailable (a feature 😉).
.. figure:: /components/images/mqtt-availability.png
2018-06-01 18:10:00 +02:00
:align: center
:width: 50.0%
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
By default, ESPHome will send a retained MQTT message to
2018-05-13 11:37:02 +02:00
``<TOPIC_PREFIX>/status`` with payload ``online``, and will tell the
broker to send a message ``<TOPIC_PREFIX>/status`` with payload
``offline`` if the connection drops.
You can change these messages by overriding the ``birth_message`` and
``will_message`` with the following options.
.. code-block:: yaml
2018-05-13 11:37:02 +02:00
mqtt:
# ...
birth_message:
topic: myavailability/topic
payload: online
will_message:
topic: myavailability/topic
payload: offline
2018-06-01 18:10:00 +02:00
- **birth_message** (*Optional*, :ref:`mqtt-message`)
- **will_message** (*Optional*, :ref:`mqtt-message`)
2018-05-13 11:37:02 +02:00
If the birth message and last will message have empty topics or topics
2018-06-07 23:01:07 +02:00
that are different from each other, availability reporting will be
2018-05-13 11:37:02 +02:00
disabled.
2018-06-01 18:10:00 +02:00
.. _mqtt-ssl_fingerprints:
2018-05-13 11:37:02 +02:00
SSL Fingerprints
2018-08-24 22:44:01 +02:00
----------------
2018-05-13 11:37:02 +02:00
On the ESP8266 you have the option to use SSL connections for MQTT. This feature
will get expanded to the ESP32 once the base library, AsyncTCP, supports it. Please
note that the SSL feature only checks the SHA1 hash of the SSL certificate to verify
the integrity of the connection, so every time the certificate changes, you'll have to
update the fingerprints variable. Additionally, SHA1 is known to be partially insecure
and with some computing power the fingerprint can be faked.
To get this fingerprint, first put the broker and port options in the configuration and
2019-02-16 23:25:23 +01:00
then run the ``mqtt-fingerprint`` script of ESPHome to get the certificate:
2018-05-13 11:37:02 +02:00
.. code-block:: bash
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
esphome livingroom.yaml mqtt-fingerprint
2018-05-13 11:37:02 +02:00
> SHA1 Fingerprint: a502ff13999f8b398ef1834f1123650b3236fc07
> Copy above string into mqtt.ssl_fingerprints section of livingroom.yaml
.. code-block:: yaml
2018-05-13 11:37:02 +02:00
mqtt:
# ...
ssl_fingerprints:
- a502ff13999f8b398ef1834f1123650b3236fc07
2018-06-01 18:10:00 +02:00
.. _config-mqtt-component:
2018-05-13 11:37:02 +02:00
MQTT Component Base Configuration
2018-08-24 22:44:01 +02:00
---------------------------------
2018-05-13 11:37:02 +02:00
2019-02-16 23:25:23 +01:00
All components in ESPHome that do some sort of communication through
2018-05-13 11:37:02 +02:00
MQTT can have some overrides for specific options.
.. code-block:: yaml
2018-05-13 11:37:02 +02:00
name: "Component Name"
# Optional variables:
retain: True
discovery: True
2018-06-07 23:01:07 +02:00
availability:
2018-05-13 11:37:02 +02:00
topic: livingroom/status
payload_available: online
payload_not_available: offline
state_topic: livingroom/custom_state_topic
command_topic: livingroom/custom_command_topic
Configuration variables:
- **name** (**Required**, string): The name to use for the MQTT
Component.
- **retain** (*Optional*, boolean): If all MQTT state messages should
be retained. Defaults to ``True``.
- **discovery** (*Optional*, boolean): Manually enable/disable
discovery for a component. Defaults to the global default.
2018-06-07 23:01:07 +02:00
- **availability** (*Optional*): Manually set what should be sent to
Home Assistant for showing entity availability. Default derived from
2018-06-01 18:10:00 +02:00
:ref:`global birth/last will message <mqtt-last_will_birth>`.
2018-05-13 11:37:02 +02:00
- **state_topic** (*Optional*, string): The topic to publish state
updates to. Defaults to
2018-06-06 08:56:22 +02:00
``<TOPIC_PREFIX>/<COMPONENT_TYPE>/<COMPONENT_NAME>/state``.
2018-05-13 11:37:02 +02:00
- **command_topic** (*Optional*, string): The topic to subscribe to for
commands from the remote. Defaults to
2018-06-06 08:56:22 +02:00
``<TOPIC_PREFIX>/<COMPONENT_TYPE>/<COMPONENT_NAME>/command``.
2018-05-13 11:37:02 +02:00
2018-06-07 23:01:07 +02:00
.. warning::
When changing these options and you're using MQTT discovery, you will need to restart Home Assistant.
This is because Home Assistant only discovers a device once in every Home Assistant start.
2018-06-01 18:10:00 +02:00
.. _mqtt-on_message:
``on_message`` Trigger
----------------------
2018-06-01 18:10:00 +02:00
With this configuration option you can write complex automations whenever an MQTT
2018-06-06 08:12:04 +02:00
message on a specific topic is received. To use the message content, use a :ref:`lambda <config-lambda>`
template, the message payload is available under the name ``x`` inside that lambda.
2018-06-01 18:10:00 +02:00
.. code-block:: yaml
2018-06-01 18:10:00 +02:00
mqtt:
# ...
on_message:
topic: my/custom/topic
qos: 0
then:
2018-11-10 14:31:27 +01:00
- switch.turn_on: some_switch
2018-06-01 18:10:00 +02:00
Configuration variables:
- **topic** (**Required**, string): The MQTT topic to subscribe to and listen for MQTT
messages on. Every time a message with **this exact topic** is received, the automation will trigger.
- **qos** (*Optional*, integer): The MQTT Quality of Service to subscribe to the topic with. Defaults
to 0.
- **payload** (*Optional*, string): Optionally set a payload to match. Only if exactly the payload
you specify with this option is received, the automation will be executed.
2018-06-01 18:10:00 +02:00
.. note::
You can even specify multiple ``on_message`` triggers by using a YAML list:
.. code-block:: yaml
2018-06-01 18:10:00 +02:00
mqtt:
on_message:
- topic: some/topic
then:
- # ...
- topic: some/other/topic
then:
- # ...
2018-10-31 16:27:55 +01:00
.. note::
This action can also be used in :ref:`lambdas <config-lambda>`:
.. code-block:: yaml
mqtt:
# Give the mqtt component an ID
id: mqtt_client
.. code-block:: cpp
2018-10-31 16:27:55 +01:00
id(mqtt_client).subscribe("the/topic", [=](const std::string &payload) {
2018-10-31 16:27:55 +01:00
// do something with payload
});
.. _mqtt-on_json_message:
``on_json_message`` Trigger
---------------------------
With this configuration option you can write complex automations whenever a JSON-encoded MQTT
message is received. To use the message content, use a :ref:`lambda <config-lambda>`
template, the decoded message payload is available under the name ``x`` inside that lambda.
The ``x`` object is of type ``JsonObject`` by the `ArduinoJson <https://github.com/bblanchon/ArduinoJson>`__
library, and you can use all of the methods of that library to access data.
Basically, you can access elements by typing ``x["THE_KEY"]`` and save them into local variables.
Please note that it's a good idea to check if the key exists in the Json Object by calling
``containsKey`` first as the ESP will crash if an element that does not exist is accessed.
.. code-block:: yaml
mqtt:
# ...
on_json_message:
topic: the/topic
then:
- light.turn_on:
id: living_room_lights
transition_length: !lambda |-
int length = 1000;
if (x.containsKey("length"))
length = x["length"];
return length;
brightness: !lambda "return x["bright"];"
effect: !lambda |-
const char *effect = "None";
if (x.containsKey("effect"))
effect = x["effect"];
return effect;
Configuration variables:
- **topic** (**Required**, string): The MQTT topic to subscribe to and listen for MQTT
messages on. Every time a message with **this exact topic** is received, the automation will trigger.
- **qos** (*Optional*, integer): The MQTT Quality of Service to subscribe to the topic with. Defaults
to 0.
.. note::
Due to the way this trigger works internally it is incompatible with certain actions and will
trigger a compile failure. For example with the ``delay`` action.
2018-10-31 16:27:55 +01:00
.. note::
This action can also be used in :ref:`lambdas <config-lambda>`:
.. code-block:: yaml
mqtt:
# Give the mqtt component an ID
id: mqtt_client
.. code-block:: cpp
2018-10-31 16:27:55 +01:00
id(mqtt_client).subscribe_json("the/topic", [=](JsonObject &root) {
2018-10-31 16:27:55 +01:00
// do something with JSON-decoded value root
});
2018-06-01 18:10:00 +02:00
.. _mqtt-publish_action:
``mqtt.publish`` Action
2018-08-24 22:44:01 +02:00
-----------------------
2018-06-01 18:10:00 +02:00
Publish an MQTT message on a topic using this action in automations.
.. code-block:: yaml
2018-06-01 18:10:00 +02:00
on_...:
then:
- mqtt.publish:
topic: some/topic
payload: "Something happened!"
# Templated:
- mqtt.publish:
2019-01-06 18:56:14 +01:00
topic: !lambda |-
if (id(reed_switch).state) return "topic1";
2018-06-01 18:10:00 +02:00
else return "topic2";
2019-01-06 18:56:14 +01:00
payload: !lambda |-
return id(reed_switch).state ? "YES" : "NO";
2018-06-01 18:10:00 +02:00
Configuration options:
- **topic** (*Required*, string, :ref:`templatable <config-templatable>`):
The MQTT topic to publish the message.
- **payload** (*Required*, string, :ref:`templatable <config-templatable>`): The message content.
- **qos** (*Optional*, int, :ref:`templatable <config-templatable>`): The `Quality of
Service <https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels>`__
level of the topic. Defaults to 0.
- **retain** (*Optional*, boolean, :ref:`templatable <config-templatable>`): If the published message should
have a retain flag on or not. Defaults to ``False``.
.. note::
This action can also be written in :ref:`lambdas <config-lambda>`:
.. code-block:: yaml
mqtt:
# Give the mqtt component an ID
id: mqtt_client
.. code-block:: cpp
2018-10-31 16:27:55 +01:00
id(mqtt_client).publish("the/topic", "The Payload");
.. _mqtt-publish_json_action:
``mqtt.publish_json`` Action
----------------------------
Publish a JSON-formatted MQTT message on a topic using this action in automations.
The JSON message will be constructed using the `ArduinoJson <https://github.com/bblanchon/ArduinoJson>`__ library.
In the ``payload`` option you have access to a ``root`` object which will represents the base object
of the JSON message. You can assign values to keys by using the ``root["KEY_NAME"] = VALUE;`` syntax
as seen below.
.. code-block:: yaml
on_...:
then:
- mqtt.publish_json:
topic: the/topic
payload: |-
2019-01-13 15:49:06 +01:00
root["key"] = id(my_sensor).state;
root["greeting"] = "Hello World";
# Will produce:
# {"key": 42.0, "greeting": "Hello World"}
Configuration options:
- **topic** (*Required*, string, :ref:`templatable <config-templatable>`):
The MQTT topic to publish the message.
- **payload** (*Required*, :ref:`lambda <config-lambda>`): The message content.
- **qos** (*Optional*, int): The `Quality of
Service <https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels>`__
level of the topic. Defaults to 0.
- **retain** (*Optional*, boolean): If the published message should
have a retain flag on or not. Defaults to ``False``.
2018-10-31 16:27:55 +01:00
.. note::
This action can also be written in :ref:`lambdas <config-lambda>`:
.. code-block:: yaml
2018-10-31 16:27:55 +01:00
mqtt:
# Give the mqtt component an ID
id: mqtt_client
.. code-block:: cpp
2018-10-31 16:27:55 +01:00
id(mqtt_client).publish_json("the/topic", [=](JsonObject &root) {
2019-01-13 15:49:06 +01:00
root["something"] = id(my_sensor).state;
2018-10-31 16:27:55 +01:00
});
2019-05-15 11:49:05 +02:00
.. _mqtt-connected_condition:
2019-05-12 22:44:59 +02:00
``mqtt.connected`` Condition
----------------------------
This :ref:`Condition <config-condition>` checks if the MQTT client is currently connected to
the MQTT broker.
.. code-block:: yaml
on_...:
if:
condition:
mqtt.connected:
then:
- logger.log: MQTT is connected!
2018-10-31 16:27:55 +01:00
.. note::
This action can also be written in :ref:`lambdas <config-lambda>`:
.. code-block:: yaml
mqtt:
# Give the mqtt component an ID
id: mqtt_client
.. code-block:: cpp
if (id(mqtt_client)->is_connected()) {
// do something if MQTT is connected
}
2018-06-01 18:10:00 +02:00
See Also
2018-08-24 22:44:01 +02:00
--------
2018-06-01 18:10:00 +02:00
2019-05-12 22:44:59 +02:00
- :apiref:`mqtt/mqtt_client.h`
- :ghedit:`Edit`