11
11
#warning "MQTT topics length > 32 is not recommended for compatibility with usermods!"
12
12
#endif
13
13
14
+ static const char * sTopicFormat PROGMEM = " %.*s/%s" ;
15
+
16
+ // parse payload for brightness, ON/OFF or toggle
17
+ // briLast is used to remember last brightness value in case of ON/OFF or toggle
18
+ // bri is set to 0 if payload is "0" or "OFF" or "false"
14
19
static void parseMQTTBriPayload (char * payload)
15
20
{
16
21
if (strstr (payload, " ON" ) || strstr (payload, " on" ) || strstr (payload, " true" )) {bri = briLast; stateUpdated (CALL_MODE_DIRECT_CHANGE);}
@@ -30,22 +35,18 @@ static void onMqttConnect(bool sessionPresent)
30
35
char subuf[MQTT_MAX_TOPIC_LEN + 9 ];
31
36
32
37
if (mqttDeviceTopic[0 ] != 0 ) {
33
- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
34
- mqtt->subscribe (subuf, 0 );
35
- strcat_P (subuf, PSTR (" /col" ));
38
+ mqtt->subscribe (mqttDeviceTopic, 0 );
39
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " col" );
36
40
mqtt->subscribe (subuf, 0 );
37
- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
38
- strcat_P (subuf, PSTR (" /api" ));
41
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " api" );
39
42
mqtt->subscribe (subuf, 0 );
40
43
}
41
44
42
45
if (mqttGroupTopic[0 ] != 0 ) {
43
- strlcpy (subuf, mqttGroupTopic, MQTT_MAX_TOPIC_LEN + 1 );
46
+ mqtt->subscribe (mqttGroupTopic, 0 );
47
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttGroupTopic, " col" );
44
48
mqtt->subscribe (subuf, 0 );
45
- strcat_P (subuf, PSTR (" /col" ));
46
- mqtt->subscribe (subuf, 0 );
47
- strlcpy (subuf, mqttGroupTopic, MQTT_MAX_TOPIC_LEN + 1 );
48
- strcat_P (subuf, PSTR (" /api" ));
49
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttGroupTopic, " api" );
49
50
mqtt->subscribe (subuf, 0 );
50
51
}
51
52
@@ -54,8 +55,7 @@ static void onMqttConnect(bool sessionPresent)
54
55
DEBUG_PRINTLN (F (" MQTT ready" ));
55
56
56
57
#ifndef USERMOD_SMARTNEST
57
- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
58
- strcat_P (subuf, PSTR (" /status" ));
58
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " status" );
59
59
mqtt->publish (subuf, 0 , true , " online" ); // retain message for a LWT
60
60
#endif
61
61
@@ -136,7 +136,7 @@ static void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProp
136
136
}
137
137
138
138
// Print adapter for flat buffers
139
- namespace {
139
+ namespace {
140
140
class bufferPrint : public Print {
141
141
char * _buf;
142
142
size_t _size, _offset;
@@ -172,21 +172,21 @@ void publishMqtt()
172
172
char subuf[MQTT_MAX_TOPIC_LEN + 16 ];
173
173
174
174
sprintf_P (s, PSTR (" %u" ), bri);
175
- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
176
- strcat_P (subuf, PSTR (" /g" ));
175
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " g" );
177
176
mqtt->publish (subuf, 0 , retainMqttMsg, s); // optionally retain message (#2263)
178
177
179
178
sprintf_P (s, PSTR (" #%06X" ), (colPri[3 ] << 24 ) | (colPri[0 ] << 16 ) | (colPri[1 ] << 8 ) | (colPri[2 ]));
180
- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
181
- strcat_P (subuf, PSTR (" /c" ));
179
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " c" );
182
180
mqtt->publish (subuf, 0 , retainMqttMsg, s); // optionally retain message (#2263)
183
181
182
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " status" );
183
+ mqtt->publish (subuf, 0 , true , " online" ); // retain message for a LWT
184
+
184
185
// TODO: use a DynamicBufferList. Requires a list-read-capable MQTT client API.
185
186
DynamicBuffer buf (1024 );
186
187
bufferPrint pbuf (buf.data (), buf.size ());
187
188
XML_response (pbuf);
188
- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
189
- strcat_P (subuf, PSTR (" /v" ));
189
+ snprintf_P (subuf, sizeof (subuf)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " v" );
190
190
mqtt->publish (subuf, 0 , retainMqttMsg, buf.data (), pbuf.size ()); // optionally retain message (#2263)
191
191
#endif
192
192
}
@@ -213,14 +213,26 @@ bool initMqtt()
213
213
{
214
214
mqtt->setServer (mqttIP, mqttPort);
215
215
} else {
216
- mqtt->setServer (mqttServer, mqttPort);
216
+ #ifdef ARDUINO_ARCH_ESP32
217
+ String mqttMDNS = mqttServer;
218
+ mqttMDNS.toLowerCase (); // make sure we have a lowercase hostname
219
+ int pos = mqttMDNS.indexOf (F (" .local" ));
220
+ if (pos > 0 ) mqttMDNS.remove (pos); // remove .local domain if present (and anything following it)
221
+ if (strlen (cmDNS) > 0 && mqttMDNS.length () > 0 && mqttMDNS.indexOf (' .' ) < 0 ) { // if mDNS is enabled and server does not have domain
222
+ mqttIP = MDNS.queryHost (mqttMDNS.c_str ());
223
+ if (mqttIP != IPAddress ()) // if MDNS resolved the hostname
224
+ mqtt->setServer (mqttIP, mqttPort);
225
+ else
226
+ mqtt->setServer (mqttServer, mqttPort);
227
+ } else
228
+ #endif
229
+ mqtt->setServer (mqttServer, mqttPort);
217
230
}
218
231
mqtt->setClientId (mqttClientID);
219
232
if (mqttUser[0 ] && mqttPass[0 ]) mqtt->setCredentials (mqttUser, mqttPass);
220
233
221
234
#ifndef USERMOD_SMARTNEST
222
- strlcpy (mqttStatusTopic, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
223
- strcat_P (mqttStatusTopic, PSTR (" /status" ));
235
+ snprintf_P (mqttStatusTopic, sizeof (mqttStatusTopic)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " status" );
224
236
mqtt->setWill (mqttStatusTopic, 0 , true , " offline" ); // LWT message
225
237
#endif
226
238
mqtt->setKeepAlive (MQTT_KEEP_ALIVE_TIME);
0 commit comments