Added MQTT authentication support

This commit is contained in:
Timothy Brown 2019-08-17 06:27:06 -04:00
parent f0f02c4ea6
commit c6d8b63e54
9 changed files with 178 additions and 149 deletions

View File

@ -57,7 +57,7 @@ arduino_core_2_4_1 = espressif8266@1.7.3
arduino_core_2_4_2 = espressif8266@1.8.0
arduino_core_2_5_0 = espressif8266@2.0.4
arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#feature/stage
platform = ${common:esp8266.arduino_core_2_4_2}
platform = ${common:esp8266.arduino_core_2_5_0}
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
-Wl,-Teagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs
@ -159,5 +159,4 @@ build_flags =
lib_deps =
${common.lib_deps_external}
lib_ignore =
IRremoteESP8266
IRremoteESP8266

Binary file not shown.

View File

@ -1,7 +1,7 @@
/*
* Settings html
*/
//common CSS of settings pages
const char PAGE_settingsCss[] PROGMEM = R"=====(body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:4em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}td{padding:2px;}</style>)=====";
@ -253,6 +253,9 @@ Device Auth token: <input name="BK" maxlength="33"><br>
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
<h3>MQTT</h3>
Broker: <input name="MS" maxlength="32"><br>
Username: <input name="MQTTUSER" maxlength="32"><br>
Password: <input type="password" input name="MQTTPASS" maxlength="32"><br>
Client ID: <input name="MQTTCID" maxlength="32"><br>
Device Topic: <input name="MD" maxlength="32"><br>
Group Topic: <input name="MG" maxlength="32"><br>
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
@ -289,7 +292,7 @@ function Wd(){a=[0,0,0,0,0,0,0,0];for(i=0;i<8;i++){m=1;for(j=0;j<8;j++){a[i]+=gI
<h2>Time setup</h2>
Get time from NTP server: <input type="checkbox" name="NT"><br>
Use 24h format: <input type="checkbox" name="CF"><br>
Time zone:
Time zone:
<select name="TZ">
<option value="0" selected>GMT(UTC)</option>
<option value="1">GMT/BST</option>

View File

@ -3,7 +3,7 @@
*/
/*
* @title WLED project sketch
* @version 0.8.4
* @version 0.8.5-dev #mqttauth @TimothyBrown
* @author Christian Schwinne
*/
@ -129,17 +129,17 @@ IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP
IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks
//LED CONFIG
uint16_t ledCount = 30; //overcurrent prevented by ABL
uint16_t ledCount = 30; //overcurrent prevented by ABL
bool useRGBW = false; //SK6812 strips can contain an extra White channel
bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
bool turnOnAtBoot = true; //turn on LEDs at power-up
byte bootPreset = 0; //save preset to load after power-up
byte colS[]{255, 159, 0, 0}; //default RGB(W) color
byte colSecS[]{0, 0, 0, 0}; //default RGB(W) secondary color
byte briS = 127; //default brightness
byte effectDefault = 0;
byte effectDefault = 0;
byte effectSpeedDefault = 75;
byte effectIntensityDefault = 128; //intensity is supported on some effects as an additional parameter (e.g. for blink you can change the duty cycle)
byte effectPaletteDefault = 0; //palette is supported on the FastLED effects, otherwise it has no effect
@ -204,6 +204,9 @@ bool e131Multicast = false;
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
char mqttUser[33] = ""; //optional: username for MQTT auth
char mqttPass[33] = ""; //optional: password for MQTT auth
char mqttClientID[33] = ""; //override the client ID
bool huePollingEnabled = false; //poll hue bridge for light state
uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response
@ -239,7 +242,7 @@ byte countdownMin = 0, countdownSec = 0;
byte macroBoot = 0; //macro loaded after startup
byte macroNl = 0; //after nightlight delay over
byte macroCountdown = 0;
byte macroCountdown = 0;
byte macroAlexaOn = 0, macroAlexaOff = 0;
byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0;
@ -483,7 +486,7 @@ bool oappend(char* txt)
//append new number to temp buffer efficiently
bool oappendi(int i)
{
char s[11];
char s[11];
sprintf(s,"%ld", i);
return oappend(s);
}
@ -502,18 +505,18 @@ void loop() {
handleNotifications();
handleTransitions();
userLoop();
yield();
handleIO();
handleIR();
handleNetworkTime();
if (!onlyAP) handleAlexa();
handleOverlays();
yield();
if (doReboot) reset();
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
{
if (dnsActive) dnsServer.processNextRequest();
@ -536,7 +539,7 @@ void loop() {
yield();
if (!offMode) strip.service();
}
//DEBUG serial logging
#ifdef WLED_DEBUG
if (millis() - debugTime > 9999)
@ -554,7 +557,7 @@ void loop() {
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
debugTime = millis();
debugTime = millis();
}
#endif
}

View File

@ -6,7 +6,7 @@
#define EEPSIZE 2560
//eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 10
#define EEPVER 11
//0 -> old version, default
//1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up
@ -18,6 +18,7 @@
//8 -> 0.8.0-a and up
//9 -> 0.8.0
//10-> 0.8.2
//11-> 0.8.5-dev #mqttauth @TimothyBrown
/*
@ -64,7 +65,7 @@ void saveSettingsToEEPROM()
clearEEPROM();
EEPROM.write(233, 233);
}
writeStringToEEPROM( 0, clientSSID, 32);
writeStringToEEPROM( 32, clientPass, 64);
writeStringToEEPROM( 96, cmDNS, 32);
@ -81,50 +82,50 @@ void saveSettingsToEEPROM()
EEPROM.write(231, notifyTwice);
EEPROM.write(232, buttonEnabled);
//233 reserved for first boot flag
for (int i = 0; i<4; i++) //ip addresses
{
EEPROM.write(234+i, staticIP[i]);
EEPROM.write(238+i, staticGateway[i]);
EEPROM.write(242+i, staticSubnet[i]);
}
EEPROM.write(246, colS[0]);
EEPROM.write(247, colS[1]);
EEPROM.write(248, colS[2]);
EEPROM.write(249, briS);
EEPROM.write(250, receiveNotificationBrightness);
EEPROM.write(251, fadeTransition);
EEPROM.write(252, strip.reverseMode);
EEPROM.write(253, transitionDelayDefault & 0xFF);
EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF);
EEPROM.write(255, briMultiplier);
//255,250,231,230,226 notifier bytes
writeStringToEEPROM(256, otaPass, 32);
EEPROM.write(288, nightlightTargetBri);
EEPROM.write(289, otaLock);
EEPROM.write(290, udpPort & 0xFF);
EEPROM.write(291, (udpPort >> 8) & 0xFF);
writeStringToEEPROM(292, serverDescription, 32);
EEPROM.write(324, effectDefault);
EEPROM.write(325, effectSpeedDefault);
EEPROM.write(326, effectIntensityDefault);
EEPROM.write(327, ntpEnabled);
EEPROM.write(328, currentTimezone);
EEPROM.write(329, useAMPM);
EEPROM.write(330, strip.gammaCorrectBri);
EEPROM.write(331, strip.gammaCorrectCol);
EEPROM.write(332, overlayDefault);
EEPROM.write(333, alexaEnabled);
writeStringToEEPROM(334, alexaInvocationName, 32);
EEPROM.write(366, notifyAlexa);
EEPROM.write(367, (arlsOffset>=0));
EEPROM.write(368, abs(arlsOffset));
EEPROM.write(369, turnOnAtBoot);
@ -135,9 +136,9 @@ void saveSettingsToEEPROM()
EEPROM.write(374, strip.paletteFade);
EEPROM.write(375, apWaitTimeSecs);
EEPROM.write(376, recoveryAPDisabled);
EEPROM.write(377, EEPVER); //eeprom was updated to latest
EEPROM.write(378, colSecS[0]);
EEPROM.write(379, colSecS[1]);
EEPROM.write(380, colSecS[2]);
@ -154,7 +155,7 @@ void saveSettingsToEEPROM()
EEPROM.write(391, receiveNotificationColor);
EEPROM.write(392, receiveNotificationEffects);
EEPROM.write(393, wifiLock);
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
@ -193,7 +194,7 @@ void saveSettingsToEEPROM()
EEPROM.write(2152, analogClock12pixel);
EEPROM.write(2153, analogClock5MinuteMarks);
EEPROM.write(2154, analogClockSecondsTrail);
EEPROM.write(2155, countdownMode);
EEPROM.write(2156, countdownYear);
EEPROM.write(2157, countdownMonth);
@ -206,7 +207,7 @@ void saveSettingsToEEPROM()
writeStringToEEPROM(2165, cronixieDisplay, 6);
EEPROM.write(2171, cronixieBacklight);
setCronixie();
EEPROM.write(2175, macroBoot);
EEPROM.write(2176, macroAlexaOn);
EEPROM.write(2177, macroAlexaOff);
@ -253,10 +254,13 @@ void saveSettingsToEEPROM()
EEPROM.write(2290 + i, timerMacro[i] );
}
writeStringToEEPROM(2300, mqttServer, 32);
writeStringToEEPROM(2300, mqttServer, 32);
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
writeStringToEEPROM(2366, mqttGroupTopic, 32);
writeStringToEEPROM(2366, mqttGroupTopic, 32);
writeStringToEEPROM(2399, mqttUser, 32);
writeStringToEEPROM(2432, mqttPass, 32);
writeStringToEEPROM(2465, mqttClientID, 32);
EEPROM.commit();
}
@ -274,7 +278,7 @@ void loadSettingsFromEEPROM(bool first)
return;
}
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
readStringFromEEPROM( 0, clientSSID, 32);
readStringFromEEPROM( 32, clientPass, 64);
@ -287,17 +291,17 @@ void loadSettingsFromEEPROM(bool first)
nightlightFade = EEPROM.read(225);
notifyDirectDefault = EEPROM.read(226);
notifyDirect = notifyDirectDefault;
apChannel = EEPROM.read(227);
if (apChannel > 13 || apChannel < 1) apChannel = 1;
apHide = EEPROM.read(228);
if (apHide > 1) apHide = 1;
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 30;
notifyButton = EEPROM.read(230);
notifyTwice = EEPROM.read(231);
buttonEnabled = EEPROM.read(232);
staticIP[0] = EEPROM.read(234);
staticIP[1] = EEPROM.read(235);
staticIP[2] = EEPROM.read(236);
@ -310,7 +314,7 @@ void loadSettingsFromEEPROM(bool first)
staticSubnet[1] = EEPROM.read(243);
staticSubnet[2] = EEPROM.read(244);
staticSubnet[3] = EEPROM.read(245);
colS[0] = EEPROM.read(246); col[0] = colS[0];
colS[1] = EEPROM.read(247); col[1] = colS[1];
colS[2] = EEPROM.read(248); col[2] = colS[2];
@ -327,13 +331,13 @@ void loadSettingsFromEEPROM(bool first)
briMultiplier = EEPROM.read(255);
readStringFromEEPROM(256, otaPass, 32);
nightlightTargetBri = EEPROM.read(288);
otaLock = EEPROM.read(289);
udpPort = EEPROM.read(290) + ((EEPROM.read(291) << 8) & 0xFF00);
readStringFromEEPROM(292, serverDescription, 32);
effectDefault = EEPROM.read(324); effectCurrent = effectDefault;
effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault;
ntpEnabled = EEPROM.read(327);
@ -343,11 +347,11 @@ void loadSettingsFromEEPROM(bool first)
strip.gammaCorrectCol = EEPROM.read(331);
overlayDefault = EEPROM.read(332);
if (lastEEPROMversion < 8 && overlayDefault > 0) overlayDefault--; //overlay mode 1 (solid) was removed
alexaEnabled = EEPROM.read(333);
readStringFromEEPROM(334, alexaInvocationName, 32);
notifyAlexa = EEPROM.read(366);
arlsOffset = EEPROM.read(368);
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
@ -358,7 +362,7 @@ void loadSettingsFromEEPROM(bool first)
effectPaletteDefault = EEPROM.read(373); effectPalette = effectPaletteDefault;
//374 - strip.paletteFade
if (lastEEPROMversion > 0) {
if (lastEEPROMversion > 0) {
apWaitTimeSecs = EEPROM.read(375);
recoveryAPDisabled = EEPROM.read(376);
}
@ -370,7 +374,7 @@ void loadSettingsFromEEPROM(bool first)
}
}
if (lastEEPROMversion > 3) {
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
aOtaEnabled = EEPROM.read(390);
receiveNotificationColor = EEPROM.read(391);
receiveNotificationEffects = EEPROM.read(392);
@ -391,7 +395,7 @@ void loadSettingsFromEEPROM(bool first)
}
readStringFromEEPROM(2054, hueApiKey, 46);
huePollIntervalMs = EEPROM.read(2100) + ((EEPROM.read(2101) << 8) & 0xFF00);
notifyHue = EEPROM.read(2102);
hueApplyOnOff = EEPROM.read(2103);
@ -416,7 +420,7 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(2165, cronixieDisplay, 6);
cronixieBacklight = EEPROM.read(2171);
macroBoot = EEPROM.read(2175);
macroAlexaOn = EEPROM.read(2176);
macroAlexaOff = EEPROM.read(2177);
@ -454,9 +458,9 @@ void loadSettingsFromEEPROM(bool first)
if (lastEEPROMversion > 8)
{
readStringFromEEPROM(2300, mqttServer, 32);
readStringFromEEPROM(2300, mqttServer, 32);
readStringFromEEPROM(2333, mqttDeviceTopic, 32);
readStringFromEEPROM(2366, mqttGroupTopic, 32);
readStringFromEEPROM(2366, mqttGroupTopic, 32);
}
if (lastEEPROMversion > 9)
@ -470,16 +474,23 @@ void loadSettingsFromEEPROM(bool first)
} else {
strip.ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
}
if (lastEEPROMversion > 10)
{
readStringFromEEPROM(2399, mqttUser, 32);
readStringFromEEPROM(2432, mqttPass, 32);
readStringFromEEPROM(2465, mqttClientID, 32);
}
receiveDirect = !EEPROM.read(2200);
notifyMacro = EEPROM.read(2201);
uiConfiguration = EEPROM.read(2202);
#ifdef WLED_DISABLE_MOBILE_UI
uiConfiguration = 1;
//force default UI since mobile is unavailable
#endif
autoRGBtoRGBW = EEPROM.read(2203);
skipFirstLed = EEPROM.read(2204);
@ -493,7 +504,7 @@ void loadSettingsFromEEPROM(bool first)
presetApplyCol = EEPROM.read(2211);
presetApplyFx = EEPROM.read(2212);
}
bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393);
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
@ -513,10 +524,10 @@ void loadSettingsFromEEPROM(bool first)
//1024-2047 reserved
readStringFromEEPROM(2220, blynkApiKey, 35);
//user MOD memory
//2944 - 3071 reserved
useHSB = useHSBDefault;
overlayCurrent = overlayDefault;
@ -570,7 +581,7 @@ void savePreset(byte index)
}
EEPROM.write(i+10, effectCurrent);
EEPROM.write(i+11, effectSpeed);
EEPROM.write(i+16, effectIntensity);
EEPROM.write(i+17, effectPalette);
EEPROM.commit();
@ -597,7 +608,7 @@ void applyMacro(byte index)
if (!notifyMacro) mc += "&NN";
String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop
/*
* NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again.
* NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again.
* To prevent that, but also disable calling macros within macros, comment the next line out.
*/
forbidden = forbidden + index;

View File

@ -7,12 +7,12 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
{
char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed
obuf = (dest == nullptr)? sbuf:dest;
olen = 0;
oappend("<?xml version=\"1.0\" ?><vs><ac>");
oappendi((nightlightActive && nightlightFade) ? briT : bri);
oappend("</ac>");
for (int i = 0; i < 3; i++)
{
oappend("<cl>");
@ -77,7 +77,7 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
} else {
oappend(serverDescription);
}
oappend("</ds>");
if (includeTheme)
{
@ -107,7 +107,7 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
void sappend(char stype, char* key, int val)
{
char ds[] = "d.Sf.";
switch(stype)
{
case 'c': //checkbox
@ -165,7 +165,7 @@ void getSettingsJS(byte subPage, char* dest)
DEBUG_PRINTLN(subPage);
obuf = dest;
olen = 0;
if (subPage <1 || subPage >6) return;
if (subPage == 1) {
@ -174,7 +174,7 @@ void getSettingsJS(byte subPage, char* dest)
byte l = strlen(clientPass);
char fpass[l+1]; //fill password field with ***
fpass[l] = 0;
memset(fpass,'*',l);
memset(fpass,'*',l);
sappends('s',"CP",fpass);
char k[3]; k[2] = 0; //IP addresses
@ -190,13 +190,13 @@ void getSettingsJS(byte subPage, char* dest)
sappend('v',"AT",apWaitTimeSecs);
sappends('s',"AS",apSSID);
sappend('c',"AH",apHide);
l = strlen(apPass);
char fapass[l+1]; //fill password field with ***
fapass[l] = 0;
memset(fapass,'*',l);
memset(fapass,'*',l);
sappends('s',"AP",fapass);
sappend('v',"AC",apChannel);
if (WiFi.localIP()[0] != 0) //is connected
@ -209,7 +209,7 @@ void getSettingsJS(byte subPage, char* dest)
{
sappends('m',"(\"sip\")[0]","Not connected");
}
if (WiFi.softAPIP()[0] != 0) //is active
{
char s[16];
@ -221,7 +221,7 @@ void getSettingsJS(byte subPage, char* dest)
sappends('m',"(\"sip\")[1]","Not active");
}
}
if (subPage == 2) {
sappend('v',"LC",ledCount);
sappend('v',"MA",strip.ablMilliampsMax);
@ -269,7 +269,7 @@ void getSettingsJS(byte subPage, char* dest)
}
if (subPage == 3)
{
{
sappend('i',"UI",uiConfiguration);
sappends('s',"DS",serverDescription);
sappend('c',"MD",useHSBDefault);
@ -308,6 +308,9 @@ void getSettingsJS(byte subPage, char* dest)
sappend('c',"SA",notifyAlexa);
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
sappends('s',"MS",mqttServer);
sappends('s',"MQTTUSER",mqttUser);
sappends('s',"MQTTPASS",mqttPass);
sappends('s',"MQTTCID",mqttClientID);
sappends('s',"MD",mqttDeviceTopic);
sappends('s',"MG",mqttGroupTopic);
sappend('v',"H0",hueIP[0]);
@ -330,7 +333,7 @@ void getSettingsJS(byte subPage, char* dest)
sappend('i',"TZ",currentTimezone);
sappend('v',"UO",utcOffsetSecs);
char tm[32];
getTimeString(tm);
getTimeString(tm);
sappends('m',"(\"times\")[0]",tm);
sappend('i',"OL",overlayCurrent);
sappend('v',"O1",overlayMin);
@ -355,7 +358,7 @@ void getSettingsJS(byte subPage, char* dest)
sprintf(k+1,"%i",i);
sappends('s',k,m);
}
sappend('v',"MB",macroBoot);
sappend('v',"A0",macroAlexaOn);
sappend('v',"A1",macroAlexaOff);
@ -398,7 +401,7 @@ void getThemeColors(char o[][9])
{
switch (currentTheme)
{
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
default: strcpy(o[0], "D9B310"); strcpy(o[1], "0B3C5D"); strcpy(o[2], "1D2731"); strcpy(o[3], "328CC1"); strcpy(o[4], "000"); strcpy(o[5], "328CC1"); break; //night
case 1: strcpy(o[0], "eee"); strcpy(o[1], "ddd"); strcpy(o[2], "b9b9b9"); strcpy(o[3], "049"); strcpy(o[4], "777"); strcpy(o[5], "049"); break; //modern
case 2: strcpy(o[0], "abb"); strcpy(o[1], "fff"); strcpy(o[2], "ddd"); strcpy(o[3], "000"); strcpy(o[4], "0004"); strcpy(o[5], "000"); break; //bright

View File

@ -19,7 +19,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
{
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
if (subPage <1 || subPage >6) return;
//WIFI SETTINGS
if (subPage == 1)
{
@ -27,25 +27,25 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (request->arg("CP").charAt(0) != '*') strcpy(clientPass, request->arg("CP").c_str());
strcpy(cmDNS, request->arg("CM").c_str());
int t = request->arg("AT").toInt(); if (t > 9 && t <= 255) apWaitTimeSecs = t;
strcpy(apSSID, request->arg("AS").c_str());
apHide = request->hasArg("AH");
int passlen = request->arg("AP").length();
if (passlen == 0 || (passlen > 7 && request->arg("AP").charAt(0) != '*')) strcpy(apPass, request->arg("AP").c_str());
t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
char k[3]; k[2] = 0;
for (int i = 0; i<4; i++)
{
k[1] = i+48;//ascii 0,1,2,3
k[0] = 'I'; //static IP
staticIP[i] = request->arg(k).toInt();
k[0] = 'G'; //gateway
staticGateway[i] = request->arg(k).toInt();
k[0] = 'S'; //subnet
staticSubnet[i] = request->arg(k).toInt();
}
@ -63,7 +63,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
#endif
strip.ablMilliampsMax = request->arg("MA").toInt();
useRGBW = request->hasArg("EW");
strip.colorOrder = request->arg("CO").toInt();
strip.colorOrder = request->arg("CO").toInt();
autoRGBtoRGBW = request->hasArg("AW");
//ignore settings and save current brightness, colors and fx as default
@ -100,19 +100,19 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
if (t <= 25) bootPreset = t;
strip.gammaCorrectBri = request->hasArg("GB");
strip.gammaCorrectCol = request->hasArg("GC");
fadeTransition = request->hasArg("TF");
t = request->arg("TD").toInt();
if (t > 0) transitionDelay = t;
transitionDelayDefault = t;
strip.paletteFade = request->hasArg("PF");
enableSecTransition = request->hasArg("T2");
nightlightTargetBri = request->arg("TB").toInt();
t = request->arg("TL").toInt();
if (t > 0) nightlightDelayMinsDefault = t;
nightlightFade = request->hasArg("TW");
t = request->arg("PB").toInt();
if (t >= 0 && t < 4) strip.paletteBlend = t;
strip.reverseMode = request->hasArg("RV");
@ -157,7 +157,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
notifyHue = request->hasArg("SH");
notifyMacro = request->hasArg("SM");
notifyTwice = request->hasArg("S2");
receiveDirect = request->hasArg("RD");
e131Multicast = request->hasArg("EM");
t = request->arg("EU").toInt();
@ -168,18 +168,21 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
arlsDisableGammaCorrection = request->hasArg("RG");
t = request->arg("WO").toInt();
if (t >= -255 && t <= 255) arlsOffset = t;
alexaEnabled = request->hasArg("AL");
strcpy(alexaInvocationName, request->arg("AI").c_str());
if (request->hasArg("BK") && !request->arg("BK").equals("Hidden")) {
strcpy(blynkApiKey,request->arg("BK").c_str()); initBlynk(blynkApiKey);
}
strcpy(mqttServer, request->arg("MS").c_str());
strcpy(mqttUser, request->arg("MQTTUSER").c_str());
strcpy(mqttPass, request->arg("MQTTPASS").c_str());
strcpy(mqttClientID, request->arg("MQTTCID").c_str());
strcpy(mqttDeviceTopic, request->arg("MD").c_str());
strcpy(mqttGroupTopic, request->arg("MG").c_str());
for (int i=0;i<4;i++){
String a = "H"+String(i);
hueIP[i] = request->arg(a).toInt();
@ -209,19 +212,19 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
//start ntp if not already connected
if (ntpEnabled && WiFi.status() == WL_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort);
if (request->hasArg("OL")){
overlayDefault = request->arg("OL").toInt();
if (overlayCurrent != overlayDefault) strip.unlockAll();
overlayCurrent = overlayDefault;
}
overlayMin = request->arg("O1").toInt();
overlayMax = request->arg("O2").toInt();
analogClock12pixel = request->arg("OM").toInt();
analogClock5MinuteMarks = request->hasArg("O5");
analogClockSecondsTrail = request->hasArg("OS");
strcpy(cronixieDisplay,request->arg("CX").c_str());
bool cbOld = cronixieBacklight;
cronixieBacklight = request->hasArg("CB");
@ -236,13 +239,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
countdownHour = request->arg("CH").toInt();
countdownMin = request->arg("CM").toInt();
countdownSec = request->arg("CS").toInt();
for (int i=1;i<17;i++)
{
String a = "M"+String(i);
if (request->hasArg(a.c_str())) saveMacro(i,request->arg(a),false);
}
macroBoot = request->arg("MB").toInt();
macroAlexaOn = request->arg("A0").toInt();
macroAlexaOff = request->arg("A1").toInt();
@ -256,13 +259,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
for (int i = 0; i<8; i++)
{
k[1] = i+48;//ascii 0,1,2,3
k[0] = 'H'; //timer hours
timerHours[i] = request->arg(k).toInt();
k[0] = 'N'; //minutes
timerMinutes[i] = request->arg(k).toInt();
k[0] = 'T'; //macros
timerMacro[i] = request->arg(k).toInt();
@ -293,7 +296,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
strcpy(otaPass,request->arg("OP").c_str());
}
}
if (pwdCorrect) //allow changes if correct pwd or no ota active
{
otaLock = request->hasArg("NO");
@ -321,7 +324,7 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte
{
int pos = req->indexOf(key);
if (pos < 1) return false;
if (req->charAt(pos+3) == '~') {
int out = getNumVal(req, pos+1);
if (out == 0)
@ -354,25 +357,25 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
int pos = 0;
DEBUG_PRINT("API req: ");
DEBUG_PRINTLN(req);
//save macro, requires &MS=<slot>(<macro>) format
pos = req.indexOf("&MS=");
if (pos > 0) {
int i = req.substring(pos + 4).toInt();
pos = req.indexOf('(') +1;
if (pos > 0) {
if (pos > 0) {
int en = req.indexOf(')');
String mc = req.substring(pos);
if (en > 0) mc = req.substring(pos, en);
saveMacro(i, mc);
saveMacro(i, mc);
}
pos = req.indexOf("IN");
if (pos < 1) XML_response(request, false);
return true;
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
}
//set brightness
updateVal(&req, "&A=", &bri);
@ -397,7 +400,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
}
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
}
//set color from HEX or 32bit DEC
pos = req.indexOf("CL=");
if (pos > 0) {
@ -407,7 +410,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (pos > 0) {
colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str());
}
//set 2nd to white
pos = req.indexOf("SW");
if (pos > 0) {
@ -422,7 +425,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
colSec[2] = 255;
}
}
//set 2nd to black
pos = req.indexOf("SB");
if (pos > 0) {
@ -431,13 +434,13 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
colSec[1] = 0;
colSec[2] = 0;
}
//set to random hue SR=0->1st SR=1->2nd
pos = req.indexOf("SR");
if (pos > 0) {
_setRandomColor(getNumVal(&req, pos));
}
//set 2nd to 1st
pos = req.indexOf("SP");
if (pos > 0) {
@ -446,7 +449,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
colSec[2] = col[2];
colSec[3] = col[3];
}
//swap 2nd & 1st
pos = req.indexOf("SC");
if (pos > 0) {
@ -458,7 +461,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
colSec[i] = temp;
}
}
//set effect parameters
if (updateVal(&req, "FX=", &effectCurrent, 0, strip.getModeCount()-1)) presetCyclingEnabled = false;
updateVal(&req, "SX=", &effectSpeed);
@ -479,20 +482,20 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
}
}
#endif
//set default control mode (0 - RGB, 1 - HSB)
pos = req.indexOf("MD=");
if (pos > 0) {
useHSB = getNumVal(&req, pos);
}
//set advanced overlay
pos = req.indexOf("OL=");
if (pos > 0) {
overlayCurrent = getNumVal(&req, pos);
strip.unlockAll();
}
//(un)lock pixel (ranges)
pos = req.indexOf("&L=");
if (pos > 0) {
@ -520,11 +523,11 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (pos > 0) {
applyMacro(getNumVal(&req, pos));
}
//toggle send UDP direct notifications
pos = req.indexOf("SN=");
if (pos > 0) notifyDirect = (req.charAt(pos+3) != '0');
//toggle receive UDP direct notifications
pos = req.indexOf("RN=");
if (pos > 0) receiveNotifications = (req.charAt(pos+3) != '0');
@ -532,7 +535,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
//receive live data via UDP/Hyperion
pos = req.indexOf("RD=");
if (pos > 0) receiveDirect = (req.charAt(pos+3) != '0');
//toggle nightlight mode
bool aNlDef = false;
if (req.indexOf("&ND") > 0) aNlDef = true;
@ -553,14 +556,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
nightlightActive = true;
nightlightStartTime = millis();
}
//set nightlight target brightness
pos = req.indexOf("NT=");
if (pos > 0) {
nightlightTargetBri = getNumVal(&req, pos);
nightlightActiveOld = false; //re-init
}
//toggle nightlight fade
pos = req.indexOf("NF=");
if (pos > 0)
@ -578,7 +581,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (auxTime == 0) auxActive = false;
}
#endif
pos = req.indexOf("TT=");
if (pos > 0) transitionDelay = getNumVal(&req, pos);
@ -597,7 +600,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
//Segment reverse
pos = req.indexOf("RV=");
if (pos > 0) strip.getSegment(0).setOption(1, req.charAt(pos+3) != '0');
//deactivate nightlight if target brightness is reached
if (bri == nightlightTargetBri) nightlightActive = false;
//set time (unix timestamp)
@ -605,18 +608,18 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (pos > 0) {
setTime(getNumVal(&req, pos));
}
//set countdown goal (unix timestamp)
pos = req.indexOf("CT=");
if (pos > 0) {
countdownTime = getNumVal(&req, pos);
if (countdownTime - now() > 0) countdownOverTriggered = false;
}
//set presets
pos = req.indexOf("P1="); //sets first preset for cycle
if (pos > 0) presetCycleMin = getNumVal(&req, pos);
pos = req.indexOf("P2="); //sets last preset for cycle
if (pos > 0) presetCycleMax = getNumVal(&req, pos);
@ -627,7 +630,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
presetCyclingEnabled = (req.charAt(pos+3) != '0');
presetCycCurr = presetCycleMin;
}
pos = req.indexOf("PT="); //sets cycle time in ms
if (pos > 0) {
int v = getNumVal(&req, pos);
@ -638,11 +641,11 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (pos > 0) presetApplyBri = (req.charAt(pos+3) != '0');
pos = req.indexOf("PC="); //apply color from preset
if (pos > 0) presetApplyCol = (req.charAt(pos+3) != '0');
if (pos > 0) presetApplyCol = (req.charAt(pos+3) != '0');
pos = req.indexOf("PX="); //apply effects from preset
if (pos > 0) presetApplyFx = (req.charAt(pos+3) != '0');
pos = req.indexOf("PS="); //saves current in preset
if (pos > 0) savePreset(getNumVal(&req, pos));
@ -650,7 +653,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (updateVal(&req, "PL=", &presetCycCurr, presetCycleMin, presetCycleMax)) {
applyPreset(presetCycCurr, presetApplyBri, presetApplyCol, presetApplyFx);
}
//cronixie
#ifndef WLED_DISABLE_CRONIXIE
pos = req.indexOf("NX="); //sets digits to code
@ -658,7 +661,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
strcpy(cronixieDisplay,req.substring(pos + 3, pos + 9).c_str());
setCronixie();
}
if (req.indexOf("NB=") > 0) //sets backlight
{
cronixieBacklight = true;
@ -673,24 +676,24 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
//mode, 1 countdown
pos = req.indexOf("NM=");
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
pos = req.indexOf("U0="); //user var 0
if (pos > 0) {
userVar0 = getNumVal(&req, pos);
}
pos = req.indexOf("U1="); //user var 1
if (pos > 0) {
userVar1 = getNumVal(&req, pos);
}
//you can add more if you need
//internal call, does not send XML response
pos = req.indexOf("IN");
if (pos < 1) XML_response(request, (req.indexOf("&IT") > 0)); //include theme if firstload
pos = req.indexOf("&NN"); //do not send UDP notifications this time
colorUpdated((pos > 0) ? 5:1);
return true;
}

View File

@ -3,9 +3,9 @@
*/
void wledInit()
{
{
EEPROM.begin(EEPSIZE);
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
if (ledCount > 1200 || ledCount == 0) ledCount = 30;
#ifndef ARDUINO_ARCH_ESP32
#if LEDPIN == 3
@ -24,7 +24,7 @@ void wledInit()
int heapPreAlloc = ESP.getFreeHeap();
DEBUG_PRINT("heap ");
DEBUG_PRINTLN(ESP.getFreeHeap());
strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly
DEBUG_PRINT("LEDs inited. heap usage ~");
@ -36,7 +36,7 @@ void wledInit()
#endif
SPIFFS.begin();
#endif
DEBUG_PRINTLN("Load EEPROM");
loadSettingsFromEEPROM(true);
beginStrip();
@ -67,7 +67,7 @@ void wledInit()
ntpConnected = ntpUdp.begin(ntpLocalPort);
//start captive portal if AP active
if (onlyAP || strlen(apSSID) > 0)
if (onlyAP || strlen(apSSID) > 0)
{
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure);
dnsServer.start(53, "wled.me", WiFi.softAPIP());
@ -85,12 +85,17 @@ void wledInit()
strcpy(mqttDeviceTopic, "wled/");
strcat(mqttDeviceTopic, escapedMac.c_str());
}
if (mqttClientID[0] == 0)
{
strcpy(mqttClientID, "WLED-");
sprintf(mqttClientID+5, "%*s", 6, escapedMac.c_str()+6);
}
strip.service();
//HTTP server page init
initServer();
strip.service();
//init Alexa hue emulation
if (alexaEnabled && !onlyAP) alexaInit();
@ -113,7 +118,7 @@ void wledInit()
ArduinoOTA.begin();
}
#endif
strip.service();
// Set up mDNS responder:
if (strlen(cmDNS) > 0 && !onlyAP)

View File

@ -22,7 +22,7 @@ void onMqttConnect(bool sessionPresent)
//(re)subscribe to required topics
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
if (mqttDeviceTopic[0] != 0)
{
strcpy(subuf, mqttDeviceTopic);
@ -80,7 +80,7 @@ void publishMqtt()
char s[10];
char subuf[38];
sprintf(s, "%ld", bri);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/g");
@ -102,7 +102,7 @@ const char HA_static_JSON[] PROGMEM = R"=====(,"bri_val_tpl":"{{value}}","rgb_cm
void sendHADiscoveryMQTT()
{
#if ARDUINO_ARCH_ESP32 || LEDPIN != 3
/*
@ -130,7 +130,7 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
"fx_val_tpl":"{{value}}",
"fx_list":[
"[FX=00] Solid",
"[FX=01] Blink",
"[FX=01] Blink",
"[FX=02] ...",
"[FX=79] Ripple"
]
@ -180,11 +180,11 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
{
if (pgm_read_byte(JSON_mode_names + j) == '\"' || j == jmnlen -1)
{
if (isNameStart)
if (isNameStart)
{
nameStart = j +1;
}
else
else
{
nameEnd = j;
char mdnfx[64], mdn[56];
@ -197,7 +197,7 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
i++;
}
isNameStart = !isNameStart;
}
}
}
olen--;
oappend("]}");
@ -219,7 +219,7 @@ bool initMqtt()
if (WiFi.status() != WL_CONNECTED) return false;
if (!mqtt) mqtt = new AsyncMqttClient();
if (mqtt->connected()) return true;
IPAddress mqttIP;
if (mqttIP.fromString(mqttServer)) //see if server is IP or domain
{
@ -227,7 +227,9 @@ bool initMqtt()
} else {
mqtt->setServer(mqttServer, WLED_MQTT_PORT);
}
mqtt->setClientId(escapedMac.c_str());
//mqtt->setClientId(escapedMac.c_str());
mqtt->setClientId(mqttClientID);
if (mqttUser[0] && mqttPass[0] != 0) mqtt->setCredentials(mqttUser, mqttPass);
mqtt->onMessage(onMqttMessage);
mqtt->onConnect(onMqttConnect);
mqtt->connect();