2020-04-10 10:30:08 +00:00
# include "wled.h"
2016-12-30 23:38:51 +00:00
/*
* Receives client input
*/
2018-09-17 09:15:08 +00:00
//called upon POST settings form submit
2019-02-15 23:21:22 +00:00
void handleSettingsSet ( AsyncWebServerRequest * request , byte subPage )
2016-11-19 18:39:17 +00:00
{
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_PINREQ )
2022-03-01 22:37:28 +00:00
{
2023-06-14 09:53:39 +00:00
checkSettingsPIN ( request - > arg ( F ( " PIN " ) ) . c_str ( ) ) ;
2022-03-01 22:37:28 +00:00
return ;
}
2020-02-23 21:24:51 +00:00
2022-05-08 08:50:48 +00:00
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 7: DMX 8: usermods 9: N/A 10: 2D
2023-06-15 21:58:22 +00:00
if ( subPage < 1 | | subPage > 10 | | ! correctPIN ) return ;
2022-03-01 22:37:28 +00:00
2018-02-20 21:29:48 +00:00
//WIFI SETTINGS
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_WIFI )
2016-11-19 18:39:17 +00:00
{
2020-09-19 23:18:31 +00:00
strlcpy ( clientSSID , request - > arg ( F ( " CS " ) ) . c_str ( ) , 33 ) ;
2019-12-10 23:59:15 +00:00
2020-09-19 23:18:31 +00:00
if ( ! isAsterisksOnly ( request - > arg ( F ( " CP " ) ) . c_str ( ) , 65 ) ) strlcpy ( clientPass , request - > arg ( F ( " CP " ) ) . c_str ( ) , 65 ) ;
2018-09-17 09:15:08 +00:00
2020-09-19 23:18:31 +00:00
strlcpy ( cmDNS , request - > arg ( F ( " CM " ) ) . c_str ( ) , 33 ) ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
apBehavior = request - > arg ( F ( " AB " ) ) . toInt ( ) ;
strlcpy ( apSSID , request - > arg ( F ( " AS " ) ) . c_str ( ) , 33 ) ;
apHide = request - > hasArg ( F ( " AH " ) ) ;
int passlen = request - > arg ( F ( " AP " ) ) . length ( ) ;
if ( passlen = = 0 | | ( passlen > 7 & & ! isAsterisksOnly ( request - > arg ( F ( " AP " ) ) . c_str ( ) , 65 ) ) ) strlcpy ( apPass , request - > arg ( F ( " AP " ) ) . c_str ( ) , 65 ) ;
int t = request - > arg ( F ( " AC " ) ) . toInt ( ) ; if ( t > 0 & & t < 14 ) apChannel = t ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
noWifiSleep = request - > hasArg ( F ( " WS " ) ) ;
2020-02-20 16:08:56 +00:00
2023-06-22 08:06:19 +00:00
# ifndef WLED_DISABLE_ESPNOW
enable_espnow_remote = request - > hasArg ( F ( " RE " ) ) ;
strlcpy ( linked_remote , request - > arg ( F ( " RMAC " ) ) . c_str ( ) , 13 ) ;
//Normalize MAC format to lowercase
strlcpy ( linked_remote , strlwr ( linked_remote ) , 13 ) ;
# endif
2021-01-15 09:37:45 +00:00
# ifdef WLED_USE_ETHERNET
ethernetType = request - > arg ( F ( " ETH " ) ) . toInt ( ) ;
2021-08-23 12:14:48 +00:00
WLED : : instance ( ) . initEthernet ( ) ;
2021-01-15 09:37:45 +00:00
# endif
2018-09-17 09:15:08 +00:00
char k [ 3 ] ; k [ 2 ] = 0 ;
2018-07-21 21:21:07 +00:00
for ( int i = 0 ; i < 4 ; i + + )
2018-01-27 22:28:20 +00:00
{
2018-09-17 09:15:08 +00:00
k [ 1 ] = i + 48 ; //ascii 0,1,2,3
2019-08-17 10:27:06 +00:00
2018-07-21 21:21:07 +00:00
k [ 0 ] = ' I ' ; //static IP
2019-02-15 23:21:22 +00:00
staticIP [ i ] = request - > arg ( k ) . toInt ( ) ;
2019-08-17 10:27:06 +00:00
2018-07-21 21:21:07 +00:00
k [ 0 ] = ' G ' ; //gateway
2019-02-15 23:21:22 +00:00
staticGateway [ i ] = request - > arg ( k ) . toInt ( ) ;
2019-08-17 10:27:06 +00:00
2018-07-21 21:21:07 +00:00
k [ 0 ] = ' S ' ; //subnet
2019-02-15 23:21:22 +00:00
staticSubnet [ i ] = request - > arg ( k ) . toInt ( ) ;
2016-11-27 15:45:54 +00:00
}
2016-11-19 18:39:17 +00:00
}
2018-02-20 21:29:48 +00:00
//LED SETTINGS
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_LEDS )
2016-12-11 19:11:14 +00:00
{
2021-01-21 00:21:16 +00:00
int t = 0 ;
2021-08-23 12:14:48 +00:00
if ( rlyPin > = 0 & & pinManager . isPinAllocated ( rlyPin , PinOwner : : Relay ) ) {
pinManager . deallocatePin ( rlyPin , PinOwner : : Relay ) ;
}
if ( irPin > = 0 & & pinManager . isPinAllocated ( irPin , PinOwner : : IR ) ) {
pinManager . deallocatePin ( irPin , PinOwner : : IR ) ;
}
for ( uint8_t s = 0 ; s < WLED_MAX_BUTTONS ; s + + ) {
if ( btnPin [ s ] > = 0 & & pinManager . isPinAllocated ( btnPin [ s ] , PinOwner : : Button ) ) {
pinManager . deallocatePin ( btnPin [ s ] , PinOwner : : Button ) ;
}
}
2021-01-16 23:20:31 +00:00
2022-04-30 10:45:38 +00:00
uint8_t colorOrder , type , skip , awmode , channelSwap ;
2021-01-25 23:19:41 +00:00
uint16_t length , start ;
2021-02-24 19:23:32 +00:00
uint8_t pins [ 5 ] = { 255 , 255 , 255 , 255 , 255 } ;
2021-01-21 00:21:16 +00:00
2021-09-10 23:17:42 +00:00
autoSegments = request - > hasArg ( F ( " MS " ) ) ;
2021-11-24 10:02:25 +00:00
correctWB = request - > hasArg ( F ( " CCT " ) ) ;
2021-11-26 19:18:38 +00:00
cctFromRgb = request - > hasArg ( F ( " CR " ) ) ;
2022-03-08 01:16:33 +00:00
strip . cctBlending = request - > arg ( F ( " CB " ) ) . toInt ( ) ;
Bus : : setCCTBlend ( strip . cctBlending ) ;
2023-02-14 00:33:06 +00:00
Bus : : setGlobalAWMode ( request - > arg ( F ( " AW " ) ) . toInt ( ) ) ;
2022-03-08 01:16:33 +00:00
strip . setTargetFps ( request - > arg ( F ( " FR " ) ) . toInt ( ) ) ;
2023-06-26 16:16:38 +00:00
strip . useGlobalLedBuffer = request - > hasArg ( F ( " LD " ) ) ;
2021-09-10 23:17:42 +00:00
2022-07-01 12:10:32 +00:00
bool busesChanged = false ;
2022-12-31 16:06:18 +00:00
for ( uint8_t s = 0 ; s < WLED_MAX_BUSSES + WLED_MIN_VIRTUAL_BUSSES ; s + + ) {
2021-01-30 19:51:36 +00:00
char lp [ 4 ] = " L0 " ; lp [ 2 ] = 48 + s ; lp [ 3 ] = 0 ; //ascii 0-9 //strip data pin
char lc [ 4 ] = " LC " ; lc [ 2 ] = 48 + s ; lc [ 3 ] = 0 ; //strip length
char co [ 4 ] = " CO " ; co [ 2 ] = 48 + s ; co [ 3 ] = 0 ; //strip color order
char lt [ 4 ] = " LT " ; lt [ 2 ] = 48 + s ; lt [ 3 ] = 0 ; //strip type
char ls [ 4 ] = " LS " ; ls [ 2 ] = 48 + s ; ls [ 3 ] = 0 ; //strip start LED
char cv [ 4 ] = " CV " ; cv [ 2 ] = 48 + s ; cv [ 3 ] = 0 ; //strip reverse
2022-03-16 00:45:07 +00:00
char sl [ 4 ] = " SL " ; sl [ 2 ] = 48 + s ; sl [ 3 ] = 0 ; //skip first N LEDs
2021-10-07 20:57:07 +00:00
char rf [ 4 ] = " RF " ; rf [ 2 ] = 48 + s ; rf [ 3 ] = 0 ; //refresh required
2022-03-09 12:39:51 +00:00
char aw [ 4 ] = " AW " ; aw [ 2 ] = 48 + s ; aw [ 3 ] = 0 ; //auto white mode
2022-04-30 10:45:38 +00:00
char wo [ 4 ] = " WO " ; wo [ 2 ] = 48 + s ; wo [ 3 ] = 0 ; //channel swap
2023-04-27 22:27:19 +00:00
char sp [ 4 ] = " SP " ; sp [ 2 ] = 48 + s ; sp [ 3 ] = 0 ; //bus clock speed (DotStar & PWM)
2021-01-30 19:51:36 +00:00
if ( ! request - > hasArg ( lp ) ) {
2022-07-01 12:10:32 +00:00
DEBUG_PRINT ( F ( " No data for " ) ) ;
DEBUG_PRINTLN ( s ) ;
break ;
2021-01-16 23:20:31 +00:00
}
2021-02-24 13:49:39 +00:00
for ( uint8_t i = 0 ; i < 5 ; i + + ) {
lp [ 1 ] = 48 + i ;
if ( ! request - > hasArg ( lp ) ) break ;
pins [ i ] = ( request - > arg ( lp ) . length ( ) > 0 ) ? request - > arg ( lp ) . toInt ( ) : 255 ;
2021-01-30 19:51:36 +00:00
}
type = request - > arg ( lt ) . toInt ( ) ;
2021-10-07 20:57:07 +00:00
type | = request - > hasArg ( rf ) < < 7 ; // off refresh override
2022-03-16 00:45:07 +00:00
skip = request - > arg ( sl ) . toInt ( ) ;
2021-02-25 08:54:10 +00:00
colorOrder = request - > arg ( co ) . toInt ( ) ;
start = ( request - > hasArg ( ls ) ) ? request - > arg ( ls ) . toInt ( ) : t ;
2021-01-30 19:51:36 +00:00
if ( request - > hasArg ( lc ) & & request - > arg ( lc ) . toInt ( ) > 0 ) {
2021-02-25 08:54:10 +00:00
t + = length = request - > arg ( lc ) . toInt ( ) ;
2021-01-30 19:51:36 +00:00
} else {
break ; // no parameter
}
2022-03-09 12:39:51 +00:00
awmode = request - > arg ( aw ) . toInt ( ) ;
2023-04-27 22:27:19 +00:00
uint16_t freqHz = request - > arg ( sp ) . toInt ( ) ;
if ( type > TYPE_ONOFF & & type < 49 ) {
switch ( freqHz ) {
case 0 : freqHz = WLED_PWM_FREQ / 3 ; break ;
case 1 : freqHz = WLED_PWM_FREQ / 2 ; break ;
default :
case 2 : freqHz = WLED_PWM_FREQ ; break ;
case 3 : freqHz = WLED_PWM_FREQ * 2 ; break ;
case 4 : freqHz = WLED_PWM_FREQ * 3 ; break ;
}
} else if ( type > 48 & & type < 64 ) {
switch ( freqHz ) {
default :
case 0 : freqHz = 1000 ; break ;
case 1 : freqHz = 2000 ; break ;
case 2 : freqHz = 5000 ; break ;
case 3 : freqHz = 10000 ; break ;
case 4 : freqHz = 20000 ; break ;
}
} else {
freqHz = 0 ;
}
2022-04-30 10:45:38 +00:00
channelSwap = ( type = = TYPE_SK6812_RGBW | | type = = TYPE_TM1814 ) ? request - > arg ( wo ) . toInt ( ) : 0 ;
2021-03-03 21:04:24 +00:00
// actual finalization is done in WLED::loop() (removing old busses and adding new)
2022-07-01 12:10:32 +00:00
// this may happen even before this loop is finished so we do "doInitBusses" after the loop
2021-01-30 19:51:36 +00:00
if ( busConfigs [ s ] ! = nullptr ) delete busConfigs [ s ] ;
2023-04-27 22:27:19 +00:00
busConfigs [ s ] = new BusConfig ( type , pins , start , length , colorOrder | ( channelSwap < < 4 ) , request - > hasArg ( cv ) , skip , awmode , freqHz ) ;
2022-07-01 12:10:32 +00:00
busesChanged = true ;
2021-01-16 23:20:31 +00:00
}
2022-07-01 12:10:32 +00:00
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
2021-01-16 23:20:31 +00:00
2021-12-31 20:35:27 +00:00
ColorOrderMap com = { } ;
for ( uint8_t s = 0 ; s < WLED_MAX_COLOR_ORDER_MAPPINGS ; s + + ) {
char xs [ 4 ] = " XS " ; xs [ 2 ] = 48 + s ; xs [ 3 ] = 0 ; //start LED
char xc [ 4 ] = " XC " ; xc [ 2 ] = 48 + s ; xc [ 3 ] = 0 ; //strip length
char xo [ 4 ] = " XO " ; xo [ 2 ] = 48 + s ; xo [ 3 ] = 0 ; //color order
2022-01-13 15:06:01 +00:00
if ( request - > hasArg ( xs ) ) {
start = request - > arg ( xs ) . toInt ( ) ;
length = request - > arg ( xc ) . toInt ( ) ;
colorOrder = request - > arg ( xo ) . toInt ( ) ;
com . add ( start , length , colorOrder ) ;
}
2021-12-31 20:35:27 +00:00
}
busses . updateColorOrderMap ( com ) ;
2021-01-16 23:20:31 +00:00
// upate other pins
int hw_ir_pin = request - > arg ( F ( " IR " ) ) . toInt ( ) ;
2021-08-23 12:14:48 +00:00
if ( pinManager . allocatePin ( hw_ir_pin , false , PinOwner : : IR ) ) {
2021-01-16 23:20:31 +00:00
irPin = hw_ir_pin ;
} else {
irPin = - 1 ;
}
2021-05-19 16:39:16 +00:00
irEnabled = request - > arg ( F ( " IT " ) ) . toInt ( ) ;
2022-02-06 23:40:45 +00:00
irApplyToAllSelected = ! request - > hasArg ( F ( " MSO " ) ) ;
2021-01-16 23:20:31 +00:00
int hw_rly_pin = request - > arg ( F ( " RL " ) ) . toInt ( ) ;
2021-08-23 12:14:48 +00:00
if ( pinManager . allocatePin ( hw_rly_pin , true , PinOwner : : Relay ) ) {
2021-01-16 23:20:31 +00:00
rlyPin = hw_rly_pin ;
} else {
rlyPin = - 1 ;
}
rlyMde = ( bool ) request - > hasArg ( F ( " RM " ) ) ;
2022-11-26 22:56:55 +00:00
disablePullUp = ( bool ) request - > hasArg ( F ( " IP " ) ) ;
2021-05-19 16:39:16 +00:00
for ( uint8_t i = 0 ; i < WLED_MAX_BUTTONS ; i + + ) {
2021-11-28 10:24:58 +00:00
char bt [ 4 ] = " BT " ; bt [ 2 ] = ( i < 10 ? 48 : 55 ) + i ; bt [ 3 ] = 0 ; // button pin (use A,B,C,... if WLED_MAX_BUTTONS>10)
char be [ 4 ] = " BE " ; be [ 2 ] = ( i < 10 ? 48 : 55 ) + i ; be [ 3 ] = 0 ; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10)
2021-05-20 04:45:02 +00:00
int hw_btn_pin = request - > arg ( bt ) . toInt ( ) ;
2021-08-23 12:14:48 +00:00
if ( pinManager . allocatePin ( hw_btn_pin , false , PinOwner : : Button ) ) {
2021-05-20 04:45:02 +00:00
btnPin [ i ] = hw_btn_pin ;
buttonType [ i ] = request - > arg ( be ) . toInt ( ) ;
2022-12-10 18:16:02 +00:00
# ifdef ARDUINO_ARCH_ESP32
// ESP32 only: check that analog button pin is a valid ADC gpio
2023-01-06 08:24:29 +00:00
if ( ( ( buttonType [ i ] = = BTN_TYPE_ANALOG ) | | ( buttonType [ i ] = = BTN_TYPE_ANALOG_INVERTED ) ) & & ( digitalPinToAnalogChannel ( btnPin [ i ] ) < 0 ) )
2022-12-10 18:16:02 +00:00
{
// not an ADC analog pin
2022-12-10 20:03:58 +00:00
if ( btnPin [ i ] > = 0 ) DEBUG_PRINTF ( " PIN ALLOC error: GPIO%d for analog button #%d is not an analog pin! \n " , btnPin [ i ] , i ) ;
2022-12-10 18:16:02 +00:00
btnPin [ i ] = - 1 ;
pinManager . deallocatePin ( hw_btn_pin , PinOwner : : Button ) ;
2023-01-06 08:24:29 +00:00
}
else
2022-12-10 18:16:02 +00:00
# endif
{
if ( disablePullUp ) {
pinMode ( btnPin [ i ] , INPUT ) ;
} else {
# ifdef ESP32
pinMode ( btnPin [ i ] , buttonType [ i ] = = BTN_TYPE_PUSH_ACT_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP ) ;
# else
pinMode ( btnPin [ i ] , INPUT_PULLUP ) ;
# endif
}
2022-11-26 22:56:55 +00:00
}
2021-05-20 04:45:02 +00:00
} else {
btnPin [ i ] = - 1 ;
buttonType [ i ] = BTN_TYPE_NONE ;
}
2021-01-16 23:20:31 +00:00
}
2021-05-19 18:23:35 +00:00
touchThreshold = request - > arg ( F ( " TT " ) ) . toInt ( ) ;
2021-01-16 23:20:31 +00:00
2020-09-19 23:18:31 +00:00
strip . ablMilliampsMax = request - > arg ( F ( " MA " ) ) . toInt ( ) ;
strip . milliampsPerLed = request - > arg ( F ( " LA " ) ) . toInt ( ) ;
2023-01-06 08:24:29 +00:00
2020-09-19 23:18:31 +00:00
briS = request - > arg ( F ( " CA " ) ) . toInt ( ) ;
2019-12-04 01:01:47 +00:00
2020-09-19 23:18:31 +00:00
turnOnAtBoot = request - > hasArg ( F ( " BO " ) ) ;
t = request - > arg ( F ( " BP " ) ) . toInt ( ) ;
2021-01-13 10:24:27 +00:00
if ( t < = 250 ) bootPreset = t ;
2022-09-04 18:17:05 +00:00
gammaCorrectBri = request - > hasArg ( F ( " GB " ) ) ;
gammaCorrectCol = request - > hasArg ( F ( " GC " ) ) ;
2023-02-12 12:18:30 +00:00
gammaCorrectVal = request - > arg ( F ( " GV " ) ) . toFloat ( ) ;
if ( gammaCorrectVal > 1.0f & & gammaCorrectVal < = 3 )
2023-06-10 18:43:27 +00:00
NeoGammaWLEDMethod : : calcGammaTable ( gammaCorrectVal ) ;
2023-02-12 12:18:30 +00:00
else {
gammaCorrectVal = 1.0f ; // no gamma correction
gammaCorrectBri = false ;
gammaCorrectCol = false ;
}
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
fadeTransition = request - > hasArg ( F ( " TF " ) ) ;
t = request - > arg ( F ( " TD " ) ) . toInt ( ) ;
2022-07-29 10:15:56 +00:00
if ( t > = 0 ) transitionDelayDefault = t ;
2020-09-19 23:18:31 +00:00
strip . paletteFade = request - > hasArg ( F ( " PF " ) ) ;
2023-03-25 20:28:30 +00:00
t = request - > arg ( F ( " TP " ) ) . toInt ( ) ;
randomPaletteChangeTime = MIN ( 255 , MAX ( 1 , t ) ) ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
nightlightTargetBri = request - > arg ( F ( " TB " ) ) . toInt ( ) ;
t = request - > arg ( F ( " TL " ) ) . toInt ( ) ;
2018-11-21 23:09:30 +00:00
if ( t > 0 ) nightlightDelayMinsDefault = t ;
2019-09-19 19:15:20 +00:00
nightlightDelayMins = nightlightDelayMinsDefault ;
2020-09-19 23:18:31 +00:00
nightlightMode = request - > arg ( F ( " TW " ) ) . toInt ( ) ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " PB " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > = 0 & & t < 4 ) strip . paletteBlend = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " BF " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > 0 ) briMultiplier = t ;
2022-07-01 12:10:32 +00:00
doInitBusses = busesChanged ;
2016-12-11 19:11:14 +00:00
}
2018-02-20 21:29:48 +00:00
//UI
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_UI )
2016-11-19 18:39:17 +00:00
{
2020-09-19 23:18:31 +00:00
strlcpy ( serverDescription , request - > arg ( F ( " DS " ) ) . c_str ( ) , 33 ) ;
syncToggleReceive = request - > hasArg ( F ( " ST " ) ) ;
2022-03-31 19:44:11 +00:00
# ifdef WLED_ENABLE_SIMPLE_UI
2021-08-10 19:52:07 +00:00
if ( simplifiedUI ^ request - > hasArg ( F ( " SU " ) ) ) {
// UI selection changed, invalidate browser cache
cacheInvalidate + + ;
}
2021-08-10 15:11:17 +00:00
simplifiedUI = request - > hasArg ( F ( " SU " ) ) ;
# endif
2023-02-12 12:18:30 +00:00
DEBUG_PRINTLN ( F ( " Enumerating ledmaps " ) ) ;
enumerateLedmaps ( ) ;
DEBUG_PRINTLN ( F ( " Loading custom palettes " ) ) ;
strip . loadCustomPalettes ( ) ; // (re)load all custom palettes
2016-11-19 18:39:17 +00:00
}
2018-02-20 21:29:48 +00:00
//SYNC
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_SYNC )
2017-02-24 22:21:48 +00:00
{
2020-09-19 23:18:31 +00:00
int t = request - > arg ( F ( " UP " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > 0 ) udpPort = t ;
2020-09-27 09:43:28 +00:00
t = request - > arg ( F ( " U2 " ) ) . toInt ( ) ;
if ( t > 0 ) udpPort2 = t ;
2021-08-21 10:22:26 +00:00
2021-08-24 22:36:31 +00:00
syncGroups = request - > arg ( F ( " GS " ) ) . toInt ( ) ;
receiveGroups = request - > arg ( F ( " GR " ) ) . toInt ( ) ;
2021-08-21 10:22:26 +00:00
2020-09-19 23:18:31 +00:00
receiveNotificationBrightness = request - > hasArg ( F ( " RB " ) ) ;
receiveNotificationColor = request - > hasArg ( F ( " RC " ) ) ;
receiveNotificationEffects = request - > hasArg ( F ( " RX " ) ) ;
2021-12-17 10:22:20 +00:00
receiveSegmentOptions = request - > hasArg ( F ( " SO " ) ) ;
2022-02-20 21:24:11 +00:00
receiveSegmentBounds = request - > hasArg ( F ( " SG " ) ) ;
2021-12-17 10:22:20 +00:00
receiveNotifications = ( receiveNotificationBrightness | | receiveNotificationColor | | receiveNotificationEffects | | receiveSegmentOptions ) ;
2020-09-19 23:18:31 +00:00
notifyDirectDefault = request - > hasArg ( F ( " SD " ) ) ;
2018-02-20 21:29:48 +00:00
notifyDirect = notifyDirectDefault ;
2020-09-19 23:18:31 +00:00
notifyButton = request - > hasArg ( F ( " SB " ) ) ;
notifyAlexa = request - > hasArg ( F ( " SA " ) ) ;
notifyHue = request - > hasArg ( F ( " SH " ) ) ;
notifyMacro = request - > hasArg ( F ( " SM " ) ) ;
2022-10-18 23:31:23 +00:00
t = request - > arg ( F ( " UR " ) ) . toInt ( ) ;
if ( ( t > = 0 ) & & ( t < 30 ) ) udpNumRetries = t ;
2020-09-19 23:18:31 +00:00
2021-03-13 21:04:37 +00:00
nodeListEnabled = request - > hasArg ( F ( " NL " ) ) ;
if ( ! nodeListEnabled ) Nodes . clear ( ) ;
nodeBroadcastEnabled = request - > hasArg ( F ( " NB " ) ) ;
2020-09-19 23:18:31 +00:00
receiveDirect = request - > hasArg ( F ( " RD " ) ) ;
2022-03-25 15:36:05 +00:00
useMainSegmentOnly = request - > hasArg ( F ( " MO " ) ) ;
2020-09-19 23:18:31 +00:00
e131SkipOutOfSequence = request - > hasArg ( F ( " ES " ) ) ;
e131Multicast = request - > hasArg ( F ( " EM " ) ) ;
t = request - > arg ( F ( " EP " ) ) . toInt ( ) ;
2020-04-12 22:42:27 +00:00
if ( t > 0 ) e131Port = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " EU " ) ) . toInt ( ) ;
2020-04-12 22:42:27 +00:00
if ( t > = 0 & & t < = 63999 ) e131Universe = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " DA " ) ) . toInt ( ) ;
2020-04-12 22:42:27 +00:00
if ( t > = 0 & & t < = 510 ) DMXAddress = t ;
2022-11-19 13:10:40 +00:00
t = request - > arg ( F ( " XX " ) ) . toInt ( ) ;
if ( t > = 0 & & t < = 150 ) DMXSegmentSpacing = t ;
2023-02-21 16:13:15 +00:00
t = request - > arg ( F ( " PY " ) ) . toInt ( ) ;
if ( t > = 0 & & t < = 200 ) e131Priority = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " DM " ) ) . toInt ( ) ;
2022-11-19 13:10:40 +00:00
if ( t > = DMX_MODE_DISABLED & & t < = DMX_MODE_PRESET ) DMXMode = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " ET " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > 99 & & t < = 65000 ) realtimeTimeoutMs = t ;
2020-09-19 23:18:31 +00:00
arlsForceMaxBri = request - > hasArg ( F ( " FB " ) ) ;
arlsDisableGammaCorrection = request - > hasArg ( F ( " RG " ) ) ;
t = request - > arg ( F ( " WO " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > = - 255 & & t < = 255 ) arlsOffset = t ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
alexaEnabled = request - > hasArg ( F ( " AL " ) ) ;
strlcpy ( alexaInvocationName , request - > arg ( F ( " AI " ) ) . c_str ( ) , 33 ) ;
2022-10-25 21:42:26 +00:00
t = request - > arg ( F ( " AP " ) ) . toInt ( ) ;
if ( t > = 0 & & t < = 9 ) alexaNumPresets = t ;
2019-08-17 10:27:06 +00:00
2019-12-10 23:59:15 +00:00
# ifdef WLED_ENABLE_MQTT
2020-09-19 23:18:31 +00:00
mqttEnabled = request - > hasArg ( F ( " MQ " ) ) ;
strlcpy ( mqttServer , request - > arg ( F ( " MS " ) ) . c_str ( ) , 33 ) ;
t = request - > arg ( F ( " MQPORT " ) ) . toInt ( ) ;
2019-08-18 16:14:17 +00:00
if ( t > 0 ) mqttPort = t ;
2020-09-19 23:18:31 +00:00
strlcpy ( mqttUser , request - > arg ( F ( " MQUSER " ) ) . c_str ( ) , 41 ) ;
2021-06-29 23:23:35 +00:00
if ( ! isAsterisksOnly ( request - > arg ( F ( " MQPASS " ) ) . c_str ( ) , 41 ) ) strlcpy ( mqttPass , request - > arg ( F ( " MQPASS " ) ) . c_str ( ) , 65 ) ;
2020-09-19 23:18:31 +00:00
strlcpy ( mqttClientID , request - > arg ( F ( " MQCID " ) ) . c_str ( ) , 41 ) ;
strlcpy ( mqttDeviceTopic , request - > arg ( F ( " MD " ) ) . c_str ( ) , 33 ) ;
strlcpy ( mqttGroupTopic , request - > arg ( F ( " MG " ) ) . c_str ( ) , 33 ) ;
2021-07-01 18:51:52 +00:00
buttonPublishMqtt = request - > hasArg ( F ( " BM " ) ) ;
2023-05-28 20:50:19 +00:00
retainMqttMsg = request - > hasArg ( F ( " RT " ) ) ;
2019-12-10 23:59:15 +00:00
# endif
2019-08-17 10:27:06 +00:00
2019-12-10 23:59:15 +00:00
# ifndef WLED_DISABLE_HUESYNC
2018-02-27 23:27:10 +00:00
for ( int i = 0 ; i < 4 ; i + + ) {
2018-03-14 18:05:51 +00:00
String a = " H " + String ( i ) ;
2019-02-15 23:21:22 +00:00
hueIP [ i ] = request - > arg ( a ) . toInt ( ) ;
2018-02-27 23:27:10 +00:00
}
2018-09-17 09:15:08 +00:00
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " HL " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > 0 ) huePollLightId = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " HI " ) ) . toInt ( ) ;
2018-09-17 09:15:08 +00:00
if ( t > 50 ) huePollIntervalMs = t ;
2020-09-19 23:18:31 +00:00
hueApplyOnOff = request - > hasArg ( F ( " HO " ) ) ;
hueApplyBri = request - > hasArg ( F ( " HB " ) ) ;
hueApplyColor = request - > hasArg ( F ( " HC " ) ) ;
huePollingEnabled = request - > hasArg ( F ( " HP " ) ) ;
2019-02-18 21:34:21 +00:00
hueStoreAllowed = true ;
reconnectHue ( ) ;
2019-12-10 23:59:15 +00:00
# endif
2022-02-01 19:02:46 +00:00
t = request - > arg ( F ( " BD " ) ) . toInt ( ) ;
if ( t > = 96 & & t < = 15000 ) serialBaud = t ;
updateBaudRate ( serialBaud * 100 ) ;
2017-02-24 22:21:48 +00:00
}
2018-02-20 21:29:48 +00:00
//TIME
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_TIME )
2017-02-24 22:21:48 +00:00
{
2020-09-19 23:18:31 +00:00
ntpEnabled = request - > hasArg ( F ( " NT " ) ) ;
strlcpy ( ntpServerName , request - > arg ( F ( " NS " ) ) . c_str ( ) , 33 ) ;
useAMPM = ! request - > hasArg ( F ( " CF " ) ) ;
currentTimezone = request - > arg ( F ( " TZ " ) ) . toInt ( ) ;
utcOffsetSecs = request - > arg ( F ( " UO " ) ) . toInt ( ) ;
2018-11-09 16:00:36 +00:00
//start ntp if not already connected
2019-10-18 11:26:39 +00:00
if ( ntpEnabled & & WLED_CONNECTED & & ! ntpConnected ) ntpConnected = ntpUdp . begin ( ntpLocalPort ) ;
2021-12-29 16:03:03 +00:00
ntpLastSyncTime = 0 ; // force new NTP query
2021-03-09 12:24:20 +00:00
2021-03-05 22:05:09 +00:00
longitude = request - > arg ( F ( " LN " ) ) . toFloat ( ) ;
latitude = request - > arg ( F ( " LT " ) ) . toFloat ( ) ;
2021-03-08 18:52:43 +00:00
// force a sunrise/sunset re-calculation
2023-01-06 08:24:29 +00:00
calculateSunriseAndSunset ( ) ;
2019-08-17 10:27:06 +00:00
2022-03-06 23:11:43 +00:00
overlayCurrent = request - > hasArg ( F ( " OL " ) ) ? 1 : 0 ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
overlayMin = request - > arg ( F ( " O1 " ) ) . toInt ( ) ;
overlayMax = request - > arg ( F ( " O2 " ) ) . toInt ( ) ;
analogClock12pixel = request - > arg ( F ( " OM " ) ) . toInt ( ) ;
analogClock5MinuteMarks = request - > hasArg ( F ( " O5 " ) ) ;
analogClockSecondsTrail = request - > hasArg ( F ( " OS " ) ) ;
countdownMode = request - > hasArg ( F ( " CE " ) ) ;
countdownYear = request - > arg ( F ( " CY " ) ) . toInt ( ) ;
countdownMonth = request - > arg ( F ( " CI " ) ) . toInt ( ) ;
countdownDay = request - > arg ( F ( " CD " ) ) . toInt ( ) ;
countdownHour = request - > arg ( F ( " CH " ) ) . toInt ( ) ;
countdownMin = request - > arg ( F ( " CM " ) ) . toInt ( ) ;
countdownSec = request - > arg ( F ( " CS " ) ) . toInt ( ) ;
2020-12-31 19:47:38 +00:00
setCountdown ( ) ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
macroAlexaOn = request - > arg ( F ( " A0 " ) ) . toInt ( ) ;
macroAlexaOff = request - > arg ( F ( " A1 " ) ) . toInt ( ) ;
macroCountdown = request - > arg ( F ( " MC " ) ) . toInt ( ) ;
macroNl = request - > arg ( F ( " MN " ) ) . toInt ( ) ;
2021-05-19 16:39:16 +00:00
for ( uint8_t i = 0 ; i < WLED_MAX_BUTTONS ; i + + ) {
2021-12-08 21:05:51 +00:00
char mp [ 4 ] = " MP " ; mp [ 2 ] = ( i < 10 ? 48 : 55 ) + i ; mp [ 3 ] = 0 ; // short
char ml [ 4 ] = " ML " ; ml [ 2 ] = ( i < 10 ? 48 : 55 ) + i ; ml [ 3 ] = 0 ; // long
char md [ 4 ] = " MD " ; md [ 2 ] = ( i < 10 ? 48 : 55 ) + i ; md [ 3 ] = 0 ; // double
2021-05-20 04:45:02 +00:00
//if (!request->hasArg(mp)) break;
macroButton [ i ] = request - > arg ( mp ) . toInt ( ) ; // these will default to 0 if not present
2021-05-19 16:39:16 +00:00
macroLongPress [ i ] = request - > arg ( ml ) . toInt ( ) ;
macroDoublePress [ i ] = request - > arg ( md ) . toInt ( ) ;
}
2018-09-22 20:49:24 +00:00
char k [ 3 ] ; k [ 2 ] = 0 ;
2021-12-25 17:46:43 +00:00
for ( int i = 0 ; i < 10 ; i + + ) {
2021-12-31 13:09:48 +00:00
k [ 1 ] = i + 48 ; //ascii 0,1,2,3,...
2018-09-22 20:49:24 +00:00
k [ 0 ] = ' H ' ; //timer hours
2019-02-15 23:21:22 +00:00
timerHours [ i ] = request - > arg ( k ) . toInt ( ) ;
2018-09-22 20:49:24 +00:00
k [ 0 ] = ' N ' ; //minutes
2019-02-15 23:21:22 +00:00
timerMinutes [ i ] = request - > arg ( k ) . toInt ( ) ;
2018-09-22 20:49:24 +00:00
k [ 0 ] = ' T ' ; //macros
2019-02-15 23:21:22 +00:00
timerMacro [ i ] = request - > arg ( k ) . toInt ( ) ;
2019-01-30 23:09:44 +00:00
k [ 0 ] = ' W ' ; //weekdays
2019-02-15 23:21:22 +00:00
timerWeekday [ i ] = request - > arg ( k ) . toInt ( ) ;
2021-12-25 17:46:43 +00:00
if ( i < 8 ) {
2023-02-14 13:28:10 +00:00
k [ 0 ] = ' M ' ; //start month
timerMonth [ i ] = request - > arg ( k ) . toInt ( ) & 0x0F ;
timerMonth [ i ] < < = 4 ;
k [ 0 ] = ' P ' ; //end month
timerMonth [ i ] + = ( request - > arg ( k ) . toInt ( ) & 0x0F ) ;
k [ 0 ] = ' D ' ; //start day
timerDay [ i ] = request - > arg ( k ) . toInt ( ) ;
k [ 0 ] = ' E ' ; //end day
timerDayEnd [ i ] = request - > arg ( k ) . toInt ( ) ;
2021-12-25 17:46:43 +00:00
}
2018-09-22 20:49:24 +00:00
}
2017-02-24 22:21:48 +00:00
}
2018-02-20 21:29:48 +00:00
//SECURITY
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_SEC )
2016-11-20 00:47:15 +00:00
{
2020-09-19 23:18:31 +00:00
if ( request - > hasArg ( F ( " RS " ) ) ) //complete factory reset
2016-11-20 00:47:15 +00:00
{
2020-11-06 21:12:48 +00:00
WLED_FS . format ( ) ;
2022-07-30 09:04:04 +00:00
# ifdef WLED_ADD_EEPROM_SUPPORT
2020-12-10 15:27:23 +00:00
clearEEPROM ( ) ;
2022-07-30 09:04:04 +00:00
# endif
2020-09-19 23:18:31 +00:00
serveMessage ( request , 200 , F ( " All Settings erased. " ) , F ( " Connect to WLED-AP to setup again " ) , 255 ) ;
2023-05-30 17:36:14 +00:00
doReboot = true ; // may reboot immediately on dual-core system (race condition) which is desireable in this case
2018-02-20 21:29:48 +00:00
}
2018-02-23 00:33:32 +00:00
2022-03-01 22:37:28 +00:00
if ( request - > hasArg ( F ( " PIN " ) ) ) {
const char * pin = request - > arg ( F ( " PIN " ) ) . c_str ( ) ;
2022-04-30 10:45:38 +00:00
uint8_t pinLen = strlen ( pin ) ;
if ( pinLen = = 4 | | pinLen = = 0 ) {
uint8_t numZeros = 0 ;
for ( uint8_t i = 0 ; i < pinLen ; i + + ) numZeros + = ( pin [ i ] = = ' 0 ' ) ;
if ( numZeros < pinLen | | pinLen = = 0 ) { // ignore 0000 input (placeholder)
strlcpy ( settingsPIN , pin , 5 ) ;
}
2022-03-01 22:37:28 +00:00
settingsPIN [ 4 ] = 0 ;
}
}
2018-02-23 00:33:32 +00:00
bool pwdCorrect = ! otaLock ; //always allow access if ota not locked
2020-09-19 23:18:31 +00:00
if ( request - > hasArg ( F ( " OP " ) ) )
2016-11-20 00:47:15 +00:00
{
2020-09-19 23:18:31 +00:00
if ( otaLock & & strcmp ( otaPass , request - > arg ( F ( " OP " ) ) . c_str ( ) ) = = 0 )
2018-02-20 21:29:48 +00:00
{
2022-04-30 10:45:38 +00:00
// brute force protection: do not unlock even if correct if last save was less than 3 seconds ago
2023-06-14 09:53:39 +00:00
if ( millis ( ) - lastEditTime > PIN_RETRY_COOLDOWN ) pwdCorrect = true ;
2018-02-23 00:33:32 +00:00
}
2020-09-19 23:18:31 +00:00
if ( ! otaLock & & request - > arg ( F ( " OP " ) ) . length ( ) > 0 )
2016-11-20 00:47:15 +00:00
{
2022-04-30 10:45:38 +00:00
strlcpy ( otaPass , request - > arg ( F ( " OP " ) ) . c_str ( ) , 33 ) ; // set new OTA password
2016-11-20 00:47:15 +00:00
}
}
2019-08-17 10:27:06 +00:00
2018-02-23 00:33:32 +00:00
if ( pwdCorrect ) //allow changes if correct pwd or no ota active
2018-02-20 21:29:48 +00:00
{
2020-09-19 23:18:31 +00:00
otaLock = request - > hasArg ( F ( " NO " ) ) ;
wifiLock = request - > hasArg ( F ( " OW " ) ) ;
aOtaEnabled = request - > hasArg ( F ( " AO " ) ) ;
2022-04-30 10:45:38 +00:00
//createEditHandler(correctPIN && !otaLock);
2018-02-20 21:29:48 +00:00
}
2016-11-20 00:47:15 +00:00
}
2022-03-01 22:37:28 +00:00
2020-02-23 21:24:51 +00:00
# ifdef WLED_ENABLE_DMX // include only if DMX is enabled
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_DMX )
2020-02-23 21:24:51 +00:00
{
2020-09-19 23:18:31 +00:00
int t = request - > arg ( F ( " PU " ) ) . toInt ( ) ;
2020-05-11 09:51:11 +00:00
if ( t > = 0 & & t < = 63999 ) e131ProxyUniverse = t ;
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " CN " ) ) . toInt ( ) ;
2020-02-23 21:24:51 +00:00
if ( t > 0 & & t < 16 ) {
DMXChannels = t ;
}
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " CS " ) ) . toInt ( ) ;
2020-02-23 21:24:51 +00:00
if ( t > 0 & & t < 513 ) {
DMXStart = t ;
}
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " CG " ) ) . toInt ( ) ;
2020-02-23 21:24:51 +00:00
if ( t > 0 & & t < 513 ) {
DMXGap = t ;
}
2020-09-19 23:18:31 +00:00
t = request - > arg ( F ( " SL " ) ) . toInt ( ) ;
2020-04-10 10:30:08 +00:00
if ( t > = 0 & & t < MAX_LEDS ) {
DMXStartLED = t ;
}
2020-02-23 21:24:51 +00:00
for ( int i = 0 ; i < 15 ; i + + ) {
String argname = " CH " + String ( ( i + 1 ) ) ;
t = request - > arg ( argname ) . toInt ( ) ;
DMXFixtureMap [ i ] = t ;
}
}
# endif
2021-01-16 23:20:31 +00:00
2021-04-09 22:17:15 +00:00
//USERMODS
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_UM )
2021-04-09 22:17:15 +00:00
{
2021-12-04 00:05:01 +00:00
if ( ! requestJSONBufferLock ( 5 ) ) return ;
2021-11-03 13:52:22 +00:00
2022-08-07 14:43:29 +00:00
// global I2C & SPI pins
2022-09-13 18:26:45 +00:00
int8_t hw_sda_pin = ! request - > arg ( F ( " SDA " ) ) . length ( ) ? - 1 : ( int ) request - > arg ( F ( " SDA " ) ) . toInt ( ) ;
int8_t hw_scl_pin = ! request - > arg ( F ( " SCL " ) ) . length ( ) ? - 1 : ( int ) request - > arg ( F ( " SCL " ) ) . toInt ( ) ;
2023-05-30 17:36:14 +00:00
if ( i2c_sda ! = hw_sda_pin | | i2c_scl ! = hw_scl_pin ) {
// only if pins changed
uint8_t old_i2c [ 2 ] = { static_cast < uint8_t > ( i2c_scl ) , static_cast < uint8_t > ( i2c_sda ) } ;
pinManager . deallocateMultiplePins ( old_i2c , 2 , PinOwner : : HW_I2C ) ; // just in case deallocation of old pins
PinManagerPinType i2c [ 2 ] = { { hw_sda_pin , true } , { hw_scl_pin , true } } ;
if ( hw_sda_pin > = 0 & & hw_scl_pin > = 0 & & pinManager . allocateMultiplePins ( i2c , 2 , PinOwner : : HW_I2C ) ) {
i2c_sda = hw_sda_pin ;
i2c_scl = hw_scl_pin ;
// no bus re-initialisation as usermods do not get any notification
//Wire.begin(i2c_sda, i2c_scl);
} else {
// there is no Wire.end()
DEBUG_PRINTLN ( F ( " Could not allocate I2C pins. " ) ) ;
i2c_sda = - 1 ;
i2c_scl = - 1 ;
}
2022-08-07 14:43:29 +00:00
}
2022-09-13 18:26:45 +00:00
int8_t hw_mosi_pin = ! request - > arg ( F ( " MOSI " ) ) . length ( ) ? - 1 : ( int ) request - > arg ( F ( " MOSI " ) ) . toInt ( ) ;
int8_t hw_miso_pin = ! request - > arg ( F ( " MISO " ) ) . length ( ) ? - 1 : ( int ) request - > arg ( F ( " MISO " ) ) . toInt ( ) ;
int8_t hw_sclk_pin = ! request - > arg ( F ( " SCLK " ) ) . length ( ) ? - 1 : ( int ) request - > arg ( F ( " SCLK " ) ) . toInt ( ) ;
2022-08-07 14:43:29 +00:00
# ifdef ESP8266
// cannot change pins on ESP8266
2022-08-15 18:23:47 +00:00
if ( hw_mosi_pin > = 0 & & hw_mosi_pin ! = HW_PIN_DATASPI ) hw_mosi_pin = HW_PIN_DATASPI ;
2022-08-27 16:25:54 +00:00
if ( hw_miso_pin > = 0 & & hw_miso_pin ! = HW_PIN_MISOSPI ) hw_mosi_pin = HW_PIN_MISOSPI ;
2022-08-15 18:23:47 +00:00
if ( hw_sclk_pin > = 0 & & hw_sclk_pin ! = HW_PIN_CLOCKSPI ) hw_sclk_pin = HW_PIN_CLOCKSPI ;
2022-08-07 14:43:29 +00:00
# endif
2023-05-30 17:36:14 +00:00
if ( spi_mosi ! = hw_mosi_pin | | spi_miso ! = hw_miso_pin | | spi_sclk ! = hw_sclk_pin ) {
// only if pins changed
uint8_t old_spi [ 3 ] = { static_cast < uint8_t > ( spi_mosi ) , static_cast < uint8_t > ( spi_miso ) , static_cast < uint8_t > ( spi_sclk ) } ;
pinManager . deallocateMultiplePins ( old_spi , 3 , PinOwner : : HW_SPI ) ; // just in case deallocation of old pins
PinManagerPinType spi [ 3 ] = { { hw_mosi_pin , true } , { hw_miso_pin , true } , { hw_sclk_pin , true } } ;
if ( hw_mosi_pin > = 0 & & hw_sclk_pin > = 0 & & pinManager . allocateMultiplePins ( spi , 3 , PinOwner : : HW_SPI ) ) {
spi_mosi = hw_mosi_pin ;
spi_miso = hw_miso_pin ;
spi_sclk = hw_sclk_pin ;
// no bus re-initialisation as usermods do not get any notification
//SPI.end();
# ifdef ESP32
//SPI.begin(spi_sclk, spi_miso, spi_mosi);
# else
//SPI.begin();
# endif
} else {
//SPI.end();
DEBUG_PRINTLN ( F ( " Could not allocate SPI pins. " ) ) ;
spi_mosi = - 1 ;
spi_miso = - 1 ;
spi_sclk = - 1 ;
}
2022-08-07 14:43:29 +00:00
}
2021-04-25 19:15:57 +00:00
JsonObject um = doc . createNestedObject ( " um " ) ;
2021-04-09 22:17:15 +00:00
size_t args = request - > args ( ) ;
2022-02-20 21:24:11 +00:00
uint16_t j = 0 ;
2021-04-09 22:17:15 +00:00
for ( size_t i = 0 ; i < args ; i + + ) {
String name = request - > argName ( i ) ;
String value = request - > arg ( i ) ;
2021-04-17 15:04:36 +00:00
// POST request parameters are combined as <usermodname>_<usermodparameter>
2021-06-27 10:15:35 +00:00
int umNameEnd = name . indexOf ( " : " ) ;
2022-08-15 18:23:47 +00:00
if ( umNameEnd < 1 ) continue ; // parameter does not contain ":" or on 1st place -> wrong
2021-04-17 15:04:36 +00:00
JsonObject mod = um [ name . substring ( 0 , umNameEnd ) ] ; // get a usermod JSON object
if ( mod . isNull ( ) ) {
mod = um . createNestedObject ( name . substring ( 0 , umNameEnd ) ) ; // if it does not exist create it
}
DEBUG_PRINT ( name . substring ( 0 , umNameEnd ) ) ;
DEBUG_PRINT ( " : " ) ;
name = name . substring ( umNameEnd + 1 ) ; // remove mod name from string
2021-06-27 10:15:35 +00:00
// if the resulting name still contains ":" this means nested object
2021-06-25 21:20:01 +00:00
JsonObject subObj ;
2021-06-27 10:15:35 +00:00
int umSubObj = name . indexOf ( " : " ) ;
DEBUG_PRINTF ( " (%d): " , umSubObj ) ;
2021-06-25 21:20:01 +00:00
if ( umSubObj > 0 ) {
2021-06-27 10:15:35 +00:00
subObj = mod [ name . substring ( 0 , umSubObj ) ] ;
2021-06-25 21:20:01 +00:00
if ( subObj . isNull ( ) )
2021-06-27 10:15:35 +00:00
subObj = mod . createNestedObject ( name . substring ( 0 , umSubObj ) ) ;
2021-06-25 21:20:01 +00:00
name = name . substring ( umSubObj + 1 ) ; // remove nested object name from string
} else {
subObj = mod ;
}
2021-06-27 10:15:35 +00:00
DEBUG_PRINT ( name ) ;
2021-06-25 21:20:01 +00:00
2021-04-17 15:04:36 +00:00
// check if parameters represent array
2021-04-10 22:38:13 +00:00
if ( name . endsWith ( " [] " ) ) {
name . replace ( " [] " , " " ) ;
2022-02-12 22:14:00 +00:00
value . replace ( " , " , " . " ) ; // just in case conversion
2021-06-25 21:20:01 +00:00
if ( ! subObj [ name ] . is < JsonArray > ( ) ) {
JsonArray ar = subObj . createNestedArray ( name ) ;
2022-02-12 22:14:00 +00:00
if ( value . indexOf ( " . " ) > = 0 ) ar . add ( value . toFloat ( ) ) ; // we do have a float
else ar . add ( value . toInt ( ) ) ; // we may have an int
2021-04-10 22:38:13 +00:00
j = 0 ;
} else {
2022-02-12 22:14:00 +00:00
if ( value . indexOf ( " . " ) > = 0 ) subObj [ name ] . add ( value . toFloat ( ) ) ; // we do have a float
else subObj [ name ] . add ( value . toInt ( ) ) ; // we may have an int
2021-04-10 22:38:13 +00:00
j + + ;
}
DEBUG_PRINT ( " [ " ) ;
DEBUG_PRINT ( j ) ;
DEBUG_PRINT ( " ] = " ) ;
DEBUG_PRINTLN ( value ) ;
} else {
2021-06-25 21:20:01 +00:00
// we are using a hidden field with the same name as our parameter (!before the actual parameter!)
// to describe the type of parameter (text,float,int), for boolean patameters the first field contains "off"
2021-06-27 10:15:35 +00:00
// so checkboxes have one or two fields (first is always "false", existence of second depends on checkmark and may be "true")
2021-06-25 21:20:01 +00:00
if ( subObj [ name ] . isNull ( ) ) {
// the first occurence of the field describes the parameter type (used in next loop)
2021-06-27 10:15:35 +00:00
if ( value = = " false " ) subObj [ name ] = false ; // checkboxes may have only one field
else subObj [ name ] = value ;
2021-06-25 21:20:01 +00:00
} else {
String type = subObj [ name ] . as < String > ( ) ; // get previously stored value as a type
2021-06-29 16:18:28 +00:00
if ( subObj [ name ] . is < bool > ( ) ) subObj [ name ] = true ; // checkbox/boolean
else if ( type = = " number " ) {
value . replace ( " , " , " . " ) ; // just in case conversion
if ( value . indexOf ( " . " ) > = 0 ) subObj [ name ] = value . toFloat ( ) ; // we do have a float
else subObj [ name ] = value . toInt ( ) ; // we may have an int
} else if ( type = = " int " ) subObj [ name ] = value . toInt ( ) ;
else subObj [ name ] = value ; // text fields
2021-06-25 21:20:01 +00:00
}
2021-04-10 22:38:13 +00:00
DEBUG_PRINT ( " = " ) ;
DEBUG_PRINTLN ( value ) ;
}
2021-04-09 22:17:15 +00:00
}
2021-04-17 15:04:36 +00:00
usermods . readFromConfig ( um ) ; // force change of usermod parameters
2022-09-14 20:28:06 +00:00
DEBUG_PRINTLN ( F ( " Done re-init usermods. " ) ) ;
2021-12-10 12:29:42 +00:00
releaseJSONBufferLock ( ) ;
}
2022-03-01 22:37:28 +00:00
2022-07-10 20:23:25 +00:00
# ifndef WLED_DISABLE_2D
2022-05-08 08:50:48 +00:00
//2D panels
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_2D )
2022-05-08 08:50:48 +00:00
{
strip . isMatrix = request - > arg ( F ( " SOMP " ) ) . toInt ( ) ;
2023-01-02 19:56:00 +00:00
strip . panel . clear ( ) ; // release memory if allocated
if ( strip . isMatrix ) {
strip . panels = MAX ( 1 , MIN ( WLED_MAX_PANELS , request - > arg ( F ( " MPC " ) ) . toInt ( ) ) ) ;
strip . panel . reserve ( strip . panels ) ; // pre-allocate memory
for ( uint8_t i = 0 ; i < strip . panels ; i + + ) {
WS2812FX : : Panel p ;
2023-01-03 13:17:42 +00:00
char pO [ 8 ] = { ' \0 ' } ;
2023-01-03 14:16:45 +00:00
snprintf_P ( pO , 7 , PSTR ( " P%d " ) , i ) ; // MAX_PANELS is 64 so pO will always only be 4 characters or less
2023-01-03 13:17:42 +00:00
pO [ 7 ] = ' \0 ' ;
uint8_t l = strlen ( pO ) ;
2023-01-03 14:16:45 +00:00
// create P0B, P1B, ..., P63B, etc for other PxxX
pO [ l ] = ' B ' ; if ( ! request - > hasArg ( pO ) ) break ;
2023-01-02 19:56:00 +00:00
pO [ l ] = ' B ' ; p . bottomStart = request - > arg ( pO ) . toInt ( ) ;
pO [ l ] = ' R ' ; p . rightStart = request - > arg ( pO ) . toInt ( ) ;
pO [ l ] = ' V ' ; p . vertical = request - > arg ( pO ) . toInt ( ) ;
pO [ l ] = ' S ' ; p . serpentine = request - > hasArg ( pO ) ;
pO [ l ] = ' X ' ; p . xOffset = request - > arg ( pO ) . toInt ( ) ;
pO [ l ] = ' Y ' ; p . yOffset = request - > arg ( pO ) . toInt ( ) ;
pO [ l ] = ' W ' ; p . width = request - > arg ( pO ) . toInt ( ) ;
pO [ l ] = ' H ' ; p . height = request - > arg ( pO ) . toInt ( ) ;
strip . panel . push_back ( p ) ;
}
2023-02-09 19:15:55 +00:00
strip . setUpMatrix ( ) ; // will check limits
2023-02-11 17:41:30 +00:00
strip . makeAutoSegments ( true ) ;
2023-02-12 12:18:30 +00:00
strip . deserializeMap ( ) ;
2023-01-02 19:56:00 +00:00
} else {
Segment : : maxWidth = strip . getLengthTotal ( ) ;
Segment : : maxHeight = 1 ;
2022-05-08 08:50:48 +00:00
}
}
2022-07-10 20:23:25 +00:00
# endif
2022-05-08 08:50:48 +00:00
2022-04-30 10:45:38 +00:00
lastEditTime = millis ( ) ;
2023-05-30 17:36:14 +00:00
// do not save if factory reset or LED settings (which are saved after LED re-init)
2023-06-15 21:58:22 +00:00
doSerializeConfig = subPage ! = SUBPAGE_LEDS & & ! ( subPage = = SUBPAGE_SEC & & doReboot ) ;
if ( subPage = = SUBPAGE_UM ) doReboot = request - > hasArg ( F ( " RBT " ) ) ; // prevent race condition on dual core system (set reboot here, after doSerializeConfig has been set)
2023-01-12 19:35:34 +00:00
# ifndef WLED_DISABLE_ALEXA
2023-06-15 21:58:22 +00:00
if ( subPage = = SUBPAGE_SYNC ) alexaInit ( ) ;
2023-01-12 19:35:34 +00:00
# endif
2016-11-19 18:39:17 +00:00
}
2018-11-24 23:00:02 +00:00
//HTTP API request parser
2020-10-02 22:29:36 +00:00
bool handleSet ( AsyncWebServerRequest * request , const String & req , bool apply )
2016-11-19 18:39:17 +00:00
{
2018-11-09 16:00:36 +00:00
if ( ! ( req . indexOf ( " win " ) > = 0 ) ) return false ;
2018-09-17 09:15:08 +00:00
2018-11-09 16:00:36 +00:00
int pos = 0 ;
2020-09-19 23:18:31 +00:00
DEBUG_PRINT ( F ( " API req: " ) ) ;
2018-11-09 16:00:36 +00:00
DEBUG_PRINTLN ( req ) ;
2019-08-17 10:27:06 +00:00
2019-12-01 00:42:52 +00:00
//segment select (sets main segment)
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SM= " ) ) ;
2022-04-07 19:54:55 +00:00
if ( pos > 0 & & ! realtimeMode ) {
2022-02-20 21:24:11 +00:00
strip . setMainSegmentId ( getNumVal ( & req , pos ) ) ;
2019-12-01 00:42:52 +00:00
}
2022-02-23 18:20:07 +00:00
byte selectedSeg = strip . getFirstSelectedSegId ( ) ;
2019-12-04 01:01:47 +00:00
2022-02-20 21:24:11 +00:00
bool singleSegment = false ;
2022-01-14 13:27:11 +00:00
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SS= " ) ) ;
2019-12-04 01:01:47 +00:00
if ( pos > 0 ) {
byte t = getNumVal ( & req , pos ) ;
2022-07-19 14:16:43 +00:00
if ( t < strip . getSegmentsNum ( ) ) {
2022-01-14 13:27:11 +00:00
selectedSeg = t ;
2022-02-20 21:24:11 +00:00
singleSegment = true ;
2022-01-14 13:27:11 +00:00
}
2019-12-04 01:01:47 +00:00
}
2022-07-06 11:13:54 +00:00
Segment & selseg = strip . getSegment ( selectedSeg ) ;
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SV= " ) ) ; //segment selected
2020-06-26 21:30:13 +00:00
if ( pos > 0 ) {
byte t = getNumVal ( & req , pos ) ;
2022-08-19 19:14:49 +00:00
if ( t = = 2 ) for ( uint8_t i = 0 ; i < strip . getSegmentsNum ( ) ; i + + ) strip . getSegment ( i ) . selected = false ; // unselect other segments
selseg . selected = t ;
2020-06-26 21:30:13 +00:00
}
2019-12-01 00:42:52 +00:00
2022-02-23 18:20:07 +00:00
// temporary values, write directly to segments, globals are updated by setValuesFromFirstSelectedSeg()
2022-02-21 17:31:19 +00:00
uint32_t col0 = selseg . colors [ 0 ] ;
uint32_t col1 = selseg . colors [ 1 ] ;
byte colIn [ 4 ] = { R ( col0 ) , G ( col0 ) , B ( col0 ) , W ( col0 ) } ;
byte colInSec [ 4 ] = { R ( col1 ) , G ( col1 ) , B ( col1 ) , W ( col1 ) } ;
byte effectIn = selseg . mode ;
byte speedIn = selseg . speed ;
byte intensityIn = selseg . intensity ;
byte paletteIn = selseg . palette ;
2022-11-13 11:13:49 +00:00
byte custom1In = selseg . custom1 ;
byte custom2In = selseg . custom2 ;
byte custom3In = selseg . custom3 ;
byte check1In = selseg . check1 ;
byte check2In = selseg . check2 ;
byte check3In = selseg . check3 ;
uint16_t startI = selseg . start ;
uint16_t stopI = selseg . stop ;
uint16_t startY = selseg . startY ;
uint16_t stopY = selseg . stopY ;
uint8_t grpI = selseg . grouping ;
uint16_t spcI = selseg . spacing ;
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " &S= " ) ) ; //segment start
2019-12-01 00:42:52 +00:00
if ( pos > 0 ) {
startI = getNumVal ( & req , pos ) ;
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " S2= " ) ) ; //segment stop
2019-12-01 00:42:52 +00:00
if ( pos > 0 ) {
stopI = getNumVal ( & req , pos ) ;
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " GP= " ) ) ; //segment grouping
2020-01-19 00:07:38 +00:00
if ( pos > 0 ) {
grpI = getNumVal ( & req , pos ) ;
if ( grpI = = 0 ) grpI = 1 ;
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SP= " ) ) ; //segment spacing
2020-01-19 00:07:38 +00:00
if ( pos > 0 ) {
spcI = getNumVal ( & req , pos ) ;
}
2023-05-28 20:50:19 +00:00
selseg . setUp ( startI , stopI , grpI , spcI , UINT16_MAX , startY , stopY ) ;
2019-12-01 00:42:52 +00:00
2021-09-20 20:24:58 +00:00
pos = req . indexOf ( F ( " RV= " ) ) ; //Segment reverse
2022-08-19 19:14:49 +00:00
if ( pos > 0 ) selseg . reverse = req . charAt ( pos + 3 ) ! = ' 0 ' ;
2021-09-20 20:24:58 +00:00
pos = req . indexOf ( F ( " MI= " ) ) ; //Segment mirror
2022-08-19 19:14:49 +00:00
if ( pos > 0 ) selseg . mirror = req . charAt ( pos + 3 ) ! = ' 0 ' ;
2021-09-20 20:24:58 +00:00
pos = req . indexOf ( F ( " SB= " ) ) ; //Segment brightness/opacity
if ( pos > 0 ) {
byte segbri = getNumVal ( & req , pos ) ;
2022-08-23 13:57:05 +00:00
selseg . setOption ( SEG_OPTION_ON , segbri ) ; // use transition
2021-09-20 20:24:58 +00:00
if ( segbri ) {
2022-07-10 20:23:25 +00:00
selseg . setOpacity ( segbri ) ;
2021-09-20 20:24:58 +00:00
}
}
pos = req . indexOf ( F ( " SW= " ) ) ; //segment power
if ( pos > 0 ) {
switch ( getNumVal ( & req , pos ) ) {
2022-08-23 13:57:05 +00:00
case 0 : selseg . setOption ( SEG_OPTION_ON , false ) ; break ; // use transition
case 1 : selseg . setOption ( SEG_OPTION_ON , true ) ; break ; // use transition
default : selseg . setOption ( SEG_OPTION_ON , ! selseg . on ) ; break ; // use transition
2021-09-20 20:24:58 +00:00
}
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " PS= " ) ) ; //saves current in preset
2020-10-07 22:52:15 +00:00
if ( pos > 0 ) savePreset ( getNumVal ( & req , pos ) ) ;
2020-02-09 15:11:38 +00:00
2021-07-04 11:23:45 +00:00
pos = req . indexOf ( F ( " P1= " ) ) ; //sets first preset for cycle
2021-11-22 20:41:04 +00:00
if ( pos > 0 ) presetCycMin = getNumVal ( & req , pos ) ;
2021-07-04 11:23:45 +00:00
pos = req . indexOf ( F ( " P2= " ) ) ; //sets last preset for cycle
2021-11-22 20:41:04 +00:00
if ( pos > 0 ) presetCycMax = getNumVal ( & req , pos ) ;
2021-07-04 11:23:45 +00:00
2020-02-09 15:11:38 +00:00
//apply preset
2022-06-03 20:22:18 +00:00
if ( updateVal ( req . c_str ( ) , " PL= " , & presetCycCurr , presetCycMin , presetCycMax ) ) {
2023-02-14 13:28:10 +00:00
unloadPlaylist ( ) ;
2021-07-04 11:23:45 +00:00
applyPreset ( presetCycCurr ) ;
}
2020-02-09 15:11:38 +00:00
2019-02-22 21:53:33 +00:00
//set brightness
2022-06-03 20:22:18 +00:00
updateVal ( req . c_str ( ) , " &A= " , & bri ) ;
2019-02-22 21:53:33 +00:00
2022-02-16 20:12:33 +00:00
bool col0Changed = false , col1Changed = false ;
2019-02-22 21:53:33 +00:00
//set colors
2022-06-03 20:22:18 +00:00
col0Changed | = updateVal ( req . c_str ( ) , " &R= " , & colIn [ 0 ] ) ;
col0Changed | = updateVal ( req . c_str ( ) , " &G= " , & colIn [ 1 ] ) ;
col0Changed | = updateVal ( req . c_str ( ) , " &B= " , & colIn [ 2 ] ) ;
col0Changed | = updateVal ( req . c_str ( ) , " &W= " , & colIn [ 3 ] ) ;
2022-02-16 20:12:33 +00:00
2022-06-03 20:22:18 +00:00
col1Changed | = updateVal ( req . c_str ( ) , " R2= " , & colInSec [ 0 ] ) ;
col1Changed | = updateVal ( req . c_str ( ) , " G2= " , & colInSec [ 1 ] ) ;
col1Changed | = updateVal ( req . c_str ( ) , " B2= " , & colInSec [ 2 ] ) ;
col1Changed | = updateVal ( req . c_str ( ) , " W2= " , & colInSec [ 3 ] ) ;
2018-02-27 23:27:10 +00:00
2020-09-27 09:43:28 +00:00
# ifdef WLED_ENABLE_LOXONE
2020-09-27 09:37:16 +00:00
//lox parser
pos = req . indexOf ( F ( " LX= " ) ) ; // Lox primary color
if ( pos > 0 ) {
int lxValue = getNumVal ( & req , pos ) ;
2022-02-20 21:24:11 +00:00
if ( parseLx ( lxValue , colIn ) ) {
2020-09-27 09:37:16 +00:00
bri = 255 ;
nightlightActive = false ; //always disable nightlight when toggling
2022-02-21 19:48:11 +00:00
col0Changed = true ;
2020-09-27 09:37:16 +00:00
}
}
2020-09-27 09:43:28 +00:00
pos = req . indexOf ( F ( " LY= " ) ) ; // Lox secondary color
2020-09-27 09:37:16 +00:00
if ( pos > 0 ) {
int lxValue = getNumVal ( & req , pos ) ;
2022-02-20 21:24:11 +00:00
if ( parseLx ( lxValue , colInSec ) ) {
2020-09-27 09:37:16 +00:00
bri = 255 ;
nightlightActive = false ; //always disable nightlight when toggling
2022-02-21 19:48:11 +00:00
col1Changed = true ;
2020-09-27 09:37:16 +00:00
}
}
2020-09-27 09:43:28 +00:00
# endif
2018-11-09 16:00:36 +00:00
//set hue
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " HU= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
uint16_t temphue = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
byte tempsat = 255 ;
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SA= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
tempsat = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
}
2022-01-15 20:15:37 +00:00
byte sec = req . indexOf ( F ( " H2 " ) ) ;
2022-02-20 21:24:11 +00:00
colorHStoRGB ( temphue , tempsat , ( sec > 0 ) ? colInSec : colIn ) ;
2022-02-21 19:48:11 +00:00
col0Changed | = ( ! sec ) ; col1Changed | = sec ;
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2020-09-27 09:43:28 +00:00
//set white spectrum (kelvin)
pos = req . indexOf ( F ( " &K= " ) ) ;
if ( pos > 0 ) {
2022-01-15 20:15:37 +00:00
byte sec = req . indexOf ( F ( " K2 " ) ) ;
2022-02-20 21:24:11 +00:00
colorKtoRGB ( getNumVal ( & req , pos ) , ( sec > 0 ) ? colInSec : colIn ) ;
2022-02-21 19:48:11 +00:00
col0Changed | = ( ! sec ) ; col1Changed | = sec ;
2020-09-27 09:43:28 +00:00
}
2018-11-09 16:00:36 +00:00
//set color from HEX or 32bit DEC
2022-01-15 20:15:37 +00:00
byte tmpCol [ 4 ] ;
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " CL= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2022-02-20 21:24:11 +00:00
colorFromDecOrHexString ( colIn , ( char * ) req . substring ( pos + 3 ) . c_str ( ) ) ;
2022-02-21 19:48:11 +00:00
col0Changed = true ;
2018-11-09 16:00:36 +00:00
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " C2= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2022-02-20 21:24:11 +00:00
colorFromDecOrHexString ( colInSec , ( char * ) req . substring ( pos + 3 ) . c_str ( ) ) ;
2022-02-21 19:48:11 +00:00
col1Changed = true ;
2018-11-09 16:00:36 +00:00
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " C3= " ) ) ;
2020-04-23 21:52:33 +00:00
if ( pos > 0 ) {
2022-01-15 20:15:37 +00:00
colorFromDecOrHexString ( tmpCol , ( char * ) req . substring ( pos + 3 ) . c_str ( ) ) ;
2022-02-16 20:12:33 +00:00
uint32_t col2 = RGBW32 ( tmpCol [ 0 ] , tmpCol [ 1 ] , tmpCol [ 2 ] , tmpCol [ 3 ] ) ;
2022-07-10 20:23:25 +00:00
selseg . setColor ( 2 , col2 ) ; // defined above (SS= or main)
2022-02-22 09:42:00 +00:00
if ( ! singleSegment ) strip . setColor ( 2 , col2 ) ; // will set color to all active & selected segments
2020-04-23 21:52:33 +00:00
}
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//set to random hue SR=0->1st SR=1->2nd
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SR " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2022-01-15 20:15:37 +00:00
byte sec = getNumVal ( & req , pos ) ;
2022-02-20 21:24:11 +00:00
setRandomColor ( sec ? colInSec : colIn ) ;
2022-02-21 19:48:11 +00:00
col0Changed | = ( ! sec ) ; col1Changed | = sec ;
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//swap 2nd & 1st
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SC " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2019-02-05 20:53:39 +00:00
byte temp ;
2022-01-15 20:15:37 +00:00
for ( uint8_t i = 0 ; i < 4 ; i + + ) {
2022-02-20 21:24:11 +00:00
temp = colIn [ i ] ;
colIn [ i ] = colInSec [ i ] ;
colInSec [ i ] = temp ;
2018-11-09 16:00:36 +00:00
}
2022-02-21 19:48:11 +00:00
col0Changed = col1Changed = true ;
2022-02-16 20:12:33 +00:00
}
2022-02-21 19:48:11 +00:00
// apply colors to selected segment, and all selected segments if applicable
if ( col0Changed ) {
uint32_t colIn0 = RGBW32 ( colIn [ 0 ] , colIn [ 1 ] , colIn [ 2 ] , colIn [ 3 ] ) ;
2022-07-10 20:23:25 +00:00
selseg . setColor ( 0 , colIn0 ) ;
2022-02-22 09:42:00 +00:00
if ( ! singleSegment ) strip . setColor ( 0 , colIn0 ) ; // will set color to all active & selected segments
2022-02-16 20:12:33 +00:00
}
2022-02-21 19:48:11 +00:00
if ( col1Changed ) {
uint32_t colIn1 = RGBW32 ( colInSec [ 0 ] , colInSec [ 1 ] , colInSec [ 2 ] , colInSec [ 3 ] ) ;
2022-07-10 20:23:25 +00:00
selseg . setColor ( 1 , colIn1 ) ;
2022-02-22 09:42:00 +00:00
if ( ! singleSegment ) strip . setColor ( 1 , colIn1 ) ; // will set color to all active & selected segments
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2022-02-21 19:48:11 +00:00
bool fxModeChanged = false , speedChanged = false , intensityChanged = false , paletteChanged = false ;
2022-11-13 11:13:49 +00:00
bool custom1Changed = false , custom2Changed = false , custom3Changed = false , check1Changed = false , check2Changed = false , check3Changed = false ;
2022-02-21 19:48:11 +00:00
// set effect parameters
2022-06-03 20:22:18 +00:00
if ( updateVal ( req . c_str ( ) , " FX= " , & effectIn , 0 , strip . getModeCount ( ) - 1 ) ) {
2022-02-21 19:48:11 +00:00
if ( request ! = nullptr ) unloadPlaylist ( ) ; // unload playlist if changing FX using web request
fxModeChanged = true ;
}
2022-06-03 20:22:18 +00:00
speedChanged = updateVal ( req . c_str ( ) , " SX= " , & speedIn ) ;
intensityChanged = updateVal ( req . c_str ( ) , " IX= " , & intensityIn ) ;
paletteChanged = updateVal ( req . c_str ( ) , " FP= " , & paletteIn , 0 , strip . getPaletteCount ( ) - 1 ) ;
2022-11-13 11:13:49 +00:00
custom1Changed = updateVal ( req . c_str ( ) , " X1= " , & custom1In ) ;
custom2Changed = updateVal ( req . c_str ( ) , " X2= " , & custom2In ) ;
custom3Changed = updateVal ( req . c_str ( ) , " X3= " , & custom3In ) ;
check1Changed = updateVal ( req . c_str ( ) , " M1= " , & check1In ) ;
check2Changed = updateVal ( req . c_str ( ) , " M2= " , & check2In ) ;
check3Changed = updateVal ( req . c_str ( ) , " M3= " , & check3In ) ;
stateChanged | = ( fxModeChanged | | speedChanged | | intensityChanged | | paletteChanged | | custom1Changed | | custom2Changed | | custom3Changed | | check1Changed | | check2Changed | | check3Changed ) ;
2022-02-21 19:48:11 +00:00
2022-02-26 00:37:09 +00:00
// apply to main and all selected segments to prevent #1618.
2022-07-19 14:16:43 +00:00
for ( uint8_t i = 0 ; i < strip . getSegmentsNum ( ) ; i + + ) {
2022-07-06 11:13:54 +00:00
Segment & seg = strip . getSegment ( i ) ;
2022-02-22 09:42:00 +00:00
if ( i ! = selectedSeg & & ( singleSegment | | ! seg . isActive ( ) | | ! seg . isSelected ( ) ) ) continue ; // skip non main segments if not applying to all
2022-09-29 10:49:12 +00:00
if ( fxModeChanged ) seg . setMode ( effectIn , req . indexOf ( F ( " FXD= " ) ) > 0 ) ; // apply defaults if FXD= is specified
2022-02-22 09:42:00 +00:00
if ( speedChanged ) seg . speed = speedIn ;
2022-02-21 19:48:11 +00:00
if ( intensityChanged ) seg . intensity = intensityIn ;
2022-09-29 10:49:12 +00:00
if ( paletteChanged ) seg . setPalette ( paletteIn ) ;
2022-11-13 11:13:49 +00:00
if ( custom1Changed ) seg . custom1 = custom1In ;
if ( custom2Changed ) seg . custom2 = custom2In ;
if ( custom3Changed ) seg . custom3 = custom3In ;
if ( check1Changed ) seg . check1 = ( bool ) check1In ;
if ( check2Changed ) seg . check2 = ( bool ) check2In ;
if ( check3Changed ) seg . check3 = ( bool ) check3In ;
2022-02-20 21:24:11 +00:00
}
2018-11-09 16:00:36 +00:00
//set advanced overlay
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " OL= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
overlayCurrent = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
}
2018-09-04 13:51:38 +00:00
2020-11-06 21:12:48 +00:00
//apply macro (deprecated, added for compatibility with pre-0.11 automations)
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " &M= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2020-11-06 21:12:48 +00:00
applyPreset ( getNumVal ( & req , pos ) + 16 ) ;
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//toggle send UDP direct notifications
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " SN= " ) ) ;
2019-02-22 21:53:33 +00:00
if ( pos > 0 ) notifyDirect = ( req . charAt ( pos + 3 ) ! = ' 0 ' ) ;
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//toggle receive UDP direct notifications
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " RN= " ) ) ;
2019-02-22 21:53:33 +00:00
if ( pos > 0 ) receiveNotifications = ( req . charAt ( pos + 3 ) ! = ' 0 ' ) ;
2019-03-09 13:48:13 +00:00
//receive live data via UDP/Hyperion
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " RD= " ) ) ;
2019-03-09 13:48:13 +00:00
if ( pos > 0 ) receiveDirect = ( req . charAt ( pos + 3 ) ! = ' 0 ' ) ;
2019-08-17 10:27:06 +00:00
2020-10-02 10:30:17 +00:00
//main toggle on/off (parse before nightlight, #1214)
pos = req . indexOf ( F ( " &T= " ) ) ;
if ( pos > 0 ) {
nightlightActive = false ; //always disable nightlight when toggling
switch ( getNumVal ( & req , pos ) )
{
case 0 : if ( bri ! = 0 ) { briLast = bri ; bri = 0 ; } break ; //off, only if it was previously on
case 1 : if ( bri = = 0 ) bri = briLast ; break ; //on, only if it was previously off
default : toggleOnOff ( ) ; //toggle
}
}
2018-11-09 16:00:36 +00:00
//toggle nightlight mode
bool aNlDef = false ;
2020-09-19 23:18:31 +00:00
if ( req . indexOf ( F ( " &ND " ) ) > 0 ) aNlDef = true ;
pos = req . indexOf ( F ( " NL= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 )
{
2019-02-22 21:53:33 +00:00
if ( req . charAt ( pos + 3 ) = = ' 0 ' )
2018-11-09 16:00:36 +00:00
{
nightlightActive = false ;
} else {
2018-04-15 13:27:54 +00:00
nightlightActive = true ;
2018-11-24 23:00:02 +00:00
if ( ! aNlDef ) nightlightDelayMins = getNumVal ( & req , pos ) ;
2022-11-04 07:33:55 +00:00
else nightlightDelayMins = nightlightDelayMinsDefault ;
2018-04-15 13:27:54 +00:00
nightlightStartTime = millis ( ) ;
2018-11-09 16:00:36 +00:00
}
} else if ( aNlDef )
{
nightlightActive = true ;
2022-11-04 07:33:55 +00:00
nightlightDelayMins = nightlightDelayMinsDefault ;
2018-11-09 16:00:36 +00:00
nightlightStartTime = millis ( ) ;
}
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//set nightlight target brightness
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " NT= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
nightlightTargetBri = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
nightlightActiveOld = false ; //re-init
}
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//toggle nightlight fade
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " NF= " ) ) ;
2019-02-22 21:53:33 +00:00
if ( pos > 0 )
2018-11-09 16:00:36 +00:00
{
2020-06-22 10:30:31 +00:00
nightlightMode = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
nightlightActiveOld = false ; //re-init
}
2020-06-22 10:30:31 +00:00
if ( nightlightMode > NL_MODE_SUN ) nightlightMode = NL_MODE_SUN ;
2019-02-25 18:14:13 +00:00
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " TT= " ) ) ;
2019-02-22 21:53:33 +00:00
if ( pos > 0 ) transitionDelay = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
//set time (unix timestamp)
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " ST= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2021-05-27 00:02:02 +00:00
setTimeFromAPI ( getNumVal ( & req , pos ) ) ;
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2018-11-09 16:00:36 +00:00
//set countdown goal (unix timestamp)
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " CT= " ) ) ;
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
countdownTime = getNumVal ( & req , pos ) ;
2021-05-25 07:59:19 +00:00
if ( countdownTime - toki . second ( ) > 0 ) countdownOverTriggered = false ;
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " LO= " ) ) ;
2020-06-22 10:30:31 +00:00
if ( pos > 0 ) {
realtimeOverride = getNumVal ( & req , pos ) ;
if ( realtimeOverride > 2 ) realtimeOverride = REALTIME_OVERRIDE_ALWAYS ;
2022-03-31 22:59:19 +00:00
if ( realtimeMode & & useMainSegmentOnly ) {
2022-08-19 19:14:49 +00:00
strip . getMainSegment ( ) . freeze = ! realtimeOverride ;
2022-03-31 22:59:19 +00:00
}
2020-06-22 10:30:31 +00:00
}
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " RB " ) ) ;
2020-04-29 23:52:36 +00:00
if ( pos > 0 ) doReboot = true ;
2022-03-06 22:47:36 +00:00
// clock mode, 0: normal, 1: countdown
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " NM= " ) ) ;
2020-01-01 00:04:54 +00:00
if ( pos > 0 ) countdownMode = ( req . charAt ( pos + 3 ) ! = ' 0 ' ) ;
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " U0= " ) ) ; //user var 0
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
userVar0 = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
}
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " U1= " ) ) ; //user var 1
2018-11-09 16:00:36 +00:00
if ( pos > 0 ) {
2018-11-24 23:00:02 +00:00
userVar1 = getNumVal ( & req , pos ) ;
2018-11-09 16:00:36 +00:00
}
2022-02-21 19:48:11 +00:00
// you can add more if you need
2019-08-17 10:27:06 +00:00
2022-02-21 19:48:11 +00:00
// global col[], effectCurrent, ... are updated in stateChanged()
if ( ! apply ) return true ; // when called by JSON API, do not call colorUpdated() here
2019-08-17 10:27:06 +00:00
2020-09-19 23:18:31 +00:00
pos = req . indexOf ( F ( " &NN " ) ) ; //do not send UDP notifications this time
2022-02-21 15:19:11 +00:00
stateUpdated ( ( pos > 0 ) ? CALL_MODE_NO_NOTIFY : CALL_MODE_DIRECT_CHANGE ) ;
2019-08-17 10:27:06 +00:00
2022-02-23 18:20:07 +00:00
// internal call, does not send XML response
pos = req . indexOf ( F ( " IN " ) ) ;
if ( pos < 1 ) XML_response ( request ) ;
2018-11-09 16:00:36 +00:00
return true ;
2016-11-19 18:39:17 +00:00
}