2016-12-31 00:38:51 +01:00
|
|
|
/*
|
|
|
|
* Receives client input
|
|
|
|
*/
|
|
|
|
|
2018-03-15 13:03:50 +01:00
|
|
|
void _setRandomColor(bool _sec,bool fromButton=false)
|
2017-12-11 23:59:12 +01:00
|
|
|
{
|
|
|
|
lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex);
|
|
|
|
if (_sec){
|
2018-03-15 13:03:50 +01:00
|
|
|
colorHStoRGB(lastRandomIndex*256,255,colSec);
|
2017-12-11 23:59:12 +01:00
|
|
|
} else {
|
2018-03-15 13:03:50 +01:00
|
|
|
colorHStoRGB(lastRandomIndex*256,255,col);
|
2017-12-11 23:59:12 +01:00
|
|
|
}
|
2018-03-15 13:03:50 +01:00
|
|
|
if (fromButton) colorUpdated(2);
|
2017-12-11 23:59:12 +01:00
|
|
|
}
|
|
|
|
|
2018-09-17 11:15:08 +02:00
|
|
|
|
2019-12-11 00:59:15 +01:00
|
|
|
bool isAsterisksOnly(const char* str, byte maxLen)
|
|
|
|
{
|
|
|
|
for (byte i = 0; i < maxLen; i++) {
|
|
|
|
if (str[i] == 0) break;
|
|
|
|
if (str[i] != '*') return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-09-17 11:15:08 +02:00
|
|
|
//called upon POST settings form submit
|
2019-02-16 00:21:22 +01:00
|
|
|
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2018-02-20 22:29:48 +01:00
|
|
|
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
|
|
|
|
if (subPage <1 || subPage >6) return;
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-02-20 22:29:48 +01:00
|
|
|
//WIFI SETTINGS
|
|
|
|
if (subPage == 1)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(clientSSID,request->arg("CS").c_str(), 33);
|
2019-12-11 00:59:15 +01:00
|
|
|
|
|
|
|
if (!isAsterisksOnly(request->arg("CP").c_str(), 65)) strlcpy(clientPass, request->arg("CP").c_str(), 65);
|
2018-09-17 11:15:08 +02:00
|
|
|
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(cmDNS, request->arg("CM").c_str(), 33);
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-10-25 00:14:58 +02:00
|
|
|
apBehavior = request->arg("AB").toInt();
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(apSSID, request->arg("AS").c_str(), 33);
|
2019-02-16 00:21:22 +01:00
|
|
|
apHide = request->hasArg("AH");
|
2019-04-14 19:31:25 +02:00
|
|
|
int passlen = request->arg("AP").length();
|
2019-12-11 00:59:15 +01:00
|
|
|
if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg("AP").c_str(), 65))) strlcpy(apPass, request->arg("AP").c_str(), 65);
|
2019-10-25 00:14:58 +02:00
|
|
|
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2020-02-20 17:08:56 +01:00
|
|
|
noWifiSleep = request->hasArg("WS");
|
|
|
|
|
2018-09-17 11:15:08 +02:00
|
|
|
char k[3]; k[2] = 0;
|
2018-07-21 23:21:07 +02:00
|
|
|
for (int i = 0; i<4; i++)
|
2018-01-27 23:28:20 +01:00
|
|
|
{
|
2018-09-17 11:15:08 +02:00
|
|
|
k[1] = i+48;//ascii 0,1,2,3
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-07-21 23:21:07 +02:00
|
|
|
k[0] = 'I'; //static IP
|
2019-02-16 00:21:22 +01:00
|
|
|
staticIP[i] = request->arg(k).toInt();
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-07-21 23:21:07 +02:00
|
|
|
k[0] = 'G'; //gateway
|
2019-02-16 00:21:22 +01:00
|
|
|
staticGateway[i] = request->arg(k).toInt();
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-07-21 23:21:07 +02:00
|
|
|
k[0] = 'S'; //subnet
|
2019-02-16 00:21:22 +01:00
|
|
|
staticSubnet[i] = request->arg(k).toInt();
|
2016-11-27 16:45:54 +01:00
|
|
|
}
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
2018-02-20 22:29:48 +01:00
|
|
|
|
|
|
|
//LED SETTINGS
|
|
|
|
if (subPage == 2)
|
2016-12-11 20:11:14 +01:00
|
|
|
{
|
2019-02-16 00:21:22 +01:00
|
|
|
int t = request->arg("LC").toInt();
|
2019-10-26 00:00:44 +02:00
|
|
|
if (t > 0 && t <= MAX_LEDS) ledCount = t;
|
2019-11-12 19:33:34 +01:00
|
|
|
#ifdef ESP8266
|
2019-02-20 23:44:34 +01:00
|
|
|
#if LEDPIN == 3
|
2019-10-26 00:00:44 +02:00
|
|
|
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
2019-02-20 23:44:34 +01:00
|
|
|
#endif
|
2018-09-17 11:15:08 +02:00
|
|
|
#endif
|
2019-02-16 00:21:22 +01:00
|
|
|
strip.ablMilliampsMax = request->arg("MA").toInt();
|
2019-11-12 19:33:34 +01:00
|
|
|
strip.milliampsPerLed = request->arg("LA").toInt();
|
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
useRGBW = request->hasArg("EW");
|
2019-08-17 12:27:06 +02:00
|
|
|
strip.colorOrder = request->arg("CO").toInt();
|
2020-02-20 00:45:09 +01:00
|
|
|
strip.rgbwMode = request->arg("AW").toInt();
|
2018-11-09 17:00:36 +01:00
|
|
|
|
2019-12-04 02:01:47 +01:00
|
|
|
briS = request->arg("CA").toInt();
|
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
saveCurrPresetCycConf = request->hasArg("PC");
|
|
|
|
turnOnAtBoot = request->hasArg("BO");
|
|
|
|
t = request->arg("BP").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t <= 25) bootPreset = t;
|
2019-05-22 00:23:09 +02:00
|
|
|
strip.gammaCorrectBri = request->hasArg("GB");
|
|
|
|
strip.gammaCorrectCol = request->hasArg("GC");
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
fadeTransition = request->hasArg("TF");
|
|
|
|
t = request->arg("TD").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 0) transitionDelay = t;
|
2018-09-28 23:53:51 +02:00
|
|
|
transitionDelayDefault = t;
|
2019-02-16 00:21:22 +01:00
|
|
|
strip.paletteFade = request->hasArg("PF");
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
nightlightTargetBri = request->arg("TB").toInt();
|
|
|
|
t = request->arg("TL").toInt();
|
2018-11-22 00:09:30 +01:00
|
|
|
if (t > 0) nightlightDelayMinsDefault = t;
|
2019-09-19 21:15:20 +02:00
|
|
|
nightlightDelayMins = nightlightDelayMinsDefault;
|
2019-02-16 00:21:22 +01:00
|
|
|
nightlightFade = request->hasArg("TW");
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
t = request->arg("PB").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t >= 0 && t < 4) strip.paletteBlend = t;
|
2019-05-22 00:23:09 +02:00
|
|
|
strip.reverseMode = request->hasArg("RV");
|
2019-02-16 00:21:22 +01:00
|
|
|
skipFirstLed = request->hasArg("SL");
|
|
|
|
t = request->arg("BF").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 0) briMultiplier = t;
|
2016-12-11 20:11:14 +01:00
|
|
|
}
|
2018-02-20 22:29:48 +01:00
|
|
|
|
|
|
|
//UI
|
|
|
|
if (subPage == 3)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(serverDescription, request->arg("DS").c_str(), 33);
|
2019-12-13 01:23:07 +01:00
|
|
|
syncToggleReceive = request->hasArg("ST");
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
2018-02-20 22:29:48 +01:00
|
|
|
|
|
|
|
//SYNC
|
|
|
|
if (subPage == 4)
|
2017-02-24 23:21:48 +01:00
|
|
|
{
|
2019-02-16 00:21:22 +01:00
|
|
|
buttonEnabled = request->hasArg("BT");
|
2020-01-08 00:46:16 +01:00
|
|
|
irEnabled = request->arg("IR").toInt();
|
2019-02-16 00:21:22 +01:00
|
|
|
int t = request->arg("UP").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 0) udpPort = t;
|
2019-02-16 00:21:22 +01:00
|
|
|
receiveNotificationBrightness = request->hasArg("RB");
|
|
|
|
receiveNotificationColor = request->hasArg("RC");
|
|
|
|
receiveNotificationEffects = request->hasArg("RX");
|
2018-02-20 22:29:48 +01:00
|
|
|
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
2019-02-16 00:21:22 +01:00
|
|
|
notifyDirectDefault = request->hasArg("SD");
|
2018-02-20 22:29:48 +01:00
|
|
|
notifyDirect = notifyDirectDefault;
|
2019-02-16 00:21:22 +01:00
|
|
|
notifyButton = request->hasArg("SB");
|
2019-02-19 12:57:50 +01:00
|
|
|
notifyAlexa = request->hasArg("SA");
|
|
|
|
notifyHue = request->hasArg("SH");
|
|
|
|
notifyMacro = request->hasArg("SM");
|
2019-02-16 00:21:22 +01:00
|
|
|
notifyTwice = request->hasArg("S2");
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
receiveDirect = request->hasArg("RD");
|
|
|
|
e131Multicast = request->hasArg("EM");
|
|
|
|
t = request->arg("EU").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 0 && t <= 63999) e131Universe = t;
|
2020-02-08 20:52:45 +01:00
|
|
|
t = request->arg("DA").toInt();
|
|
|
|
if (t > 0 && t <= 510) DMXAddress = t;
|
|
|
|
t = request->arg("DM").toInt();
|
|
|
|
if (t >= DMX_MODE_DISABLED && t <= DMX_MODE_MULTIPLE_DRGB) DMXMode = t;
|
2019-02-16 00:21:22 +01:00
|
|
|
t = request->arg("ET").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 99 && t <= 65000) realtimeTimeoutMs = t;
|
2019-02-16 00:21:22 +01:00
|
|
|
arlsForceMaxBri = request->hasArg("FB");
|
|
|
|
arlsDisableGammaCorrection = request->hasArg("RG");
|
|
|
|
t = request->arg("WO").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t >= -255 && t <= 255) arlsOffset = t;
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
alexaEnabled = request->hasArg("AL");
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(alexaInvocationName, request->arg("AI").c_str(), 33);
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
if (request->hasArg("BK") && !request->arg("BK").equals("Hidden")) {
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(blynkApiKey, request->arg("BK").c_str(), 36); initBlynk(blynkApiKey);
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2018-10-04 16:50:12 +02:00
|
|
|
|
2019-12-11 00:59:15 +01:00
|
|
|
#ifdef WLED_ENABLE_MQTT
|
2019-12-13 01:23:07 +01:00
|
|
|
mqttEnabled = request->hasArg("MQ");
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(mqttServer, request->arg("MS").c_str(), 33);
|
2019-08-18 18:14:17 +02:00
|
|
|
t = request->arg("MQPORT").toInt();
|
|
|
|
if (t > 0) mqttPort = t;
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(mqttUser, request->arg("MQUSER").c_str(), 41);
|
2019-12-11 00:59:15 +01:00
|
|
|
if (!isAsterisksOnly(request->arg("MQPASS").c_str(), 41)) strlcpy(mqttPass, request->arg("MQPASS").c_str(), 41);
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(mqttClientID, request->arg("MQCID").c_str(), 41);
|
|
|
|
strlcpy(mqttDeviceTopic, request->arg("MD").c_str(), 33);
|
|
|
|
strlcpy(mqttGroupTopic, request->arg("MG").c_str(), 33);
|
2019-12-11 00:59:15 +01:00
|
|
|
#endif
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-12-11 00:59:15 +01:00
|
|
|
#ifndef WLED_DISABLE_HUESYNC
|
2018-02-28 00:27:10 +01:00
|
|
|
for (int i=0;i<4;i++){
|
2018-03-14 19:05:51 +01:00
|
|
|
String a = "H"+String(i);
|
2019-02-16 00:21:22 +01:00
|
|
|
hueIP[i] = request->arg(a).toInt();
|
2018-02-28 00:27:10 +01:00
|
|
|
}
|
2018-09-17 11:15:08 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
t = request->arg("HL").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 0) huePollLightId = t;
|
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
t = request->arg("HI").toInt();
|
2018-09-17 11:15:08 +02:00
|
|
|
if (t > 50) huePollIntervalMs = t;
|
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
hueApplyOnOff = request->hasArg("HO");
|
|
|
|
hueApplyBri = request->hasArg("HB");
|
|
|
|
hueApplyColor = request->hasArg("HC");
|
2019-02-18 22:34:21 +01:00
|
|
|
huePollingEnabled = request->hasArg("HP");
|
|
|
|
hueStoreAllowed = true;
|
|
|
|
reconnectHue();
|
2019-12-11 00:59:15 +01:00
|
|
|
#endif
|
2017-02-24 23:21:48 +01:00
|
|
|
}
|
2018-02-20 22:29:48 +01:00
|
|
|
|
|
|
|
//TIME
|
|
|
|
if (subPage == 5)
|
2017-02-24 23:21:48 +01:00
|
|
|
{
|
2019-02-16 00:21:22 +01:00
|
|
|
ntpEnabled = request->hasArg("NT");
|
2019-12-04 02:01:47 +01:00
|
|
|
strlcpy(ntpServerName, request->arg("NS").c_str(), 33);
|
2019-02-16 00:21:22 +01:00
|
|
|
useAMPM = !request->hasArg("CF");
|
|
|
|
currentTimezone = request->arg("TZ").toInt();
|
|
|
|
utcOffsetSecs = request->arg("UO").toInt();
|
2018-11-09 17:00:36 +01:00
|
|
|
|
|
|
|
//start ntp if not already connected
|
2019-10-18 13:26:39 +02:00
|
|
|
if (ntpEnabled && WLED_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
if (request->hasArg("OL")){
|
|
|
|
overlayDefault = request->arg("OL").toInt();
|
2018-03-14 00:25:54 +01:00
|
|
|
overlayCurrent = overlayDefault;
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
overlayMin = request->arg("O1").toInt();
|
|
|
|
overlayMax = request->arg("O2").toInt();
|
|
|
|
analogClock12pixel = request->arg("OM").toInt();
|
|
|
|
analogClock5MinuteMarks = request->hasArg("O5");
|
|
|
|
analogClockSecondsTrail = request->hasArg("OS");
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
strcpy(cronixieDisplay,request->arg("CX").c_str());
|
2018-03-14 00:25:54 +01:00
|
|
|
bool cbOld = cronixieBacklight;
|
2019-02-16 00:21:22 +01:00
|
|
|
cronixieBacklight = request->hasArg("CB");
|
2018-09-22 22:49:24 +02:00
|
|
|
if (cbOld != cronixieBacklight && overlayCurrent == 3)
|
2018-03-14 00:25:54 +01:00
|
|
|
{
|
|
|
|
strip.setCronixieBacklight(cronixieBacklight); overlayRefreshedTime = 0;
|
|
|
|
}
|
2019-02-16 00:21:22 +01:00
|
|
|
countdownMode = request->hasArg("CE");
|
|
|
|
countdownYear = request->arg("CY").toInt();
|
|
|
|
countdownMonth = request->arg("CI").toInt();
|
|
|
|
countdownDay = request->arg("CD").toInt();
|
|
|
|
countdownHour = request->arg("CH").toInt();
|
|
|
|
countdownMin = request->arg("CM").toInt();
|
|
|
|
countdownSec = request->arg("CS").toInt();
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-03-14 00:25:54 +01:00
|
|
|
for (int i=1;i<17;i++)
|
|
|
|
{
|
2018-03-14 19:05:51 +01:00
|
|
|
String a = "M"+String(i);
|
2019-02-16 00:21:22 +01:00
|
|
|
if (request->hasArg(a.c_str())) saveMacro(i,request->arg(a),false);
|
2018-03-14 00:25:54 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-16 00:21:22 +01:00
|
|
|
macroBoot = request->arg("MB").toInt();
|
|
|
|
macroAlexaOn = request->arg("A0").toInt();
|
|
|
|
macroAlexaOff = request->arg("A1").toInt();
|
|
|
|
macroButton = request->arg("MP").toInt();
|
|
|
|
macroLongPress = request->arg("ML").toInt();
|
|
|
|
macroCountdown = request->arg("MC").toInt();
|
|
|
|
macroNl = request->arg("MN").toInt();
|
2019-03-13 11:13:03 +01:00
|
|
|
macroDoublePress = request->arg("MD").toInt();
|
2018-09-22 22:49:24 +02:00
|
|
|
|
|
|
|
char k[3]; k[2] = 0;
|
|
|
|
for (int i = 0; i<8; i++)
|
|
|
|
{
|
|
|
|
k[1] = i+48;//ascii 0,1,2,3
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-09-22 22:49:24 +02:00
|
|
|
k[0] = 'H'; //timer hours
|
2019-02-16 00:21:22 +01:00
|
|
|
timerHours[i] = request->arg(k).toInt();
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-09-22 22:49:24 +02:00
|
|
|
k[0] = 'N'; //minutes
|
2019-02-16 00:21:22 +01:00
|
|
|
timerMinutes[i] = request->arg(k).toInt();
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-09-22 22:49:24 +02:00
|
|
|
k[0] = 'T'; //macros
|
2019-02-16 00:21:22 +01:00
|
|
|
timerMacro[i] = request->arg(k).toInt();
|
2019-01-31 00:09:44 +01:00
|
|
|
|
|
|
|
k[0] = 'W'; //weekdays
|
2019-02-16 00:21:22 +01:00
|
|
|
timerWeekday[i] = request->arg(k).toInt();
|
2018-09-22 22:49:24 +02:00
|
|
|
}
|
2017-02-24 23:21:48 +01:00
|
|
|
}
|
2018-02-20 22:29:48 +01:00
|
|
|
|
|
|
|
//SECURITY
|
|
|
|
if (subPage == 6)
|
2016-11-20 01:47:15 +01:00
|
|
|
{
|
2019-02-16 00:21:22 +01:00
|
|
|
if (request->hasArg("RS")) //complete factory reset
|
2016-11-20 01:47:15 +01:00
|
|
|
{
|
2018-02-20 22:29:48 +01:00
|
|
|
clearEEPROM();
|
2019-02-16 00:21:22 +01:00
|
|
|
serveMessage(request, 200, "All Settings erased.", "Connect to WLED-AP to setup again",255);
|
2019-02-17 17:11:10 +01:00
|
|
|
doReboot = true;
|
2018-02-20 22:29:48 +01:00
|
|
|
}
|
2018-02-23 01:33:32 +01:00
|
|
|
|
|
|
|
bool pwdCorrect = !otaLock; //always allow access if ota not locked
|
2019-02-16 00:21:22 +01:00
|
|
|
if (request->hasArg("OP"))
|
2016-11-20 01:47:15 +01:00
|
|
|
{
|
2019-02-16 00:21:22 +01:00
|
|
|
if (otaLock && strcmp(otaPass,request->arg("OP").c_str()) == 0)
|
2018-02-20 22:29:48 +01:00
|
|
|
{
|
2018-02-23 01:33:32 +01:00
|
|
|
pwdCorrect = true;
|
|
|
|
}
|
2019-02-16 00:21:22 +01:00
|
|
|
if (!otaLock && request->arg("OP").length() > 0)
|
2016-11-20 01:47:15 +01:00
|
|
|
{
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(otaPass,request->arg("OP").c_str(), 33);
|
2016-11-20 01:47:15 +01:00
|
|
|
}
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-02-23 01:33:32 +01:00
|
|
|
if (pwdCorrect) //allow changes if correct pwd or no ota active
|
2018-02-20 22:29:48 +01:00
|
|
|
{
|
2019-02-16 00:21:22 +01:00
|
|
|
otaLock = request->hasArg("NO");
|
|
|
|
wifiLock = request->hasArg("OW");
|
|
|
|
aOtaEnabled = request->hasArg("AO");
|
2018-02-20 22:29:48 +01:00
|
|
|
}
|
2016-11-20 01:47:15 +01:00
|
|
|
}
|
2019-03-07 23:22:52 +01:00
|
|
|
if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset
|
2019-11-29 18:53:01 +01:00
|
|
|
if (subPage == 2) {
|
2020-01-14 10:59:57 +01:00
|
|
|
strip.init(useRGBW,ledCount,skipFirstLed);
|
2019-11-29 18:53:01 +01:00
|
|
|
}
|
2019-01-09 22:52:42 +01:00
|
|
|
if (subPage == 4) alexaInit();
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|
|
|
|
|
2018-11-25 00:00:02 +01:00
|
|
|
|
2019-02-22 22:53:33 +01:00
|
|
|
|
2018-11-25 00:00:02 +01:00
|
|
|
//helper to get int value at a position in string
|
2019-03-09 21:41:23 +01:00
|
|
|
int getNumVal(const String* req, uint16_t pos)
|
2018-11-25 00:00:02 +01:00
|
|
|
{
|
2019-02-22 22:53:33 +01:00
|
|
|
return req->substring(pos+3).toInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//helper to get int value at a position in string
|
2019-03-09 21:41:23 +01:00
|
|
|
bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255)
|
2019-02-22 22:53:33 +01:00
|
|
|
{
|
|
|
|
int pos = req->indexOf(key);
|
|
|
|
if (pos < 1) return false;
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-22 22:53:33 +01:00
|
|
|
if (req->charAt(pos+3) == '~') {
|
|
|
|
int out = getNumVal(req, pos+1);
|
|
|
|
if (out == 0)
|
|
|
|
{
|
|
|
|
if (req->charAt(pos+4) == '-')
|
|
|
|
{
|
|
|
|
*val = (*val <= minv)? maxv : *val -1;
|
|
|
|
} else {
|
|
|
|
*val = (*val >= maxv)? minv : *val +1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
out += *val;
|
|
|
|
if (out > maxv) out = maxv;
|
|
|
|
if (out < minv) out = minv;
|
|
|
|
*val = out;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
*val = getNumVal(req, pos);
|
|
|
|
}
|
|
|
|
return true;
|
2018-11-25 00:00:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//HTTP API request parser
|
2019-03-09 21:41:23 +01:00
|
|
|
bool handleSet(AsyncWebServerRequest *request, const String& req)
|
2016-11-19 19:39:17 +01:00
|
|
|
{
|
2018-11-09 17:00:36 +01:00
|
|
|
if (!(req.indexOf("win") >= 0)) return false;
|
2018-09-17 11:15:08 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
int pos = 0;
|
|
|
|
DEBUG_PRINT("API req: ");
|
|
|
|
DEBUG_PRINTLN(req);
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//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;
|
2019-08-17 12:27:06 +02:00
|
|
|
if (pos > 0) {
|
2018-11-09 17:00:36 +01:00
|
|
|
int en = req.indexOf(')');
|
|
|
|
String mc = req.substring(pos);
|
|
|
|
if (en > 0) mc = req.substring(pos, en);
|
2019-08-17 12:27:06 +02:00
|
|
|
saveMacro(i, mc);
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
pos = req.indexOf("IN");
|
2019-12-04 02:01:47 +01:00
|
|
|
if (pos < 1) XML_response(request);
|
2018-11-09 17:00:36 +01:00
|
|
|
return true;
|
|
|
|
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-12-02 12:41:35 +01:00
|
|
|
strip.applyToAllSelected = true;
|
|
|
|
|
2019-12-01 01:42:52 +01:00
|
|
|
//segment select (sets main segment)
|
2019-12-04 02:01:47 +01:00
|
|
|
byte prevMain = strip.getMainSegmentId();
|
|
|
|
pos = req.indexOf("SM=");
|
2019-12-01 01:42:52 +01:00
|
|
|
if (pos > 0) {
|
|
|
|
strip.mainSegment = getNumVal(&req, pos);
|
|
|
|
}
|
|
|
|
byte main = strip.getMainSegmentId();
|
2019-12-04 02:01:47 +01:00
|
|
|
if (main != prevMain) setValuesFromMainSeg();
|
|
|
|
|
|
|
|
pos = req.indexOf("SS=");
|
|
|
|
if (pos > 0) {
|
|
|
|
byte t = getNumVal(&req, pos);
|
|
|
|
if (t < strip.getMaxSegments()) main = t;
|
|
|
|
}
|
|
|
|
|
2020-01-19 01:07:38 +01:00
|
|
|
WS2812FX::Segment& mainseg = strip.getSegment(main);
|
2019-12-04 02:01:47 +01:00
|
|
|
pos = req.indexOf("SV="); //segment selected
|
2020-01-19 01:07:38 +01:00
|
|
|
if (pos > 0) mainseg.setOption(0, (req.charAt(pos+3) != '0'));
|
2019-12-01 01:42:52 +01:00
|
|
|
|
2020-01-19 01:07:38 +01:00
|
|
|
uint16_t startI = mainseg.start;
|
|
|
|
uint16_t stopI = mainseg.stop;
|
|
|
|
uint8_t grpI = mainseg.grouping;
|
|
|
|
uint16_t spcI = mainseg.spacing;
|
2019-12-04 02:01:47 +01:00
|
|
|
pos = req.indexOf("&S="); //segment start
|
2019-12-01 01:42:52 +01:00
|
|
|
if (pos > 0) {
|
|
|
|
startI = getNumVal(&req, pos);
|
|
|
|
}
|
|
|
|
pos = req.indexOf("S2="); //segment stop
|
|
|
|
if (pos > 0) {
|
|
|
|
stopI = getNumVal(&req, pos);
|
|
|
|
}
|
2020-01-19 01:07:38 +01:00
|
|
|
pos = req.indexOf("GP="); //segment grouping
|
|
|
|
if (pos > 0) {
|
|
|
|
grpI = getNumVal(&req, pos);
|
|
|
|
if (grpI == 0) grpI = 1;
|
|
|
|
}
|
|
|
|
pos = req.indexOf("SP="); //segment spacing
|
|
|
|
if (pos > 0) {
|
|
|
|
spcI = getNumVal(&req, pos);
|
|
|
|
}
|
|
|
|
strip.setSegment(main, startI, stopI, grpI, spcI);
|
2019-12-01 01:42:52 +01:00
|
|
|
|
|
|
|
main = strip.getMainSegmentId();
|
|
|
|
|
2020-02-09 16:11:38 +01:00
|
|
|
//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);
|
|
|
|
|
|
|
|
//preset cycle
|
|
|
|
pos = req.indexOf("CY=");
|
|
|
|
if (pos > 0)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
if (v > 49) presetCycleTime = v;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos = req.indexOf("PA="); //apply brightness from preset
|
|
|
|
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');
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
//apply preset
|
|
|
|
if (updateVal(&req, "PL=", &presetCycCurr, presetCycleMin, presetCycleMax)) {
|
|
|
|
applyPreset(presetCycCurr, presetApplyBri, presetApplyCol, presetApplyFx);
|
|
|
|
}
|
|
|
|
|
2019-02-22 22:53:33 +01:00
|
|
|
//set brightness
|
|
|
|
updateVal(&req, "&A=", &bri);
|
|
|
|
|
|
|
|
//set colors
|
|
|
|
updateVal(&req, "&R=", &col[0]);
|
|
|
|
updateVal(&req, "&G=", &col[1]);
|
|
|
|
updateVal(&req, "&B=", &col[2]);
|
|
|
|
updateVal(&req, "&W=", &col[3]);
|
|
|
|
updateVal(&req, "R2=", &colSec[0]);
|
|
|
|
updateVal(&req, "G2=", &colSec[1]);
|
|
|
|
updateVal(&req, "B2=", &colSec[2]);
|
|
|
|
updateVal(&req, "W2=", &colSec[3]);
|
2018-02-28 00:27:10 +01:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//set hue
|
|
|
|
pos = req.indexOf("HU=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
uint16_t temphue = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
byte tempsat = 255;
|
|
|
|
pos = req.indexOf("SA=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
tempsat = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
|
|
|
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//set color from HEX or 32bit DEC
|
|
|
|
pos = req.indexOf("CL=");
|
|
|
|
if (pos > 0) {
|
2019-02-05 21:53:39 +01:00
|
|
|
colorFromDecOrHexString(col, (char*)req.substring(pos + 3).c_str());
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
|
|
|
pos = req.indexOf("C2=");
|
|
|
|
if (pos > 0) {
|
2019-02-05 21:53:39 +01:00
|
|
|
colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str());
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//set to random hue SR=0->1st SR=1->2nd
|
|
|
|
pos = req.indexOf("SR");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
_setRandomColor(getNumVal(&req, pos));
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//swap 2nd & 1st
|
|
|
|
pos = req.indexOf("SC");
|
|
|
|
if (pos > 0) {
|
2019-02-05 21:53:39 +01:00
|
|
|
byte temp;
|
|
|
|
for (uint8_t i=0; i<4; i++)
|
2018-11-09 17:00:36 +01:00
|
|
|
{
|
2019-02-05 21:53:39 +01:00
|
|
|
temp = col[i];
|
2018-11-09 17:00:36 +01:00
|
|
|
col[i] = colSec[i];
|
2019-02-05 21:53:39 +01:00
|
|
|
colSec[i] = temp;
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-22 22:53:33 +01:00
|
|
|
//set effect parameters
|
|
|
|
if (updateVal(&req, "FX=", &effectCurrent, 0, strip.getModeCount()-1)) presetCyclingEnabled = false;
|
|
|
|
updateVal(&req, "SX=", &effectSpeed);
|
|
|
|
updateVal(&req, "IX=", &effectIntensity);
|
|
|
|
updateVal(&req, "FP=", &effectPalette, 0, strip.getPaletteCount()-1);
|
2018-11-09 17:00:36 +01:00
|
|
|
|
|
|
|
//set advanced overlay
|
|
|
|
pos = req.indexOf("OL=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
overlayCurrent = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2018-09-04 15:51:38 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//apply macro
|
|
|
|
pos = req.indexOf("&M=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
applyMacro(getNumVal(&req, pos));
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//toggle send UDP direct notifications
|
2019-02-22 22:53:33 +01:00
|
|
|
pos = req.indexOf("SN=");
|
|
|
|
if (pos > 0) notifyDirect = (req.charAt(pos+3) != '0');
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//toggle receive UDP direct notifications
|
2019-02-22 22:53:33 +01:00
|
|
|
pos = req.indexOf("RN=");
|
|
|
|
if (pos > 0) receiveNotifications = (req.charAt(pos+3) != '0');
|
2019-03-09 14:48:13 +01:00
|
|
|
|
|
|
|
//receive live data via UDP/Hyperion
|
|
|
|
pos = req.indexOf("RD=");
|
|
|
|
if (pos > 0) receiveDirect = (req.charAt(pos+3) != '0');
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//toggle nightlight mode
|
|
|
|
bool aNlDef = false;
|
|
|
|
if (req.indexOf("&ND") > 0) aNlDef = true;
|
|
|
|
pos = req.indexOf("NL=");
|
|
|
|
if (pos > 0)
|
|
|
|
{
|
2019-02-22 22:53:33 +01:00
|
|
|
if (req.charAt(pos+3) == '0')
|
2018-11-09 17:00:36 +01:00
|
|
|
{
|
|
|
|
nightlightActive = false;
|
|
|
|
bri = briT;
|
|
|
|
} else {
|
2018-04-15 15:27:54 +02:00
|
|
|
nightlightActive = true;
|
2018-11-25 00:00:02 +01:00
|
|
|
if (!aNlDef) nightlightDelayMins = getNumVal(&req, pos);
|
2018-04-15 15:27:54 +02:00
|
|
|
nightlightStartTime = millis();
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
|
|
|
} else if (aNlDef)
|
|
|
|
{
|
|
|
|
nightlightActive = true;
|
|
|
|
nightlightStartTime = millis();
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//set nightlight target brightness
|
|
|
|
pos = req.indexOf("NT=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
nightlightTargetBri = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
nightlightActiveOld = false; //re-init
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//toggle nightlight fade
|
2019-02-22 22:53:33 +01:00
|
|
|
pos = req.indexOf("NF=");
|
|
|
|
if (pos > 0)
|
2018-11-09 17:00:36 +01:00
|
|
|
{
|
2019-02-22 22:53:33 +01:00
|
|
|
nightlightFade = (req.charAt(pos+3) != '0');
|
2020-01-08 12:00:25 +01:00
|
|
|
nightlightColorFade = (req.charAt(pos+3) == '2'); //NighLightColorFade can only be enabled via API or Macro with "NF=2"
|
2018-11-09 17:00:36 +01:00
|
|
|
nightlightActiveOld = false; //re-init
|
|
|
|
}
|
2019-02-25 19:14:13 +01:00
|
|
|
|
|
|
|
#if AUXPIN >= 0
|
2018-11-09 17:00:36 +01:00
|
|
|
//toggle general purpose output
|
|
|
|
pos = req.indexOf("AX=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
auxTime = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
auxActive = true;
|
|
|
|
if (auxTime == 0) auxActive = false;
|
|
|
|
}
|
2019-02-25 19:14:13 +01:00
|
|
|
#endif
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
pos = req.indexOf("TT=");
|
2019-02-22 22:53:33 +01:00
|
|
|
if (pos > 0) transitionDelay = getNumVal(&req, pos);
|
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//main toggle on/off
|
|
|
|
pos = req.indexOf("&T=");
|
|
|
|
if (pos > 0) {
|
|
|
|
nightlightActive = false; //always disable nightlight when toggling
|
2018-11-25 00:00:02 +01:00
|
|
|
switch (getNumVal(&req, pos))
|
2018-11-09 17:00:36 +01:00
|
|
|
{
|
|
|
|
case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
|
|
|
|
case 1: bri = briLast; break; //on
|
2018-11-22 00:09:30 +01:00
|
|
|
default: toggleOnOff(); //toggle
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
|
|
|
}
|
2019-03-01 17:10:42 +01:00
|
|
|
|
|
|
|
//Segment reverse
|
2019-03-06 21:31:12 +01:00
|
|
|
pos = req.indexOf("RV=");
|
2019-12-01 01:42:52 +01:00
|
|
|
if (pos > 0) strip.getSegment(main).setOption(1, req.charAt(pos+3) != '0');
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//deactivate nightlight if target brightness is reached
|
|
|
|
if (bri == nightlightTargetBri) nightlightActive = false;
|
|
|
|
//set time (unix timestamp)
|
|
|
|
pos = req.indexOf("ST=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
setTime(getNumVal(&req, pos));
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//set countdown goal (unix timestamp)
|
|
|
|
pos = req.indexOf("CT=");
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
countdownTime = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
if (countdownTime - now() > 0) countdownOverTriggered = false;
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//cronixie
|
2019-03-01 17:10:42 +01:00
|
|
|
#ifndef WLED_DISABLE_CRONIXIE
|
2020-01-01 01:04:54 +01:00
|
|
|
//mode, 1 countdown
|
|
|
|
pos = req.indexOf("NM=");
|
|
|
|
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
|
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
pos = req.indexOf("NX="); //sets digits to code
|
|
|
|
if (pos > 0) {
|
2019-11-13 01:20:14 +01:00
|
|
|
strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6);
|
2018-11-09 17:00:36 +01:00
|
|
|
setCronixie();
|
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-12-04 02:01:47 +01:00
|
|
|
pos = req.indexOf("NB=");
|
|
|
|
if (pos > 0) //sets backlight
|
2018-11-09 17:00:36 +01:00
|
|
|
{
|
2019-12-04 02:01:47 +01:00
|
|
|
presetApplyFx = (req.charAt(pos+3) != '0');
|
2018-11-09 17:00:36 +01:00
|
|
|
if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight);
|
|
|
|
overlayRefreshedTime = 0;
|
|
|
|
}
|
2019-03-01 17:10:42 +01:00
|
|
|
#endif
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
pos = req.indexOf("U0="); //user var 0
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
userVar0 = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
pos = req.indexOf("U1="); //user var 1
|
|
|
|
if (pos > 0) {
|
2018-11-25 00:00:02 +01:00
|
|
|
userVar1 = getNumVal(&req, pos);
|
2018-11-09 17:00:36 +01:00
|
|
|
}
|
|
|
|
//you can add more if you need
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
//internal call, does not send XML response
|
|
|
|
pos = req.indexOf("IN");
|
2019-12-04 02:01:47 +01:00
|
|
|
if (pos < 1) XML_response(request);
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2019-02-22 22:53:33 +01:00
|
|
|
pos = req.indexOf("&NN"); //do not send UDP notifications this time
|
2020-02-22 16:17:32 +01:00
|
|
|
colorUpdated((pos > 0) ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
2019-08-17 12:27:06 +02:00
|
|
|
|
2018-11-09 17:00:36 +01:00
|
|
|
return true;
|
2016-11-19 19:39:17 +01:00
|
|
|
}
|