ESPHome 2025.5.0
Loading...
Searching...
No Matches
mqtt_backend_esp32.h
Go to the documentation of this file.
1#pragma once
2
3#include "mqtt_backend.h"
4#ifdef USE_MQTT
5#ifdef USE_ESP32
6
7#include <string>
8#include <queue>
9#include <mqtt_client.h>
12
13namespace esphome {
14namespace mqtt {
15
16struct Event {
17 esp_mqtt_event_id_t event_id;
18 std::vector<char> data;
21 std::string topic;
22 int msg_id;
23 bool retain;
24 int qos;
25 bool dup;
27 esp_mqtt_error_codes_t error_handle;
28
29 // Construct from esp_mqtt_event_t
30 // Any pointer values that are unsafe to keep are converted to safe copies
31 Event(const esp_mqtt_event_t &event)
32 : event_id(event.event_id),
33 data(event.data, event.data + event.data_len),
34 total_data_len(event.total_data_len),
35 current_data_offset(event.current_data_offset),
36 topic(event.topic, event.topic_len),
37 msg_id(event.msg_id),
38 retain(event.retain),
39 qos(event.qos),
40 dup(event.dup),
41 session_present(event.session_present),
42 error_handle(*event.error_handle) {}
43};
44
45class MQTTBackendESP32 final : public MQTTBackend {
46 public:
47 static const size_t MQTT_BUFFER_SIZE = 4096;
48
49 void set_keep_alive(uint16_t keep_alive) final { this->keep_alive_ = keep_alive; }
50 void set_client_id(const char *client_id) final { this->client_id_ = client_id; }
51 void set_clean_session(bool clean_session) final { this->clean_session_ = clean_session; }
52
53 void set_credentials(const char *username, const char *password) final {
54 if (username)
55 this->username_ = username;
56 if (password)
57 this->password_ = password;
58 }
59 void set_will(const char *topic, uint8_t qos, bool retain, const char *payload) final {
60 if (topic)
61 this->lwt_topic_ = topic;
62 this->lwt_qos_ = qos;
63 if (payload)
64 this->lwt_message_ = payload;
65 this->lwt_retain_ = retain;
66 }
67 void set_server(network::IPAddress ip, uint16_t port) final {
68 this->host_ = ip.str();
69 this->port_ = port;
70 }
71 void set_server(const char *host, uint16_t port) final {
72 this->host_ = host;
73 this->port_ = port;
74 }
75 void set_on_connect(std::function<on_connect_callback_t> &&callback) final {
76 this->on_connect_.add(std::move(callback));
77 }
78 void set_on_disconnect(std::function<on_disconnect_callback_t> &&callback) final {
79 this->on_disconnect_.add(std::move(callback));
80 }
81 void set_on_subscribe(std::function<on_subscribe_callback_t> &&callback) final {
82 this->on_subscribe_.add(std::move(callback));
83 }
84 void set_on_unsubscribe(std::function<on_unsubscribe_callback_t> &&callback) final {
85 this->on_unsubscribe_.add(std::move(callback));
86 }
87 void set_on_message(std::function<on_message_callback_t> &&callback) final {
88 this->on_message_.add(std::move(callback));
89 }
90 void set_on_publish(std::function<on_publish_user_callback_t> &&callback) final {
91 this->on_publish_.add(std::move(callback));
92 }
93 bool connected() const final { return this->is_connected_; }
94
95 void connect() final {
96 if (!is_initalized_) {
97 if (initialize_()) {
98 esp_mqtt_client_start(handler_.get());
99 }
100 }
101 }
102 void disconnect() final {
103 if (is_initalized_)
104 esp_mqtt_client_disconnect(handler_.get());
105 }
106
107 bool subscribe(const char *topic, uint8_t qos) final {
108 return esp_mqtt_client_subscribe(handler_.get(), topic, qos) != -1;
109 }
110 bool unsubscribe(const char *topic) final { return esp_mqtt_client_unsubscribe(handler_.get(), topic) != -1; }
111
112 bool publish(const char *topic, const char *payload, size_t length, uint8_t qos, bool retain) final {
113#if defined(USE_MQTT_IDF_ENQUEUE)
114 // use the non-blocking version
115 // it can delay sending a couple of seconds but won't block
116 return esp_mqtt_client_enqueue(handler_.get(), topic, payload, length, qos, retain, true) != -1;
117#else
118 // might block for several seconds, either due to network timeout (10s)
119 // or if publishing payloads longer than internal buffer (due to message fragmentation)
120 return esp_mqtt_client_publish(handler_.get(), topic, payload, length, qos, retain) != -1;
121#endif
122 }
124
125 void loop() final;
126
127 void set_ca_certificate(const std::string &cert) { ca_certificate_ = cert; }
128 void set_cl_certificate(const std::string &cert) { cl_certificate_ = cert; }
129 void set_cl_key(const std::string &key) { cl_key_ = key; }
130 void set_skip_cert_cn_check(bool skip_check) { skip_cert_cn_check_ = skip_check; }
131
132 protected:
133 bool initialize_();
134 void mqtt_event_handler_(const Event &event);
135 static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
136
138 void operator()(esp_mqtt_client *client_handler) { esp_mqtt_client_destroy(client_handler); }
139 };
140 using ClientHandler_ = std::unique_ptr<esp_mqtt_client, MqttClientDeleter>;
142
143 bool is_connected_{false};
144 bool is_initalized_{false};
145
146 esp_mqtt_client_config_t mqtt_cfg_{};
147
148 std::string host_;
149 uint16_t port_;
150 std::string username_;
151 std::string password_;
152 std::string lwt_topic_;
153 std::string lwt_message_;
154 uint8_t lwt_qos_;
156 std::string client_id_;
157 uint16_t keep_alive_;
163
164 // callbacks
171 std::queue<Event> mqtt_events_;
172};
173
174} // namespace mqtt
175} // namespace esphome
176
177#endif
178#endif
void set_keep_alive(uint16_t keep_alive) final
void set_on_message(std::function< on_message_callback_t > &&callback) final
CallbackManager< on_connect_callback_t > on_connect_
CallbackManager< on_disconnect_callback_t > on_disconnect_
void set_ca_certificate(const std::string &cert)
CallbackManager< on_message_callback_t > on_message_
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
static - Dispatch event to instance method
void set_client_id(const char *client_id) final
optional< std::string > ca_certificate_
CallbackManager< on_subscribe_callback_t > on_subscribe_
void set_on_publish(std::function< on_publish_user_callback_t > &&callback) final
void set_server(const char *host, uint16_t port) final
void set_cl_key(const std::string &key)
void set_on_connect(std::function< on_connect_callback_t > &&callback) final
void set_will(const char *topic, uint8_t qos, bool retain, const char *payload) final
bool subscribe(const char *topic, uint8_t qos) final
void set_server(network::IPAddress ip, uint16_t port) final
void set_cl_certificate(const std::string &cert)
CallbackManager< on_unsubscribe_callback_t > on_unsubscribe_
esp_mqtt_client_config_t mqtt_cfg_
void set_skip_cert_cn_check(bool skip_check)
void set_on_unsubscribe(std::function< on_unsubscribe_callback_t > &&callback) final
bool publish(const char *topic, const char *payload, size_t length, uint8_t qos, bool retain) final
CallbackManager< on_publish_user_callback_t > on_publish_
void set_clean_session(bool clean_session) final
bool unsubscribe(const char *topic) final
void set_on_subscribe(std::function< on_subscribe_callback_t > &&callback) final
void mqtt_event_handler_(const Event &event)
optional< std::string > cl_certificate_
void set_on_disconnect(std::function< on_disconnect_callback_t > &&callback) final
void set_credentials(const char *username, const char *password) final
std::unique_ptr< esp_mqtt_client, MqttClientDeleter > ClientHandler_
virtual bool publish(const char *topic, const char *payload, size_t length, uint8_t qos, bool retain)=0
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
esp_mqtt_event_id_t event_id
std::vector< char > data
esp_mqtt_error_codes_t error_handle
Event(const esp_mqtt_event_t &event)
void operator()(esp_mqtt_client *client_handler)
uint16_t length
Definition tt21100.cpp:0
uint8_t event_id
Definition tt21100.cpp:3