This commit is contained in:
fishbone-git 2019-12-22 17:55:40 +01:00
commit 21dc037848
10 changed files with 237 additions and 101 deletions

View File

@ -4,14 +4,17 @@
[platformio]
src_dir = ./wled00
data_dir = ./wled00/data
lib_extra_dirs = ./wled00/src
;lib_extra_dirs = ./wled00/src
lib_dir = ./wled00/src
; Please uncomment one of the 5 lines below to select your board
; env_default = nodemcuv2
; env_default = esp01
; env_default = esp01_1m
; env_default = d1_mini
; env_default = esp32dev
; env_default = esp8285_4CH_MagicHome
; env_default = esp8285_4CH_H801
; env_default = esp8285_5CH_H801
[common]
framework = arduino
@ -77,7 +80,7 @@ build_flags =
-D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE
; -D WLED_DISABLE_HUESYNC
-D WLED_DISABLE_INFRARED
; -D WLED_DISABLE_INFRARED
[common:esp8266_512k]
platform = espressif8266@1.8.0
@ -89,15 +92,15 @@ build_flags =
; -D WLED_DISABLE_ALEXA
-D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE
; -D WLED_DISABLE_HUESYNC
-D WLED_DISABLE_INFRARED
-D WLED_DISABLE_HUESYNC
; -D WLED_DISABLE_INFRARED
[common:esp32]
platform = espressif32@1.11.1
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
-D ARDUINO_ARCH_ESP32
-D WLED_DISABLE_INFRARED
-D WLED_DISABLE_INFRARED
# see: http://docs.platformio.org/en/latest/platforms/espressif8266.html
[env:nodemcuv2]
@ -147,6 +150,7 @@ framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_512k.build_flags}
-D WLED_DISABLE_INFRARED
lib_deps =
${common.lib_deps_external}
@ -165,3 +169,49 @@ lib_deps =
lib_ignore =
IRremoteESP8266
ESPAsyncUDP
[env:esp8285_4CH_MagicHome]
board = esp8285
platform = ${common:esp8266_1M.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_1M.build_flags}
-D WLED_DISABLE_HUESYNC
-D WLED_ENABLE_ANALOG_LEDS
lib_deps =
${common.lib_deps_external}
[env:esp8285_4CH_H801]
board = esp8285
platform = ${common:esp8266_1M.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_1M.build_flags}
-D WLED_DISABLE_HUESYNC
-D WLED_ENABLE_ANALOG_LEDS
-D WLED_USE_H801
lib_deps =
${common.lib_deps_external}
[env:esp8285_5CH_H801]
board = esp8285
platform = ${common:esp8266_1M.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_1M.build_flags}
-D WLED_DISABLE_HUESYNC
-D WLED_ENABLE_ANALOG_LEDS
-D WLED_USE_H801
-D WLED_ENABLE_5CH_LEDS
lib_deps =
${common.lib_deps_external}

View File

