ESPHome  2024.12.2
mqtt_client.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "esphome/core/defines.h"
4 
5 #ifdef USE_MQTT
6 
9 #include "esphome/core/log.h"
12 #if defined(USE_ESP32)
13 #include "mqtt_backend_esp32.h"
14 #elif defined(USE_ESP8266)
15 #include "mqtt_backend_esp8266.h"
16 #elif defined(USE_LIBRETINY)
17 #include "mqtt_backend_libretiny.h"
18 #endif
19 #include "lwip/ip_addr.h"
20 
21 #include <vector>
22 
23 namespace esphome {
24 namespace mqtt {
25 
28 using mqtt_on_connect_callback_t = std::function<MQTTBackend::on_connect_callback_t>;
29 using mqtt_on_disconnect_callback_t = std::function<MQTTBackend::on_disconnect_callback_t>;
30 
35 using mqtt_callback_t = std::function<void(const std::string &, const std::string &)>;
36 using mqtt_json_callback_t = std::function<void(const std::string &, JsonObject)>;
37 
40  std::string topic;
41  uint8_t qos;
43  bool subscribed;
45 };
46 
49  std::string address;
50  uint16_t port;
51  std::string username;
52  std::string password;
53  std::string client_id;
55 };
56 
58 struct Availability {
59  std::string topic;
60  std::string payload_available;
61  std::string payload_not_available;
62 };
63 
68 };
69 
74 };
75 
81  std::string prefix;
82  bool retain;
83  bool discover_ip;
84  bool clean;
87 };
88 
95 };
96 
97 class MQTTComponent;
98 
100  public:
102 
104  void set_last_will(MQTTMessage &&message);
106  void disable_last_will();
107 
109  void set_birth_message(MQTTMessage &&message);
111  void disable_birth_message();
112 
113  void set_shutdown_message(MQTTMessage &&message);
114  void disable_shutdown_message();
115 
117  void set_keep_alive(uint16_t keep_alive_s);
118 
127  void set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator,
128  MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain, bool discover_ip,
129  bool clean = false);
131  const MQTTDiscoveryInfo &get_discovery_info() const;
133  void disable_discovery();
134  bool is_discovery_enabled() const;
135  bool is_discovery_ip_enabled() const;
136 
137 #if ASYNC_TCP_SSL_ENABLED
138 
150  void add_ssl_fingerprint(const std::array<uint8_t, SHA1_SIZE> &fingerprint);
151 #endif
152 #ifdef USE_ESP32
153  void set_ca_certificate(const char *cert) { this->mqtt_backend_.set_ca_certificate(cert); }
154  void set_cl_certificate(const char *cert) { this->mqtt_backend_.set_cl_certificate(cert); }
155  void set_cl_key(const char *key) { this->mqtt_backend_.set_cl_key(key); }
156  void set_skip_cert_cn_check(bool skip_check) { this->mqtt_backend_.set_skip_cert_cn_check(skip_check); }
157 #endif
158  const Availability &get_availability();
159 
168  void set_topic_prefix(const std::string &topic_prefix);
170  const std::string &get_topic_prefix() const;
171 
173  void set_log_message_template(MQTTMessage &&message);
174  void set_log_level(int level);
176  void disable_log_message();
177  bool is_log_message_enabled() const;
178 
185  void subscribe(const std::string &topic, mqtt_callback_t callback, uint8_t qos = 0);
186 
196  void subscribe_json(const std::string &topic, const mqtt_json_callback_t &callback, uint8_t qos = 0);
197 
205  void unsubscribe(const std::string &topic);
206 
211  bool publish(const MQTTMessage &message);
212 
219  bool publish(const std::string &topic, const std::string &payload, uint8_t qos = 0, bool retain = false);
220 
221  bool publish(const std::string &topic, const char *payload, size_t payload_length, uint8_t qos = 0,
222  bool retain = false);
223 
230  bool publish_json(const std::string &topic, const json::json_build_t &f, uint8_t qos = 0, bool retain = false);
231 
233  void setup() override;
234  void dump_config() override;
236  void loop() override;
238  float get_setup_priority() const override;
239 
240  void on_message(const std::string &topic, const std::string &payload);
241 
242  bool can_proceed() override;
243 
244  void check_connected();
245 
246  void set_reboot_timeout(uint32_t reboot_timeout);
247 
248  void register_mqtt_component(MQTTComponent *component);
249 
250  bool is_connected();
251  void set_enable_on_boot(bool enable_on_boot) { this->enable_on_boot_ = enable_on_boot; }
252  void enable();
253  void disable();
254 
255  void on_shutdown() override;
256 
257  void set_broker_address(const std::string &address) { this->credentials_.address = address; }
258  void set_broker_port(uint16_t port) { this->credentials_.port = port; }
259  void set_username(const std::string &username) { this->credentials_.username = username; }
260  void set_password(const std::string &password) { this->credentials_.password = password; }
261  void set_client_id(const std::string &client_id) { this->credentials_.client_id = client_id; }
262  void set_clean_session(const bool &clean_session) { this->credentials_.clean_session = clean_session; }
263  void set_on_connect(mqtt_on_connect_callback_t &&callback);
264  void set_on_disconnect(mqtt_on_disconnect_callback_t &&callback);
265 
266  // Publish None state instead of NaN for Home Assistant
267  void set_publish_nan_as_none(bool publish_nan_as_none);
268  bool is_publish_nan_as_none() const;
269 
270  protected:
271  void send_device_info_();
272 
274  void start_connect_();
275  void start_dnslookup_();
276  void check_dnslookup_();
277 #if defined(USE_ESP8266) && LWIP_VERSION_MAJOR == 1
278  static void dns_found_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg);
279 #else
280  static void dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg);
281 #endif
282 
284  void recalculate_availability_();
285 
286  bool subscribe_(const char *topic, uint8_t qos);
287  void resubscribe_subscription_(MQTTSubscription *sub);
288  void resubscribe_subscriptions_();
289 
297  bool sent_birth_message_{false};
300  Availability availability_{};
303  MQTTDiscoveryInfo discovery_info_{
304  .prefix = "homeassistant",
305  .retain = true,
306  .discover_ip = true,
307  .clean = false,
308  .unique_id_generator = MQTT_LEGACY_UNIQUE_ID_GENERATOR,
309  .object_id_generator = MQTT_NONE_OBJECT_ID_GENERATOR,
310  };
311  std::string topic_prefix_{};
313  std::string payload_buffer_;
314  int log_level_{ESPHOME_LOG_LEVEL};
315 
316  std::vector<MQTTSubscription> subscriptions_;
317 #if defined(USE_ESP32)
319 #elif defined(USE_ESP8266)
321 #elif defined(USE_LIBRETINY)
323 #endif
324 
327  bool dns_resolved_{false};
328  bool dns_resolve_error_{false};
329  bool enable_on_boot_{true};
330  std::vector<MQTTComponent *> children_;
331  uint32_t reboot_timeout_{300000};
332  uint32_t connect_begin_;
333  uint32_t last_connected_{0};
335 
336  bool publish_nan_as_none_{false};
337 };
338 
339 extern MQTTClientComponent *global_mqtt_client; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
340 
341 class MQTTMessageTrigger : public Trigger<std::string>, public Component {
342  public:
343  explicit MQTTMessageTrigger(std::string topic);
344 
345  void set_qos(uint8_t qos);
346  void set_payload(const std::string &payload);
347  void setup() override;
348  void dump_config() override;
349  float get_setup_priority() const override;
350 
351  protected:
352  std::string topic_;
353  uint8_t qos_{0};
355 };
356 
357 class MQTTJsonMessageTrigger : public Trigger<JsonObjectConst> {
358  public:
359  explicit MQTTJsonMessageTrigger(const std::string &topic, uint8_t qos) {
360  global_mqtt_client->subscribe_json(
361  topic, [this](const std::string &topic, JsonObject root) { this->trigger(root); }, qos);
362  }
363 };
364 
365 class MQTTConnectTrigger : public Trigger<> {
366  public:
368  client->set_on_connect([this](bool session_present) { this->trigger(); });
369  }
370 };
371 
372 class MQTTDisconnectTrigger : public Trigger<> {
373  public:
375  client->set_on_disconnect([this](MQTTClientDisconnectReason reason) { this->trigger(); });
376  }
377 };
378 
379 template<typename... Ts> class MQTTPublishAction : public Action<Ts...> {
380  public:
381  MQTTPublishAction(MQTTClientComponent *parent) : parent_(parent) {}
382  TEMPLATABLE_VALUE(std::string, topic)
383  TEMPLATABLE_VALUE(std::string, payload)
384  TEMPLATABLE_VALUE(uint8_t, qos)
385  TEMPLATABLE_VALUE(bool, retain)
386 
387  void play(Ts... x) override {
388  this->parent_->publish(this->topic_.value(x...), this->payload_.value(x...), this->qos_.value(x...),
389  this->retain_.value(x...));
390  }
391 
392  protected:
393  MQTTClientComponent *parent_;
394 };
395 
396 template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
397  public:
398  MQTTPublishJsonAction(MQTTClientComponent *parent) : parent_(parent) {}
399  TEMPLATABLE_VALUE(std::string, topic)
400  TEMPLATABLE_VALUE(uint8_t, qos)
401  TEMPLATABLE_VALUE(bool, retain)
402 
403  void set_payload(std::function<void(Ts..., JsonObject)> payload) { this->payload_ = payload; }
404 
405  void play(Ts... x) override {
406  auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1);
407  auto topic = this->topic_.value(x...);
408  auto qos = this->qos_.value(x...);
409  auto retain = this->retain_.value(x...);
410  this->parent_->publish_json(topic, f, qos, retain);
411  }
412 
413  protected:
414  void encode_(Ts... x, JsonObject root) { this->payload_(x..., root); }
415  std::function<void(Ts..., JsonObject)> payload_;
417 };
418 
419 template<typename... Ts> class MQTTConnectedCondition : public Condition<Ts...> {
420  public:
421  MQTTConnectedCondition(MQTTClientComponent *parent) : parent_(parent) {}
422  bool check(Ts... x) override { return this->parent_->is_connected(); }
423 
424  protected:
426 };
427 
428 template<typename... Ts> class MQTTEnableAction : public Action<Ts...> {
429  public:
430  MQTTEnableAction(MQTTClientComponent *parent) : parent_(parent) {}
431 
432  void play(Ts... x) override { this->parent_->enable(); }
433 
434  protected:
436 };
437 
438 template<typename... Ts> class MQTTDisableAction : public Action<Ts...> {
439  public:
440  MQTTDisableAction(MQTTClientComponent *parent) : parent_(parent) {}
441 
442  void play(Ts... x) override { this->parent_->disable(); }
443 
444  protected:
446 };
447 
448 } // namespace mqtt
449 } // namespace esphome
450 
451 #endif // USE_MQTT
void setup()
MQTTConnectedCondition(MQTTClientComponent *parent)
Definition: mqtt_client.h:421
const char * name
Definition: stm32flash.h:78
void loop()
std::function< void(Ts..., JsonObject)> payload_
Definition: mqtt_client.h:415
bool clean_session
Whether the session will be cleaned or remembered between connects.
Definition: mqtt_client.h:54
MQTTClientComponent * parent_
Definition: mqtt_client.h:435
optional< std::string > payload_
Definition: mqtt_client.h:354
void set_client_id(const std::string &client_id)
Definition: mqtt_client.h:261
MQTTPublishAction(MQTTClientComponent *parent)
Definition: mqtt_client.h:381
std::string topic
Empty means disabled.
Definition: mqtt_client.h:59
MQTTDiscoveryUniqueIdGenerator unique_id_generator
Definition: mqtt_client.h:85
Internal struct for MQTT Home Assistant discovery.
Definition: mqtt_client.h:80
void set_cl_certificate(const char *cert)
Definition: mqtt_client.h:154
std::function< void(const std::string &, const std::string &)> mqtt_callback_t
Callback for MQTT subscriptions.
Definition: mqtt_client.h:35
std::string client_id
The client ID. Will automatically be truncated to 23 characters.
Definition: mqtt_client.h:53
void set_broker_port(uint16_t port)
Definition: mqtt_client.h:258
uint16_t x
Definition: tt21100.cpp:17
internal struct for MQTT messages.
Definition: mqtt_backend.h:24
std::vector< MQTTComponent * > children_
Definition: mqtt_client.h:330
void encode_(Ts... x, JsonObject root)
Definition: mqtt_client.h:414
STL namespace.
void set_enable_on_boot(bool enable_on_boot)
Definition: mqtt_client.h:251
MQTTMessage last_will_
The last will message.
Definition: mqtt_client.h:293
bool discover_ip
Enable the Home Assistant device discovery.
Definition: mqtt_client.h:83
std::string prefix
The Home Assistant discovery prefix. Empty means disabled.
Definition: mqtt_client.h:81
std::function< MQTTBackend::on_connect_callback_t > mqtt_on_connect_callback_t
Callback for MQTT events.
Definition: mqtt_client.h:28
bool is_connected()
Return whether the node is connected to the network (through wifi, eth, ...)
Definition: util.cpp:15
void set_skip_cert_cn_check(bool skip_check)
Definition: mqtt_client.h:156
void set_on_connect(mqtt_on_connect_callback_t &&callback)
void set_password(const std::string &password)
Definition: mqtt_client.h:260
void set_broker_address(const std::string &address)
Definition: mqtt_client.h:257
MQTTClientComponent * global_mqtt_client
MQTTDisableAction(MQTTClientComponent *parent)
Definition: mqtt_client.h:440
Base class for all automation conditions.
Definition: automation.h:74
MQTTJsonMessageTrigger(const std::string &topic, uint8_t qos)
Definition: mqtt_client.h:359
MQTTBackendESP8266 mqtt_backend_
Definition: mqtt_client.h:320
uint16_t port
The port number of the server.
Definition: mqtt_client.h:50
MQTTDiscoveryUniqueIdGenerator
available discovery unique_id generators
Definition: mqtt_client.h:65
std::function< void(JsonObject)> json_build_t
Callback function typedef for building JsonObjects.
Definition: json_util.h:20
MQTTPublishJsonAction(MQTTClientComponent *parent)
Definition: mqtt_client.h:398
void set_ca_certificate(const char *cert)
Definition: mqtt_client.h:153
MQTTDiscoveryObjectIdGenerator
available discovery object_id generators
Definition: mqtt_client.h:71
internal struct for MQTT subscriptions.
Definition: mqtt_client.h:39
MQTTBackendLibreTiny mqtt_backend_
Definition: mqtt_client.h:322
std::string address
The address of the server without port number.
Definition: mqtt_client.h:49
MQTTEnableAction(MQTTClientComponent *parent)
Definition: mqtt_client.h:430
Simple data struct for Home Assistant component availability.
Definition: mqtt_client.h:58
MQTTClientComponent * parent_
Definition: mqtt_client.h:445
std::function< MQTTBackend::on_disconnect_callback_t > mqtt_on_disconnect_callback_t
Definition: mqtt_client.h:29
void play(Ts... x) override
Definition: mqtt_client.h:432
MQTTMessage birth_message_
The birth message (e.g.
Definition: mqtt_client.h:296
void set_clean_session(const bool &clean_session)
Definition: mqtt_client.h:262
in_addr ip_addr_t
Definition: ip_address.h:22
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
std::string payload_not_available
Definition: mqtt_client.h:61
MQTTConnectTrigger(MQTTClientComponent *&client)
Definition: mqtt_client.h:367
uint8_t address
Definition: bl0906.h:211
std::vector< MQTTSubscription > subscriptions_
Definition: mqtt_client.h:316
MQTTDiscoveryObjectIdGenerator object_id_generator
Definition: mqtt_client.h:86
void set_cl_key(const char *key)
Definition: mqtt_client.h:155
void set_username(const std::string &username)
Definition: mqtt_client.h:259
void subscribe_json(const std::string &topic, const mqtt_json_callback_t &callback, uint8_t qos=0)
Subscribe to a MQTT topic and automatically parse JSON payload.
internal struct for MQTT credentials.
Definition: mqtt_client.h:48
MQTTDisconnectTrigger(MQTTClientComponent *&client)
Definition: mqtt_client.h:374
void set_on_disconnect(mqtt_on_disconnect_callback_t &&callback)
void play(Ts... x) override
Definition: mqtt_client.h:442
bool retain
Whether to retain discovery messages.
Definition: mqtt_client.h:82
std::function< void(const std::string &, JsonObject)> mqtt_json_callback_t
Definition: mqtt_client.h:36
MQTTComponent is the base class for all components that interact with MQTT to expose certain function...