ESPHome  2022.5.1
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_ESP_IDF)
13 #include "mqtt_backend_idf.h"
14 #elif defined(USE_ARDUINO)
15 #include "mqtt_backend_arduino.h"
16 #endif
17 #include "lwip/ip_addr.h"
18 
19 namespace esphome {
20 namespace mqtt {
21 
26 using mqtt_callback_t = std::function<void(const std::string &, const std::string &)>;
27 using mqtt_json_callback_t = std::function<void(const std::string &, JsonObject)>;
28 
31  std::string topic;
32  uint8_t qos;
34  bool subscribed;
36 };
37 
40  std::string address;
41  uint16_t port;
42  std::string username;
43  std::string password;
44  std::string client_id;
45 };
46 
48 struct Availability {
49  std::string topic;
50  std::string payload_available;
51  std::string payload_not_available;
52 };
53 
58 };
59 
64 };
65 
71  std::string prefix;
72  bool retain;
73  bool clean;
76 };
77 
83 };
84 
85 class MQTTComponent;
86 
88  public:
90 
92  void set_last_will(MQTTMessage &&message);
94  void disable_last_will();
95 
97  void set_birth_message(MQTTMessage &&message);
99  void disable_birth_message();
100 
101  void set_shutdown_message(MQTTMessage &&message);
102  void disable_shutdown_message();
103 
105  void set_keep_alive(uint16_t keep_alive_s);
106 
115  void set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator,
116  MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain, bool clean = false);
118  const MQTTDiscoveryInfo &get_discovery_info() const;
120  void disable_discovery();
121  bool is_discovery_enabled() const;
122 
123 #if ASYNC_TCP_SSL_ENABLED
124 
136  void add_ssl_fingerprint(const std::array<uint8_t, SHA1_SIZE> &fingerprint);
137 #endif
138 #ifdef USE_ESP_IDF
139  void set_ca_certificate(const char *cert) { this->mqtt_backend_.set_ca_certificate(cert); }
140  void set_skip_cert_cn_check(bool skip_check) { this->mqtt_backend_.set_skip_cert_cn_check(skip_check); }
141 #endif
142  const Availability &get_availability();
143 
152  void set_topic_prefix(const std::string &topic_prefix);
154  const std::string &get_topic_prefix() const;
155 
157  void set_log_message_template(MQTTMessage &&message);
158  void set_log_level(int level);
160  void disable_log_message();
161  bool is_log_message_enabled() const;
162 
169  void subscribe(const std::string &topic, mqtt_callback_t callback, uint8_t qos = 0);
170 
180  void subscribe_json(const std::string &topic, const mqtt_json_callback_t &callback, uint8_t qos = 0);
181 
189  void unsubscribe(const std::string &topic);
190 
195  bool publish(const MQTTMessage &message);
196 
203  bool publish(const std::string &topic, const std::string &payload, uint8_t qos = 0, bool retain = false);
204 
205  bool publish(const std::string &topic, const char *payload, size_t payload_length, uint8_t qos = 0,
206  bool retain = false);
207 
214  bool publish_json(const std::string &topic, const json::json_build_t &f, uint8_t qos = 0, bool retain = false);
215 
217  void setup() override;
218  void dump_config() override;
220  void loop() override;
222  float get_setup_priority() const override;
223 
224  void on_message(const std::string &topic, const std::string &payload);
225 
226  bool can_proceed() override;
227 
228  void check_connected();
229 
230  void set_reboot_timeout(uint32_t reboot_timeout);
231 
232  void register_mqtt_component(MQTTComponent *component);
233 
234  bool is_connected();
235 
236  void on_shutdown() override;
237 
238  void set_broker_address(const std::string &address) { this->credentials_.address = address; }
239  void set_broker_port(uint16_t port) { this->credentials_.port = port; }
240  void set_username(const std::string &username) { this->credentials_.username = username; }
241  void set_password(const std::string &password) { this->credentials_.password = password; }
242  void set_client_id(const std::string &client_id) { this->credentials_.client_id = client_id; }
243 
244  protected:
246  void start_connect_();
247  void start_dnslookup_();
248  void check_dnslookup_();
249 #if defined(USE_ESP8266) && LWIP_VERSION_MAJOR == 1
250  static void dns_found_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg);
251 #else
252  static void dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg);
253 #endif
254 
256  void recalculate_availability_();
257 
258  bool subscribe_(const char *topic, uint8_t qos);
259  void resubscribe_subscription_(MQTTSubscription *sub);
260  void resubscribe_subscriptions_();
261 
269  bool sent_birth_message_{false};
272  Availability availability_{};
275  MQTTDiscoveryInfo discovery_info_{
276  .prefix = "homeassistant",
277  .retain = true,
278  .clean = false,
279  .unique_id_generator = MQTT_LEGACY_UNIQUE_ID_GENERATOR,
280  .object_id_generator = MQTT_NONE_OBJECT_ID_GENERATOR,
281  };
282  std::string topic_prefix_{};
284  std::string payload_buffer_;
285  int log_level_{ESPHOME_LOG_LEVEL};
286 
287  std::vector<MQTTSubscription> subscriptions_;
288 #if defined(USE_ESP_IDF)
290 #elif defined(USE_ARDUINO)
292 #endif
293 
296  bool dns_resolved_{false};
297  bool dns_resolve_error_{false};
298  std::vector<MQTTComponent *> children_;
299  uint32_t reboot_timeout_{300000};
300  uint32_t connect_begin_;
301  uint32_t last_connected_{0};
303 };
304 
305 extern MQTTClientComponent *global_mqtt_client; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
306 
307 class MQTTMessageTrigger : public Trigger<std::string>, public Component {
308  public:
309  explicit MQTTMessageTrigger(std::string topic);
310 
311  void set_qos(uint8_t qos);
312  void set_payload(const std::string &payload);
313  void setup() override;
314  void dump_config() override;
315  float get_setup_priority() const override;
316 
317  protected:
318  std::string topic_;
319  uint8_t qos_{0};
321 };
322 
323 class MQTTJsonMessageTrigger : public Trigger<JsonObjectConst> {
324  public:
325  explicit MQTTJsonMessageTrigger(const std::string &topic, uint8_t qos) {
326  global_mqtt_client->subscribe_json(
327  topic, [this](const std::string &topic, JsonObject root) { this->trigger(root); }, qos);
328  }
329 };
330 
331 template<typename... Ts> class MQTTPublishAction : public Action<Ts...> {
332  public:
333  MQTTPublishAction(MQTTClientComponent *parent) : parent_(parent) {}
334  TEMPLATABLE_VALUE(std::string, topic)
335  TEMPLATABLE_VALUE(std::string, payload)
336  TEMPLATABLE_VALUE(uint8_t, qos)
337  TEMPLATABLE_VALUE(bool, retain)
338 
339  void play(Ts... x) override {
340  this->parent_->publish(this->topic_.value(x...), this->payload_.value(x...), this->qos_.value(x...),
341  this->retain_.value(x...));
342  }
343 
344  protected:
345  MQTTClientComponent *parent_;
346 };
347 
348 template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
349  public:
350  MQTTPublishJsonAction(MQTTClientComponent *parent) : parent_(parent) {}
351  TEMPLATABLE_VALUE(std::string, topic)
352  TEMPLATABLE_VALUE(uint8_t, qos)
353  TEMPLATABLE_VALUE(bool, retain)
354 
355  void set_payload(std::function<void(Ts..., JsonObject)> payload) { this->payload_ = payload; }
356 
357  void play(Ts... x) override {
358  auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1);
359  auto topic = this->topic_.value(x...);
360  auto qos = this->qos_.value(x...);
361  auto retain = this->retain_.value(x...);
362  this->parent_->publish_json(topic, f, qos, retain);
363  }
364 
365  protected:
366  void encode_(Ts... x, JsonObject root) { this->payload_(x..., root); }
367  std::function<void(Ts..., JsonObject)> payload_;
369 };
370 
371 template<typename... Ts> class MQTTConnectedCondition : public Condition<Ts...> {
372  public:
373  MQTTConnectedCondition(MQTTClientComponent *parent) : parent_(parent) {}
374  bool check(Ts... x) override { return this->parent_->is_connected(); }
375 
376  protected:
378 };
379 
380 } // namespace mqtt
381 } // namespace esphome
382 
383 #endif // USE_MQTT
void setup()
MQTTConnectedCondition(MQTTClientComponent *parent)
Definition: mqtt_client.h:373
const char * name
Definition: stm32flash.h:78
void loop()
std::function< void(Ts..., JsonObject)> payload_
Definition: mqtt_client.h:367
optional< std::string > payload_
Definition: mqtt_client.h:320
void set_client_id(const std::string &client_id)
Definition: mqtt_client.h:242
MQTTPublishAction(MQTTClientComponent *parent)
Definition: mqtt_client.h:333
std::string topic
Empty means disabled.
Definition: mqtt_client.h:49
MQTTDiscoveryUniqueIdGenerator unique_id_generator
Definition: mqtt_client.h:74
Internal struct for MQTT Home Assistant discovery.
Definition: mqtt_client.h:70
std::function< void(const std::string &, const std::string &)> mqtt_callback_t
Callback for MQTT subscriptions.
Definition: mqtt_client.h:26
std::string client_id
The client ID. Will automatically be truncated to 23 characters.
Definition: mqtt_client.h:44
void set_broker_port(uint16_t port)
Definition: mqtt_client.h:239
internal struct for MQTT messages.
Definition: mqtt_backend.h:23
std::vector< MQTTComponent * > children_
Definition: mqtt_client.h:298
void encode_(Ts... x, JsonObject root)
Definition: mqtt_client.h:366
STL namespace.
MQTTMessage last_will_
The last will message.
Definition: mqtt_client.h:265
std::string prefix
The Home Assistant discovery prefix. Empty means disabled.
Definition: mqtt_client.h:71
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:140
void set_password(const std::string &password)
Definition: mqtt_client.h:241
void set_broker_address(const std::string &address)
Definition: mqtt_client.h:238
MQTTClientComponent * global_mqtt_client
Base class for all automation conditions.
Definition: automation.h:74
MQTTJsonMessageTrigger(const std::string &topic, uint8_t qos)
Definition: mqtt_client.h:325
uint16_t port
The port number of the server.
Definition: mqtt_client.h:41
MQTTDiscoveryUniqueIdGenerator
available discovery unique_id generators
Definition: mqtt_client.h:55
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:350
void set_ca_certificate(const char *cert)
Definition: mqtt_client.h:139
MQTTDiscoveryObjectIdGenerator
available discovery object_id generators
Definition: mqtt_client.h:61
internal struct for MQTT subscriptions.
Definition: mqtt_client.h:30
std::string address
The address of the server without port number.
Definition: mqtt_client.h:40
Simple data struct for Home Assistant component availability.
Definition: mqtt_client.h:48
MQTTMessage birth_message_
The birth message (e.g.
Definition: mqtt_client.h:268
Definition: a4988.cpp:4
std::string payload_not_available
Definition: mqtt_client.h:51
std::vector< MQTTSubscription > subscriptions_
Definition: mqtt_client.h:287
MQTTDiscoveryObjectIdGenerator object_id_generator
Definition: mqtt_client.h:75
void set_username(const std::string &username)
Definition: mqtt_client.h:240
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:39
MQTTBackendArduino mqtt_backend_
Definition: mqtt_client.h:291
bool retain
Whether to retain discovery messages.
Definition: mqtt_client.h:72
std::function< void(const std::string &, JsonObject)> mqtt_json_callback_t
Definition: mqtt_client.h:27
MQTTComponent is the base class for all components that interact with MQTT to expose certain function...