@ -151,7 +151,7 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) {
uint32_t col1 = useRandomColors? color_wheel(SEGENV.aux1) : SEGCOLOR(1);
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
{
uint16_t index = (rev && back)? SEGMENT.stop -1 -i : i;
uint16_t index = (rev && back)? SEGMENT.stop -1 -i +SEGMENT.start : i;
uint32_t col0 = useRandomColors? color_wheel(SEGENV.aux0) : color_from_palette(index, true, PALETTE_SOLID_WRAP, 0);
if (i - SEGMENT.start < ledIndex)
@ -729,33 +729,40 @@ uint16_t WS2812FX::mode_colorful(void) {
cols[3] = 0x0077F0F0;
for (uint8_t i = 4; i < 7; i++) cols[i] = cols[i-4];
}
int i = SEGMENT.start;
for (i; i < SEGMENT.stop ; i+=4)
uint32_t cycleTime = 50 + (15 * (uint32_t)(255 - SEGMENT.speed));
uint32_t it = now / cycleTime;
if (it != SEGENV.step)
{
setPixelColor(i, cols[SEGENV.step]);
setPixelColor(i+1, cols[SEGENV.step+1]);
setPixelColor(i+2, cols[SEGENV.step+2]);
setPixelColor(i+3, cols[SEGENV.step+3]);
if (SEGMENT.speed > 0) SEGENV.aux0++;
if (SEGENV.aux0 > 3) SEGENV.aux0 = 0;
SEGENV.step = it;
}
uint16_t i = SEGMENT.start;
for (i; i < SEGMENT.stop -3; i+=4)
{
setPixelColor(i, cols[SEGENV.aux0]);
setPixelColor(i+1, cols[SEGENV.aux0+1]);
setPixelColor(i+2, cols[SEGENV.aux0+2]);
setPixelColor(i+3, cols[SEGENV.aux0+3]);
}
i+=4;
if(i < SEGMENT.stop)
{
setPixelColor(i, cols[SEGENV.step]);
setPixelColor(i, cols[SEGENV.aux0]);
if(i+1 < SEGMENT.stop)
{
setPixelColor(i+1, cols[SEGENV.step+1]);
setPixelColor(i+1, cols[SEGENV.aux0+1]);
if(i+2 < SEGMENT.stop)
{
setPixelColor(i+2, cols[SEGENV.step+2]);
setPixelColor(i+2, cols[SEGENV.aux0+2]);
}
}
}
if (SEGMENT.speed > 0) SEGENV.step++; //static if lowest speed
if (SEGENV.step >3) SEGENV.step = 0;
return 50 + (15 * (uint32_t)(255 - SEGMENT.speed));
return FRAMETIME;
}
@ -768,7 +775,7 @@ uint16_t WS2812FX::mode_traffic_light(void) {
uint32_t mdelay = 500;
for (int i = SEGMENT.start; i < SEGMENT.stop-2 ; i+=3)
{
switch (SEGENV.step)
switch (SEGENV.aux0)
{
case 0: setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break;
case 1: setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); setPixelColor(i+1, 0x00EECC00); break;
@ -777,9 +784,14 @@ uint16_t WS2812FX::mode_traffic_light(void) {
}
}
SEGENV.step++;
if (SEGENV.step >3) SEGENV.step = 0;
return mdelay;
if (now - SEGENV.step > mdelay)
{
SEGENV.aux0++;
if (SEGENV.aux0 > 3) SEGENV.aux0 = 0;
SEGENV.step = now;
}
return FRAMETIME;
}
@ -1074,7 +1086,7 @@ uint16_t WS2812FX::gradient_base(bool loading) {
}
per = val/brd;
if (per >1.0) per = 1.0;
setPixelColor(SEGMENT.start + i, color_blend(SEGCOLOR(0), color_from_palette(SEGMENT.start + i, true, PALETTE_SOLID_WRAP, 1), per*255));
setPixelColor(i, color_blend(SEGCOLOR(0), color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), per*255));
}
SEGENV.step++;

View File

