mirror of
https://github.com/wled/WLED.git
synced 2025-07-14 14:26:33 +00:00
Hostname unification
- fixes #1242 - fixes empty MQTT topic - fixes missing hostname on change #4586
This commit is contained in:
parent
66869f8341
commit
e2edd38de5
@ -57,10 +57,21 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject id = doc["id"];
|
JsonObject id = doc["id"];
|
||||||
getStringFromJson(cmDNS, id[F("mdns")], 33);
|
getStringFromJson(cmDNS, id[F("mdns")], sizeof(cmDNS));
|
||||||
getStringFromJson(serverDescription, id[F("name")], 33);
|
// fill in unique mDNS name if not set (cmDNS can be empty meaning no mDNS is used)
|
||||||
|
if (strcmp(cmDNS, DEFAULT_MDNS_NAME) == 0) sprintf_P(cmDNS, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
||||||
|
getStringFromJson(serverDescription, id[F("name")], sizeof(serverDescription));
|
||||||
|
if (!fromFS) {
|
||||||
|
char hostname[25];
|
||||||
|
prepareHostname(hostname, sizeof(hostname)-1);
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
WiFi.setHostname(hostname);
|
||||||
|
#else
|
||||||
|
WiFi.hostname(hostname);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#ifndef WLED_DISABLE_ALEXA
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
|
getStringFromJson(alexaInvocationName, id[F("inv")], sizeof(alexaInvocationName));
|
||||||
#endif
|
#endif
|
||||||
CJSON(simplifiedUI, id[F("sui")]);
|
CJSON(simplifiedUI, id[F("sui")]);
|
||||||
|
|
||||||
@ -637,8 +648,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
getStringFromJson(mqttUser, if_mqtt[F("user")], 41);
|
getStringFromJson(mqttUser, if_mqtt[F("user")], 41);
|
||||||
getStringFromJson(mqttPass, if_mqtt["psk"], 65); //normally not present due to security
|
getStringFromJson(mqttPass, if_mqtt["psk"], 65); //normally not present due to security
|
||||||
getStringFromJson(mqttClientID, if_mqtt[F("cid")], 41);
|
getStringFromJson(mqttClientID, if_mqtt[F("cid")], 41);
|
||||||
|
if (mqttClientID[0] == 0) sprintf_P(mqttClientID, PSTR("WLED-%*s"), 6, escapedMac.c_str() + 6);
|
||||||
getStringFromJson(mqttDeviceTopic, if_mqtt[F("topics")][F("device")], MQTT_MAX_TOPIC_LEN+1); // "wled/test"
|
getStringFromJson(mqttDeviceTopic, if_mqtt[F("topics")][F("device")], MQTT_MAX_TOPIC_LEN+1); // "wled/test"
|
||||||
|
if (mqttDeviceTopic[0] == 0) sprintf_P(mqttDeviceTopic, PSTR("wled/%*s"), 6, escapedMac.c_str() + 6);
|
||||||
getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], MQTT_MAX_TOPIC_LEN+1); // ""
|
getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], MQTT_MAX_TOPIC_LEN+1); // ""
|
||||||
CJSON(retainMqttMsg, if_mqtt[F("rtn")]);
|
CJSON(retainMqttMsg, if_mqtt[F("rtn")]);
|
||||||
#endif
|
#endif
|
||||||
|
@ -144,6 +144,7 @@ Static subnet mask:<br>
|
|||||||
function tE() {
|
function tE() {
|
||||||
// keep the hidden input with MAC addresses, only toggle visibility of the list UI
|
// keep the hidden input with MAC addresses, only toggle visibility of the list UI
|
||||||
gId('rlc').style.display = d.Sf.RE.checked ? 'block' : 'none';
|
gId('rlc').style.display = d.Sf.RE.checked ? 'block' : 'none';
|
||||||
|
if (d.Sf.RE.checked) d.Sf.ETH.selectedIndex = 0; // disable Ethernet if ESPNOW is enabled
|
||||||
}
|
}
|
||||||
// reset remotes: initialize empty list (called from xml.cpp)
|
// reset remotes: initialize empty list (called from xml.cpp)
|
||||||
function rstR() {
|
function rstR() {
|
||||||
@ -176,7 +177,9 @@ Static subnet mask:<br>
|
|||||||
rC++;
|
rC++;
|
||||||
gId('+').style.display = gId("rml").childElementCount < 10 ? 'inline' : 'none'; // can't append to list anymore, hide button
|
gId('+').style.display = gId("rml").childElementCount < 10 ? 'inline' : 'none'; // can't append to list anymore, hide button
|
||||||
}
|
}
|
||||||
|
function vI(i) {
|
||||||
|
i.style.color = (i.value.match(/^[a-zA-Z0-9_\-]*$/)) ? 'white' : 'red';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>@import url("style.css");</style>
|
<style>@import url("style.css");</style>
|
||||||
</head>
|
</head>
|
||||||
@ -187,6 +190,9 @@ Static subnet mask:<br>
|
|||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
|
||||||
</div>
|
</div>
|
||||||
<h2>WiFi setup</h2>
|
<h2>WiFi setup</h2>
|
||||||
|
Hostname/mDNS address (empty for no mDNS):<br>
|
||||||
|
http://<input type="text" name="CM" maxlength="32" pattern="[a-zA-Z0-9_\-]*" oninput="vI(this)">.local<br>
|
||||||
|
Client IP: <span class="sip"> Not connected </span><br>
|
||||||
<h3>Connect to existing network</h3>
|
<h3>Connect to existing network</h3>
|
||||||
<button type="button" id="scan" onclick="N()">Scan</button><br>
|
<button type="button" id="scan" onclick="N()">Scan</button><br>
|
||||||
<div id="wifi">
|
<div id="wifi">
|
||||||
@ -198,14 +204,10 @@ Static subnet mask:<br>
|
|||||||
</div>
|
</div>
|
||||||
DNS server address:<br>
|
DNS server address:<br>
|
||||||
<input name="D0" type="number" class="s" min="0" max="255" required>.<input name="D1" type="number" class="s" min="0" max="255" required>.<input name="D2" type="number" class="s" min="0" max="255" required>.<input name="D3" type="number" class="s" min="0" max="255" required><br>
|
<input name="D0" type="number" class="s" min="0" max="255" required>.<input name="D1" type="number" class="s" min="0" max="255" required>.<input name="D2" type="number" class="s" min="0" max="255" required>.<input name="D3" type="number" class="s" min="0" max="255" required><br>
|
||||||
<br>
|
|
||||||
mDNS address (leave empty for no mDNS):<br>
|
|
||||||
http:// <input type="text" name="CM" maxlength="32"> .local<br>
|
|
||||||
Client IP: <span class="sip"> Not connected </span> <br>
|
|
||||||
<h3>Configure Access Point</h3>
|
<h3>Configure Access Point</h3>
|
||||||
AP SSID (leave empty for no AP):<br> <input type="text" name="AS" maxlength="32"><br>
|
AP SSID (empty for no AP):<br> <input type="text" name="AS" maxlength="32" pattern="[a-zA-Z0-9_\-]*" oninput="vI(this)"><br>
|
||||||
Hide AP name: <input type="checkbox" name="AH"><br>
|
Hide AP name: <input type="checkbox" name="AH"><br>
|
||||||
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63" pattern="(.{8,63})|()" title="Empty or min. 8 characters"><br>
|
AP password (empty for open):<br> <input type="password" name="AP" maxlength="63" pattern="(.{8,63})|()" title="Empty or min. 8 characters"><br>
|
||||||
Access Point WiFi channel: <input name="AC" type="number" class="xs" min="1" max="13" required><br>
|
Access Point WiFi channel: <input name="AC" type="number" class="xs" min="1" max="13" required><br>
|
||||||
AP opens:
|
AP opens:
|
||||||
<select name="AB">
|
<select name="AB">
|
||||||
@ -256,7 +258,7 @@ Static subnet mask:<br>
|
|||||||
|
|
||||||
<div id="ethd">
|
<div id="ethd">
|
||||||
<h3>Ethernet Type</h3>
|
<h3>Ethernet Type</h3>
|
||||||
<select name="ETH">
|
<select name="ETH" onchange="if(this.selectedIndex!=0)d.Sf.RE.checked=false;">
|
||||||
<option value="0">None</option>
|
<option value="0">None</option>
|
||||||
<option value="9">ABC! WLED V43 & compatible</option>
|
<option value="9">ABC! WLED V43 & compatible</option>
|
||||||
<option value="2">ESP32-POE</option>
|
<option value="2">ESP32-POE</option>
|
||||||
@ -270,7 +272,8 @@ Static subnet mask:<br>
|
|||||||
<option value="5">TwilightLord-ESP32</option>
|
<option value="5">TwilightLord-ESP32</option>
|
||||||
<option value="3">WESP32</option>
|
<option value="3">WESP32</option>
|
||||||
<option value="1">WT32-ETH01</option>
|
<option value="1">WT32-ETH01</option>
|
||||||
</select><br><br>
|
</select><br>
|
||||||
|
<i class="warn">ESP-NOW is incompatible with Ethernet.</i>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
|
||||||
|
@ -505,7 +505,7 @@ size_t printSetFormValue(Print& settingsScript, const char* key, int val);
|
|||||||
size_t printSetFormValue(Print& settingsScript, const char* key, const char* val);
|
size_t printSetFormValue(Print& settingsScript, const char* key, const char* val);
|
||||||
size_t printSetFormIndex(Print& settingsScript, const char* key, int index);
|
size_t printSetFormIndex(Print& settingsScript, const char* key, int index);
|
||||||
size_t printSetClassElementHTML(Print& settingsScript, const char* key, const int index, const char* val);
|
size_t printSetClassElementHTML(Print& settingsScript, const char* key, const int index, const char* val);
|
||||||
void prepareHostname(char* hostname);
|
void prepareHostname(char* hostname, size_t maxLen = 32);
|
||||||
[[gnu::pure]] bool isAsterisksOnly(const char* str, byte maxLen);
|
[[gnu::pure]] bool isAsterisksOnly(const char* str, byte maxLen);
|
||||||
bool requestJSONBufferLock(uint8_t moduleID=255);
|
bool requestJSONBufferLock(uint8_t moduleID=255);
|
||||||
void releaseJSONBufferLock();
|
void releaseJSONBufferLock();
|
||||||
|
@ -386,7 +386,7 @@ void WiFiEvent(WiFiEvent_t event)
|
|||||||
case ARDUINO_EVENT_WIFI_AP_STOP:
|
case ARDUINO_EVENT_WIFI_AP_STOP:
|
||||||
DEBUG_PRINTLN(F("WiFi-E: AP Stopped"));
|
DEBUG_PRINTLN(F("WiFi-E: AP Stopped"));
|
||||||
break;
|
break;
|
||||||
#if defined(WLED_USE_ETHERNET)
|
#ifdef WLED_USE_ETHERNET
|
||||||
case ARDUINO_EVENT_ETH_START:
|
case ARDUINO_EVENT_ETH_START:
|
||||||
DEBUG_PRINTLN(F("ETH-E: Started"));
|
DEBUG_PRINTLN(F("ETH-E: Started"));
|
||||||
break;
|
break;
|
||||||
@ -402,8 +402,8 @@ void WiFiEvent(WiFiEvent_t event)
|
|||||||
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||||
}
|
}
|
||||||
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
|
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
|
||||||
char hostname[64];
|
char hostname[33];
|
||||||
prepareHostname(hostname);
|
prepareHostname(hostname, sizeof(hostname)-1);
|
||||||
ETH.setHostname(hostname);
|
ETH.setHostname(hostname);
|
||||||
showWelcomePage = false;
|
showWelcomePage = false;
|
||||||
break;
|
break;
|
||||||
|
@ -63,16 +63,23 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
dnsAddress = IPAddress(request->arg(F("D0")).toInt(),request->arg(F("D1")).toInt(),request->arg(F("D2")).toInt(),request->arg(F("D3")).toInt());
|
dnsAddress = IPAddress(request->arg(F("D0")).toInt(),request->arg(F("D1")).toInt(),request->arg(F("D2")).toInt(),request->arg(F("D3")).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(cmDNS, request->arg(F("CM")).c_str(), 33);
|
strlcpy(cmDNS, request->arg(F("CM")).c_str(), sizeof(cmDNS));
|
||||||
|
char hostname[25];
|
||||||
|
prepareHostname(hostname, sizeof(hostname)-1);
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
WiFi.setHostname(hostname);
|
||||||
|
#else
|
||||||
|
WiFi.hostname(hostname);
|
||||||
|
#endif
|
||||||
|
|
||||||
apBehavior = request->arg(F("AB")).toInt();
|
apBehavior = request->arg(F("AB")).toInt();
|
||||||
char oldSSID[33]; strcpy(oldSSID, apSSID);
|
char oldSSID[33]; strcpy(oldSSID, apSSID);
|
||||||
strlcpy(apSSID, request->arg(F("AS")).c_str(), 33);
|
strlcpy(apSSID, request->arg(F("AS")).c_str(), sizeof(apSSID));
|
||||||
if (!strcmp(oldSSID, apSSID) && apActive) forceReconnect = true;
|
if (!strcmp(oldSSID, apSSID) && apActive) forceReconnect = true;
|
||||||
apHide = request->hasArg(F("AH"));
|
apHide = request->hasArg(F("AH"));
|
||||||
int passlen = request->arg(F("AP")).length();
|
int passlen = request->arg(F("AP")).length();
|
||||||
if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg(F("AP")).c_str(), 65))) {
|
if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg(F("AP")).c_str(), sizeof(apPass)))) {
|
||||||
strlcpy(apPass, request->arg(F("AP")).c_str(), 65);
|
strlcpy(apPass, request->arg(F("AP")).c_str(), sizeof(apPass));
|
||||||
forceReconnect = true;
|
forceReconnect = true;
|
||||||
}
|
}
|
||||||
int t = request->arg(F("AC")).toInt();
|
int t = request->arg(F("AC")).toInt();
|
||||||
@ -368,6 +375,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (subPage == SUBPAGE_UI)
|
if (subPage == SUBPAGE_UI)
|
||||||
{
|
{
|
||||||
strlcpy(serverDescription, request->arg(F("DS")).c_str(), 33);
|
strlcpy(serverDescription, request->arg(F("DS")).c_str(), 33);
|
||||||
|
char hostname[25];
|
||||||
|
prepareHostname(hostname, sizeof(hostname)-1);
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
WiFi.setHostname(hostname);
|
||||||
|
#else
|
||||||
|
WiFi.hostname(hostname);
|
||||||
|
#endif
|
||||||
//syncToggleReceive = request->hasArg(F("ST"));
|
//syncToggleReceive = request->hasArg(F("ST"));
|
||||||
simplifiedUI = request->hasArg(F("SU"));
|
simplifiedUI = request->hasArg(F("SU"));
|
||||||
DEBUG_PRINTLN(F("Enumerating ledmaps"));
|
DEBUG_PRINTLN(F("Enumerating ledmaps"));
|
||||||
|
@ -114,28 +114,30 @@ size_t printSetClassElementHTML(Print& settingsScript, const char* key, const in
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// prepare a unique hostname based on the last 6 digits of the MAC address
|
||||||
void prepareHostname(char* hostname)
|
// if no mDNS name or serverDescription is set, otherwise use cmDNS or serverDescription
|
||||||
|
// the hostname will be at most 24 characters long, starting with "wled-"
|
||||||
|
// and containing only alphanumeric characters and hyphens
|
||||||
|
// the hostname will not end with a hyphen and will be null-terminated
|
||||||
|
void prepareHostname(char* hostname, size_t maxLen)
|
||||||
{
|
{
|
||||||
|
// create a unique hostname based on the last 6 digits of the MAC address if no mDNS name or serverDescription is set
|
||||||
sprintf_P(hostname, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
sprintf_P(hostname, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6);
|
||||||
const char *pC = serverDescription;
|
const char *pC = cmDNS; // use cmDNS as hostname if set
|
||||||
unsigned pos = 5; // keep "wled-"
|
if (strlen(pC) == 0) pC = serverDescription; // else use serverDescription
|
||||||
while (*pC && pos < 24) { // while !null and not over length
|
unsigned pos = 5; // keep "wled-" from unique name
|
||||||
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
|
while (*pC && pos < maxLen) { // while !null and not over length
|
||||||
hostname[pos] = *pC;
|
if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname
|
||||||
pos++;
|
hostname[pos++] = *pC;
|
||||||
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
|
} else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') {
|
||||||
hostname[pos] = '-';
|
hostname[pos++] = '-';
|
||||||
pos++;
|
|
||||||
}
|
}
|
||||||
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
|
// else do nothing - no leading hyphens and do not include hyphens for all other characters.
|
||||||
pC++;
|
pC++;
|
||||||
}
|
}
|
||||||
//last character must not be hyphen
|
// last character must not be hyphen
|
||||||
if (pos > 5) {
|
while (pos > 4 && hostname[pos-1] == '-') pos--;
|
||||||
while (pos > 4 && hostname[pos -1] == '-') pos--;
|
hostname[pos] = '\0'; // terminate string (leave at least "wled")
|
||||||
hostname[pos] = '\0'; // terminate string (leave at least "wled")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user