11#include " publish.h"
22#include " Logging.h"
3- #include " setup.h"
43#include < PubSubClient.h>
5- #include < ArduinoJson.h>
6-
7- extern Settings sett;
84
95/* *
10- * @brief Публикация топика в MQTT в различных режимах
6+ * @brief Публикация топика в MQTT
117 *
12- * @param mqtt_client клиент MQTT
13- * @param topic строка с топиком
14- * @param payload содержимое топика
15- * @param mode режим публикации, режим по умолчанию PUBLISH_MODE_BIG
16- */
17- void publish (PubSubClient &mqtt_client, const String &topic, const String &payload, const int mode)
18- {
19- switch (mode)
20- {
21- case PUBLISH_MODE_SIMPLE :
22- publish_simple (mqtt_client, topic, payload);
23- break ;
24- case PUBLISH_MODE_CHUNKED :
25- publish_chunked (mqtt_client, topic, payload);
26- break ;
27- case PUBLISH_MODE_BIG :
28- default :
29- publish_big (mqtt_client, topic, payload);
30- }
31- }
32-
33- /* *
34- * @brief Публикация топика в MQTT по частям,
35- * используется в случае если очень много информации
8+ * Без промежуточного буфера: сообщение может быть больше буфера клиента.
9+ * QoS 0, поэтому «опубликовано» значит «записано в сокет целиком» -
10+ * подтверждения от брокера нет. endPublish у PubSubClient 2.8 всегда
11+ * возвращает 1, судить о результате по нему нельзя.
3612 *
3713 * @param mqtt_client клиент MQTT
3814 * @param topic строка с топиком
3915 * @param payload содержимое топика
16+ * @param retain флаг retain
17+ * @return true сообщение ушло в сокет целиком
4018 */
41- void publish_chunked (PubSubClient &mqtt_client,
42- const String &topic,
43- const String &payload,
44- const unsigned int chunk_size)
19+ bool publish (PubSubClient &mqtt_client, const String &topic, const String &payload, bool retain)
4520{
4621 LOG_INFO (F (" Free memory: " ) << ESP .getFreeHeap ());
4722 LOG_INFO (F (" MQTT: Publish Topic: " ) << topic);
4823 LOG_INFO (F (" MQTT: Payload Size: " ) << payload.length ());
4924 LOG_DEBUG (F (" MQTT: Payload: " ) << payload);
25+ LOG_INFO (F (" MQTT: Retain: " ) << retain);
5026
51- unsigned int len = payload.length ();
52- const uint8_t *buf = (const uint8_t *)payload.c_str ();
53-
54- if (mqtt_client.beginPublish (topic.c_str (), len, (bool )sett.mqtt_retain ))
27+ const unsigned int len = payload.length ();
28+ if (!mqtt_client.beginPublish (topic.c_str (), len, retain))
5529 {
56- while (len > 0 )
57- {
58- if (len >= chunk_size)
59- {
60- mqtt_client.write (buf, chunk_size);
61- buf += chunk_size;
62- len -= chunk_size;
63- LOG_INFO (F (" MQTT: Sended chunk size: " ) << chunk_size);
64- }
65- else
66- {
67- mqtt_client.write (buf, len);
68- LOG_INFO (F (" MQTT: Sended chunk size: " ) << len);
69- break ;
70- }
71- }
72- if (mqtt_client.endPublish ())
73- {
74- LOG_INFO (F (" MQTT: Published succesfully" ));
75- }
76- else
77- {
78- LOG_ERROR (F (" MQTT: Publish failed" ));
79- }
30+ LOG_ERROR (F (" MQTT: Publish failed: no connection" ));
31+ return false ;
8032 }
81- else
82- {
83- LOG_ERROR (F (" MQTT: Client not connected." ));
84- }
85- }
86-
87- /* *
88- * @brief Публикация топика в MQTT (основной метод)
89- * не использует промежуточных буферов,
90- * сообщение может иметь размер больше 250 байт
91- *
92- * @param mqtt_client клиент MQTT
93- * @param topic строка с топиком
94- * @param payload содержимое топика
95- */
96- void publish_big (PubSubClient &mqtt_client,
97- const String &topic,
98- const String &payload)
99- {
100- LOG_INFO (F (" Free memory: " ) << ESP .getFreeHeap ());
101- LOG_INFO (F (" MQTT: Publish Topic: " ) << topic);
102- LOG_INFO (F (" MQTT: Payload Size: " ) << payload.length ());
103- LOG_DEBUG (F (" MQTT: Payload: " ) << payload);
10433
105- unsigned int len = payload.length ();
106- LOG_INFO (F (" MQTT: Retain: " ) << sett.mqtt_retain );
107- if (mqtt_client.beginPublish (topic.c_str (), len, (bool )sett.mqtt_retain ))
108- {
109- if (mqtt_client.print (payload.c_str ()) == len)
110- {
111- LOG_INFO (F (" MQTT: Published succesfully" ));
112- }
113- else
114- {
115- LOG_ERROR (F (" MQTT: Publish failed" ));
116- }
34+ const bool sent = mqtt_client.print (payload.c_str ()) == len;
35+ mqtt_client.endPublish ();
11736
118- mqtt_client.endPublish ();
119- }
120- else
37+ if (!sent)
12138 {
122- LOG_ERROR (F (" MQTT: Client not connected." ));
39+ LOG_ERROR (F (" MQTT: Publish failed" ));
40+ return false ;
12341 }
124- }
125- /* *
126- * @brief Публикация топика в MQTT если сообщение меньше 250 символов
127- *
128- * @param mqtt_client клиент MQTT
129- * @param topic строка с топиком
130- * @param payload содержимое топика
131- */
132- void publish_simple (PubSubClient &mqtt_client, const String &topic, const String &payload)
133- {
134- LOG_INFO (F (" Free memory: " ) << ESP .getFreeHeap ());
135- LOG_INFO (F (" MQTT: Publish Topic: " ) << topic);
136- LOG_INFO (F (" MQTT: Payload Size: " ) << payload.length ());
137- LOG_DEBUG (F (" MQTT: Payload: " ) << payload);
13842
139- if (mqtt_client.connected ())
140- {
141- if (mqtt_client.publish (topic.c_str (), payload.c_str (), (bool )sett.mqtt_retain ))
142- {
143- LOG_INFO (F (" MQTT: Published succesfully" ));
144- }
145- else
146- {
147- LOG_ERROR (F (" MQTT: Publish failed" ));
148- }
149- }
150- else
151- {
152- LOG_ERROR (F (" MQTT: Client not connected." ));
153- }
43+ LOG_INFO (F (" MQTT: Published succesfully" ));
44+ return true ;
15445}
15546
15647/* *
@@ -162,13 +53,16 @@ void publish_simple(PubSubClient &mqtt_client, const String &topic, const String
16253 *
16354 * @param mqtt_client клиент MQTT
16455 * @param topic строка с топиком
56+ * @return true пустое сообщение ушло
16557 */
166- void clear_retained (PubSubClient &mqtt_client, const String &topic)
58+ bool clear_retained (PubSubClient &mqtt_client, const String &topic)
16759{
16860 LOG_INFO (F (" MQTT: Remove retain message: " ) << topic);
16961
17062 if (!mqtt_client.publish (topic.c_str (), " " , true ))
17163 {
17264 LOG_ERROR (F (" MQTT: Publish failed" ));
65+ return false ;
17366 }
67+ return true ;
17468}
0 commit comments