@ -5,12 +5,18 @@
//PIN CONFIGURATION
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
//#define USE_APA102 // Uncomment for using APA102 LEDs.
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin (-1 to disable)
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13)
//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
//#define WLED_USE_5CH //5 Channel H801 for cold and warm white
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
//END CONFIGURATION
#ifdef USE_APA102
#define CLKPIN 0
@ -20,6 +26,27 @@
#endif
#endif
#ifdef WLED_USE_ANALOG_LEDS
//PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller
#ifdef WLED_USE_H801
#define RPIN 15 //R pin for analog LED strip
#define GPIN 13 //G pin for analog LED strip
#define BPIN 12 //B pin for analog LED strip
#define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04)
#define W2PIN 04 //W2 pin for analog LED strip
#undef BTNPIN
#undef IR_PIN
#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
#else
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
#define RPIN 5 //R pin for analog LED strip
#define GPIN 12 //G pin for analog LED strip
#define BPIN 15 //B pin for analog LED strip
#define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04)
#endif
#undef RLYPIN
#define RLYPIN -1 //disable as pin 12 is used by analog LEDs
#endif
//automatically uses the right driver method for each platform
#ifdef ARDUINO_ARCH_ESP32
@ -104,40 +131,94 @@ public:
#endif
_pGrbw->Begin();
break;
#ifdef WLED_USE_ANALOG_LEDS
//init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
pinMode(RPIN, OUTPUT);
pinMode(GPIN, OUTPUT);
pinMode(BPIN, OUTPUT);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); pinMode(W2PIN, OUTPUT); break;
#else
case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); break;
#endif
}
analogWriteRange(255); //same range as one RGB channel
analogWriteFreq(880); //PWM frequency proven as good for LEDs
#endif
}
}
#ifdef WLED_USE_ANALOG_LEDS
void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0)
{
analogWrite(RPIN, r);
analogWrite(GPIN, g);
analogWrite(BPIN, b);
switch (_type) {
case NeoPixelType_Grb: break;
#ifdef WLED_USE_5CH_LEDS
case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break;
#else
case NeoPixelType_Grbw: analogWrite(WPIN, w); break;
#endif
}
}
#endif
void Show()
{
byte b;
switch (_type)
{
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
}
bool CanShow() const
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->CanShow(); break;
case NeoPixelType_Grbw: _pGrbw->CanShow(); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grb: _pGrb->Show(); break;
case NeoPixelType_Grbw: _pGrbw->Show(); break;
}
}
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
case NeoPixelType_Grb: {
_pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
#ifdef WLED_USE_ANALOG_LEDS
if (indexPixel != 0) return; //set analog LEDs from first pixel
byte b = _pGrb->GetBrightness();
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0);
#endif
}
break;
case NeoPixelType_Grbw: {
_pGrbw->SetPixelColor(indexPixel, color);
#ifdef WLED_USE_ANALOG_LEDS
if (indexPixel != 0) return; //set analog LEDs from first pixel
byte b = _pGrbw->GetBrightness();
// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
#ifdef WLED_USE_5CH_LEDS
if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) {
SetRgbwPwm(0, 0, 0, 0, color.W * b / 255);
} else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 512, colorW.W * b / 255);
} else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
} else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512);
} else if (color.R == 255 & color.G == 153 && color.B == 0 && color.W == 255) {
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
} else { // not only white colors
SetRgbwPwm(color.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, color.W * b / 255);
}
#else
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
#endif
#endif
}
break;
}
}
void SetBrightness(byte b)
@ -148,15 +229,6 @@ public:
}
}
RgbColor GetPixelColor(uint16_t indexPixel) const
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
}
return 0;
}
// NOTE: Due to feature differences, some support RGBW but the method name
// here needs to be unique, thus GetPixeColorRgbw
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
@ -168,21 +240,6 @@ public:
return 0;
}
void ClearTo(RgbColor color)
{
switch (_type) {
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
void ClearTo(RgbwColor color)
{
switch (_type) {
case NeoPixelType_Grb: break;
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
}
}
private:
NeoPixelType _type;

View File

@ -110,8 +110,8 @@ uint32_t EspalexaDevice::getKelvin()
uint32_t EspalexaDevice::getRGB()
{
if (_rgb != 0) return _rgb; //color has not changed
uint8_t rgb[3];
float r, g, b;
byte rgb[4]{0, 0, 0, 0};
float r, g, b, w;
if (_mode == EspalexaColorMode::none) return 0;
@ -122,6 +122,15 @@ uint32_t EspalexaDevice::getRGB()
float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100)
float r, g, b;
// Cold white to warm white receiving from Alexa: _ct = 199, 234, 284, 350, 383 (from cold white to warm white)
switch (_ct) {
case 199: rgb[0]=255,rgb[1]=255,rgb[2]=255;rgb[3]=255;break;
case 234: rgb[0]=127,rgb[1]=127,rgb[2]=127;rgb[3]=255;break;
case 284: rgb[0]=0,rgb[1]=0,rgb[2]=0;rgb[3]=255;break;
case 350: rgb[0]=130,rgb[1]=90,rgb[2]=0;rgb[3]=255;break;
case 383: rgb[0]=255,rgb[1]=153,rgb[2]=0;rgb[3]=255;break;
default: {
if( temp <= 66 ){
r = 255;
g = temp;
@ -143,6 +152,9 @@ uint32_t EspalexaDevice::getRGB()
rgb[0] = (byte)constrain(r,0.1,255.1);
rgb[1] = (byte)constrain(g,0.1,255.1);
rgb[2] = (byte)constrain(b,0.1,255.1);
}
}
} else if (_mode == EspalexaColorMode::hs)
{
float h = ((float)_hue)/65535.0;
@ -216,7 +228,7 @@ uint32_t EspalexaDevice::getRGB()
rgb[1] = 255.0*g;
rgb[2] = 255.0*b;
}
_rgb = ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2]));
_rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); //white value is only >0 if Alexa did provide a CT value, RGB colors will not be touched.
return _rgb;
}

View File

