Skip to content

Commit 93e011d

Browse files
authored
Merge pull request #4769 from wled/fix-4671
Add mDNS support for MQTT server
2 parents 374d906 + ecc3eae commit 93e011d

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

wled00/mqtt.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
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"
1419
static 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,8 +55,7 @@ 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"));
58+
snprintf_P(subuf, sizeof(subuf)-1, sTopicFormat, MQTT_MAX_TOPIC_LEN, mqttDeviceTopic, "status");
5959
mqtt->publish(subuf, 0, true, "online"); // retain message for a LWT
6060
#endif
6161

@@ -136,7 +136,7 @@ static void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProp
136136
}
137137

138138
// Print adapter for flat buffers
139-
namespace {
139+
namespace {
140140
class 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,14 +213,26 @@ bool initMqtt()
213213
{
214214
mqtt->setServer(mqttIP, mqttPort);
215215
} 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);
217230
}
218231
mqtt->setClientId(mqttClientID);
219232
if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
220233

221234
#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");
224236
mqtt->setWill(mqttStatusTopic, 0, true, "offline"); // LWT message
225237
#endif
226238
mqtt->setKeepAlive(MQTT_KEEP_ALIVE_TIME);

0 commit comments

Comments
 (0)