1111#warning "MQTT topics length > 32 is not recommended for compatibility with usermods!"
1212#endif
1313
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"
1419static void parseMQTTBriPayload (char * payload)
1520{
1621 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)
3035 char subuf[MQTT_MAX_TOPIC_LEN + 9 ];
3136
3237 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" );
3640 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" );
3942 mqtt->subscribe (subuf, 0 );
4043 }
4144
4245 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" );
4448 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" );
4950 mqtt->subscribe (subuf, 0 );
5051 }
5152
@@ -54,9 +55,8 @@ static void onMqttConnect(bool sessionPresent)
5455 DEBUG_PRINTLN (F (" MQTT ready" ));
5556
5657#ifndef USERMOD_SMARTNEST
57- strlcpy (subuf, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
58- strcat_P (subuf, PSTR (" /status" ));
59- mqtt->publish (subuf, 0 , true , " online" ); // retain message for a LWT
58+ snprintf_P (mqttStatusTopic, sizeof (mqttStatusTopic)-1 , sTopicFormat , MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, " status" );
59+ mqtt->setWill (mqttStatusTopic, 0 , true , " offline" ); // LWT message
6060#endif
6161
6262 publishMqtt ();
@@ -136,7 +136,7 @@ static void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProp
136136}
137137
138138// Print adapter for flat buffers
139- namespace {
139+ namespace {
140140class bufferPrint : public Print {
141141 char * _buf;
142142 size_t _size, _offset;
@@ -172,21 +172,21 @@ void publishMqtt()
172172 char subuf[MQTT_MAX_TOPIC_LEN + 16 ];
173173
174174 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" );
177176 mqtt->publish (subuf, 0 , retainMqttMsg, s); // optionally retain message (#2263)
178177
179178 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" );
182180 mqtt->publish (subuf, 0 , retainMqttMsg, s); // optionally retain message (#2263)
183181
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+
184185 // TODO: use a DynamicBufferList. Requires a list-read-capable MQTT client API.
185186 DynamicBuffer buf (1024 );
186187 bufferPrint pbuf (buf.data (), buf.size ());
187188 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" );
190190 mqtt->publish (subuf, 0 , retainMqttMsg, buf.data (), pbuf.size ()); // optionally retain message (#2263)
191191 #endif
192192}
@@ -213,16 +213,20 @@ bool initMqtt()
213213 {
214214 mqtt->setServer (mqttIP, mqttPort);
215215 } else {
216- mqtt->setServer (mqttServer, mqttPort);
216+ #ifdef ARDUINO_ARCH_ESP32
217+ if (strlen (cmDNS) > 0 && strchr (mqttServer, ' .' ) == nullptr ) { // if mDNS is enabled and server does not have domain
218+ mqttIP = MDNS.queryHost (mqttServer);
219+ if (mqttIP != IPAddress ()) // if MDNS resolved the hostname
220+ mqtt->setServer (mqttIP, mqttPort);
221+ else
222+ mqtt->setServer (mqttServer, mqttPort);
223+ } else
224+ #endif
225+ mqtt->setServer (mqttServer, mqttPort);
217226 }
218227 mqtt->setClientId (mqttClientID);
219228 if (mqttUser[0 ] && mqttPass[0 ]) mqtt->setCredentials (mqttUser, mqttPass);
220229
221- #ifndef USERMOD_SMARTNEST
222- strlcpy (mqttStatusTopic, mqttDeviceTopic, MQTT_MAX_TOPIC_LEN + 1 );
223- strcat_P (mqttStatusTopic, PSTR (" /status" ));
224- mqtt->setWill (mqttStatusTopic, 0 , true , " offline" ); // LWT message
225- #endif
226230 mqtt->setKeepAlive (MQTT_KEEP_ALIVE_TIME);
227231 mqtt->connect ();
228232 return true ;
0 commit comments