@ -15,7 +15,7 @@
#include "ArduinoJson-v6.h"
#include <Print.h>
#define DYNAMYC_JSON_DOCUMENT_SIZE 8192
#define DYNAMIC_JSON_DOCUMENT_SIZE 8192
constexpr const char* JSON_MIMETYPE = "application/json";
@ -60,7 +60,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
public:
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMYC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
_code = 200;
_contentType = JSON_MIMETYPE;
if(isArray)
@ -90,7 +90,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
}
};
typedef std::function<void(AsyncWebServerRequest *request, JsonObject json)> ArJsonRequestHandlerFunction;
typedef std::function<void(AsyncWebServerRequest *request)> ArJsonRequestHandlerFunction;
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
private:
@ -103,7 +103,7 @@ protected:
int _maxContentLength;
public:
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMYC_JSON_DOCUMENT_SIZE)
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE)
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
void setMethod(WebRequestMethodComposite method){ _method = method; }
@ -127,15 +127,8 @@ public:
virtual void handleRequest(AsyncWebServerRequest *request) override final {
if(_onRequest) {
if (request->_tempObject != NULL) {
DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize);
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
if(!error) {
JsonObject json = jsonBuffer.as<JsonObject>();
_onRequest(request, json);
return;
}
_onRequest(request);
return;
}
request->send(_contentLength > _maxContentLength ? 413 : 400);
} else {

View File

@ -3,7 +3,7 @@
*/
/*
* @title WLED project sketch
* @version 0.9.0-b1
* @version 0.9.0-b2
* @author Christian Schwinne
*/
@ -32,7 +32,6 @@
//to toggle usb serial debug (un)comment the following line
//#define WLED_DEBUG
//library inclusions
#include <Arduino.h>
#ifdef ESP8266
@ -85,6 +84,7 @@
#endif
#ifdef ARDUINO_ARCH_ESP32
#undef WLED_USE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet
/*#ifndef WLED_DISABLE_INFRARED
#include <IRremote.h>
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
@ -98,8 +98,8 @@
//version code in format yymmddb (b = daily build)
#define VERSION 1912131
char versionString[] = "0.9.0-b1";
#define VERSION 1912211
char versionString[] = "0.9.0-b2";
//AP and OTA default passwords (for maximum change them!)

View File

@ -62,10 +62,11 @@ void onAlexaChange(EspalexaDevice* dev)
} else //color
{
uint32_t color = espalexaDevice->getRGB();
col[3] = ((color >> 24) & 0xFF); // white color from Alexa is "pure white only"
col[0] = ((color >> 16) & 0xFF);
col[1] = ((color >> 8) & 0xFF);
col[2] = (color & 0xFF);
if (useRGBW) colorRGBtoRGBW(col);
if (useRGBW && col[3] == 0) colorRGBtoRGBW(col); // do not touch white value if EspalexaDevice.cpp did set the white channel
colorUpdated(10);
}
}

View File

@ -165,6 +165,6 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw)
float low = minf(rgb[0],minf(rgb[1],rgb[2]));
float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
if (high < 0.1f) return;
float sat = 255.0f * ((high - low) / high);
float sat = 100.0f * ((high - low) / high);; // maximum saturation is 100 (corrected from 255)
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
}

View File

@ -102,9 +102,20 @@ void initServer()
serveJson(request);
});
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request, JsonObject root) {
if (root.isNull()){request->send(500, "application/json", "{\"error\":\"Parsing failed\"}"); return;}
if (deserializeState(root)) { serveJson(request); return; } //if JSON contains "v" (verbose response)
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) {
bool verboseResponse = false;
{ //scope JsonDocument so it releases its buffer
DynamicJsonDocument jsonBuffer(8192);
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
JsonObject root = jsonBuffer.as<JsonObject>();
if (error || root.isNull()) {
request->send(400, "application/json", "{\"error\":10}"); return;
}
verboseResponse = deserializeState(root);
}
if (verboseResponse) { //if JSON contains "v"
serveJson(request); return;
}
request->send(200, "application/json", "{\"success\":true}");
});
server.addHandler(handler);

View File

@ -88,8 +88,8 @@ bool deserializeState(JsonObject root)
int ps = root["ps"] | -1;
if (ps >= 0) applyPreset(ps);
int cy = root["pl"] | -1;
presetCyclingEnabled = (cy >= 0);
int cy = root["pl"] | -2;
if (cy > -2) presetCyclingEnabled = (cy >= 0);
JsonObject ccnf = root["ccnf"];
presetCycleMin = ccnf["min"] | presetCycleMin;
presetCycleMax = ccnf["max"] | presetCycleMax;