Send websockets on every state change
This commit is contained in:
parent
801df94446
commit
dc01c907f1
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
### Builds after release 0.12.0
|
### Builds after release 0.12.0
|
||||||
|
|
||||||
|
#### Build 2107020
|
||||||
|
|
||||||
|
- Send websockets on every state change
|
||||||
|
- Improved Aurora effect
|
||||||
|
|
||||||
#### Build 2107011
|
#### Build 2107011
|
||||||
|
|
||||||
- Added MQTT button feedback option (PR #2011)
|
- Added MQTT button feedback option (PR #2011)
|
||||||
|
@ -3957,7 +3957,6 @@ uint16_t WS2812FX::mode_tv_simulator(void) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//CONFIG
|
//CONFIG
|
||||||
#define BACKLIGHT 5
|
|
||||||
#define W_MAX_COUNT 20 //Number of simultaneous waves
|
#define W_MAX_COUNT 20 //Number of simultaneous waves
|
||||||
#define W_MAX_SPEED 6 //Higher number, higher speed
|
#define W_MAX_SPEED 6 //Higher number, higher speed
|
||||||
#define W_WIDTH_FACTOR 6 //Higher number, smaller waves
|
#define W_WIDTH_FACTOR 6 //Higher number, smaller waves
|
||||||
@ -4082,9 +4081,13 @@ uint16_t WS2812FX::mode_aurora(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t backlight = 1; //dimmer backlight if less active colors
|
||||||
|
if (SEGCOLOR(0)) backlight++;
|
||||||
|
if (SEGCOLOR(1)) backlight++;
|
||||||
|
if (SEGCOLOR(2)) backlight++;
|
||||||
//Loop through LEDs to determine color
|
//Loop through LEDs to determine color
|
||||||
for(int i = 0; i < SEGLEN; i++) {
|
for(int i = 0; i < SEGLEN; i++) {
|
||||||
CRGB mixedRgb = CRGB(BACKLIGHT, BACKLIGHT, BACKLIGHT);
|
CRGB mixedRgb = CRGB(backlight, backlight, backlight);
|
||||||
|
|
||||||
//For each LED we must check each wave if it is "active" at this position.
|
//For each LED we must check each wave if it is "active" at this position.
|
||||||
//If there are multiple waves active on a LED we multiply their values.
|
//If there are multiple waves active on a LED we multiply their values.
|
||||||
@ -4096,7 +4099,7 @@ uint16_t WS2812FX::mode_aurora(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2], BACKLIGHT);
|
setPixelColor(i, mixedRgb[0], mixedRgb[1], mixedRgb[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
|
22
wled00/FX.h
22
wled00/FX.h
@ -320,6 +320,27 @@ class WS2812FX {
|
|||||||
vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||||
return vLength;
|
return vLength;
|
||||||
}
|
}
|
||||||
|
uint8_t differs(Segment& b) {
|
||||||
|
uint8_t d = 0;
|
||||||
|
if (start != b.start) d |= SEG_DIFFERS_BOUNDS;
|
||||||
|
if (stop != b.stop) d |= SEG_DIFFERS_BOUNDS;
|
||||||
|
if (offset != b.offset) d |= SEG_DIFFERS_GSO;
|
||||||
|
if (grouping != b.grouping) d |= SEG_DIFFERS_GSO;
|
||||||
|
if (spacing != b.spacing) d |= SEG_DIFFERS_GSO;
|
||||||
|
if (opacity != b.opacity) d |= SEG_DIFFERS_BRI;
|
||||||
|
if (mode != b.mode) d |= SEG_DIFFERS_FX;
|
||||||
|
if (speed != b.speed) d |= SEG_DIFFERS_FX;
|
||||||
|
if (intensity != b.intensity) d |= SEG_DIFFERS_FX;
|
||||||
|
if (palette != b.palette) d |= SEG_DIFFERS_FX;
|
||||||
|
|
||||||
|
if ((options & 0b00101111) != (b.options & 0b00101111)) d |= SEG_DIFFERS_OPT;
|
||||||
|
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
||||||
|
{
|
||||||
|
if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
} segment;
|
} segment;
|
||||||
|
|
||||||
// segment runtime parameters
|
// segment runtime parameters
|
||||||
@ -613,7 +634,6 @@ class WS2812FX {
|
|||||||
gammaCorrectBri = false,
|
gammaCorrectBri = false,
|
||||||
gammaCorrectCol = true,
|
gammaCorrectCol = true,
|
||||||
applyToAllSelected = true,
|
applyToAllSelected = true,
|
||||||
segmentsAreIdentical(Segment* a, Segment* b),
|
|
||||||
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p),
|
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p),
|
||||||
// return true if the strip is being sent pixel updates
|
// return true if the strip is being sent pixel updates
|
||||||
isUpdating(void);
|
isUpdating(void);
|
||||||
|
@ -1010,23 +1010,6 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8
|
|||||||
return crgb_to_col(fastled_col);
|
return crgb_to_col(fastled_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@returns `true` if color, mode, speed, intensity and palette match
|
|
||||||
bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b)
|
|
||||||
{
|
|
||||||
//if (a->start != b->start) return false;
|
|
||||||
//if (a->stop != b->stop) return false;
|
|
||||||
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
|
||||||
{
|
|
||||||
if (a->colors[i] != b->colors[i]) return false;
|
|
||||||
}
|
|
||||||
if (a->mode != b->mode) return false;
|
|
||||||
if (a->speed != b->speed) return false;
|
|
||||||
if (a->intensity != b->intensity) return false;
|
|
||||||
if (a->palette != b->palette) return false;
|
|
||||||
//if (a->getOption(SEG_OPTION_REVERSED) != b->getOption(SEG_OPTION_REVERSED)) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//load custom mapping table from JSON file
|
//load custom mapping table from JSON file
|
||||||
void WS2812FX::deserializeMap(void) {
|
void WS2812FX::deserializeMap(void) {
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
#define NOTIFIER_CALL_MODE_PRESET_CYCLE 8
|
#define NOTIFIER_CALL_MODE_PRESET_CYCLE 8
|
||||||
#define NOTIFIER_CALL_MODE_BLYNK 9
|
#define NOTIFIER_CALL_MODE_BLYNK 9
|
||||||
#define NOTIFIER_CALL_MODE_ALEXA 10
|
#define NOTIFIER_CALL_MODE_ALEXA 10
|
||||||
|
#define NOTIFIER_CALL_MODE_WS_SEND 11 //special call mode, not for notifier, updates websocket only
|
||||||
|
|
||||||
//RGB to RGBW conversion mode
|
//RGB to RGBW conversion mode
|
||||||
#define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider
|
#define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider
|
||||||
@ -195,6 +196,14 @@
|
|||||||
#define SEG_OPTION_FREEZE 5 //Segment contents will not be refreshed
|
#define SEG_OPTION_FREEZE 5 //Segment contents will not be refreshed
|
||||||
#define SEG_OPTION_TRANSITIONAL 7
|
#define SEG_OPTION_TRANSITIONAL 7
|
||||||
|
|
||||||
|
//Segment differs return byte
|
||||||
|
#define SEG_DIFFERS_BRI 0x01
|
||||||
|
#define SEG_DIFFERS_OPT 0x02
|
||||||
|
#define SEG_DIFFERS_COL 0x04
|
||||||
|
#define SEG_DIFFERS_FX 0x08
|
||||||
|
#define SEG_DIFFERS_BOUNDS 0x10
|
||||||
|
#define SEG_DIFFERS_GSO 0x20
|
||||||
|
|
||||||
//Playlist option byte
|
//Playlist option byte
|
||||||
#define PL_OPTION_SHUFFLE 0x01
|
#define PL_OPTION_SHUFFLE 0x01
|
||||||
|
|
||||||
|
300
wled00/json.cpp
300
wled00/json.cpp
@ -9,158 +9,160 @@
|
|||||||
void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||||
{
|
{
|
||||||
byte id = elem["id"] | it;
|
byte id = elem["id"] | it;
|
||||||
if (id < strip.getMaxSegments())
|
if (id >= strip.getMaxSegments()) return;
|
||||||
{
|
|
||||||
WS2812FX::Segment& seg = strip.getSegment(id);
|
|
||||||
uint16_t start = elem[F("start")] | seg.start;
|
|
||||||
int stop = elem["stop"] | -1;
|
|
||||||
|
|
||||||
if (stop < 0) {
|
WS2812FX::Segment& seg = strip.getSegment(id);
|
||||||
uint16_t len = elem[F("len")];
|
//WS2812FX::Segment prev;
|
||||||
stop = (len > 0) ? start + len : seg.stop;
|
//prev = seg; //make a backup so we can tell if something changed
|
||||||
}
|
|
||||||
uint16_t grp = elem[F("grp")] | seg.grouping;
|
|
||||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
|
||||||
strip.setSegment(id, start, stop, grp, spc);
|
|
||||||
seg.offset = elem[F("of")] | seg.offset;
|
|
||||||
if (stop > start && seg.offset > stop - start -1) seg.offset = stop - start -1;
|
|
||||||
|
|
||||||
int segbri = elem["bri"] | -1;
|
uint16_t start = elem[F("start")] | seg.start;
|
||||||
if (segbri == 0) {
|
int stop = elem["stop"] | -1;
|
||||||
seg.setOption(SEG_OPTION_ON, 0, id);
|
|
||||||
} else if (segbri > 0) {
|
|
||||||
seg.setOpacity(segbri, id);
|
|
||||||
seg.setOption(SEG_OPTION_ON, 1, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
seg.setOption(SEG_OPTION_ON, elem["on"] | seg.getOption(SEG_OPTION_ON), id);
|
|
||||||
|
|
||||||
JsonArray colarr = elem["col"];
|
|
||||||
if (!colarr.isNull())
|
|
||||||
{
|
|
||||||
for (uint8_t i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
int rgbw[] = {0,0,0,0};
|
|
||||||
bool colValid = false;
|
|
||||||
JsonArray colX = colarr[i];
|
|
||||||
if (colX.isNull()) {
|
|
||||||
byte brgbw[] = {0,0,0,0};
|
|
||||||
const char* hexCol = colarr[i];
|
|
||||||
if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400
|
|
||||||
int kelvin = colarr[i] | -1;
|
|
||||||
if (kelvin < 0) continue;
|
|
||||||
if (kelvin == 0) seg.setColor(i, 0, id);
|
|
||||||
if (kelvin > 0) colorKtoRGB(kelvin, brgbw);
|
|
||||||
colValid = true;
|
|
||||||
} else { //HEX string, e.g. "FFAA00"
|
|
||||||
colValid = colorFromHexString(brgbw, hexCol);
|
|
||||||
}
|
|
||||||
for (uint8_t c = 0; c < 4; c++) rgbw[c] = brgbw[c];
|
|
||||||
} else { //Array of ints (RGB or RGBW color), e.g. [255,160,0]
|
|
||||||
byte sz = colX.size();
|
|
||||||
if (sz == 0) continue; //do nothing on empty array
|
|
||||||
|
|
||||||
byte cp = copyArray(colX, rgbw, 4);
|
|
||||||
if (cp == 1 && rgbw[0] == 0)
|
|
||||||
seg.setColor(i, 0, id);
|
|
||||||
colValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!colValid) continue;
|
|
||||||
if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
|
|
||||||
{
|
|
||||||
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
|
|
||||||
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
|
|
||||||
} else { //normal case, apply directly to segment
|
|
||||||
seg.setColor(i, ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))), id);
|
|
||||||
if (seg.mode == FX_MODE_STATIC) strip.trigger(); //instant refresh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// lx parser
|
|
||||||
#ifdef WLED_ENABLE_LOXONE
|
|
||||||
int lx = elem[F("lx")] | -1;
|
|
||||||
if (lx > 0) {
|
|
||||||
parseLxJson(lx, id, false);
|
|
||||||
}
|
|
||||||
int ly = elem[F("ly")] | -1;
|
|
||||||
if (ly > 0) {
|
|
||||||
parseLxJson(ly, id, true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
|
||||||
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
|
||||||
seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED));
|
|
||||||
seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR ));
|
|
||||||
|
|
||||||
//temporary, strip object gets updated via colorUpdated()
|
|
||||||
if (id == strip.getMainSegmentId()) {
|
|
||||||
byte effectPrev = effectCurrent;
|
|
||||||
effectCurrent = elem[F("fx")] | effectCurrent;
|
|
||||||
if (!presetId && effectCurrent != effectPrev) unloadPlaylist(); //stop playlist if active and FX changed manually
|
|
||||||
effectSpeed = elem[F("sx")] | effectSpeed;
|
|
||||||
effectIntensity = elem[F("ix")] | effectIntensity;
|
|
||||||
effectPalette = elem["pal"] | effectPalette;
|
|
||||||
} else { //permanent
|
|
||||||
byte fx = elem[F("fx")] | seg.mode;
|
|
||||||
if (fx != seg.mode && fx < strip.getModeCount()) {
|
|
||||||
strip.setMode(id, fx);
|
|
||||||
if (!presetId) unloadPlaylist(); //stop playlist if active and FX changed manually
|
|
||||||
}
|
|
||||||
seg.speed = elem[F("sx")] | seg.speed;
|
|
||||||
seg.intensity = elem[F("ix")] | seg.intensity;
|
|
||||||
seg.palette = elem["pal"] | seg.palette;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonArray iarr = elem[F("i")]; //set individual LEDs
|
|
||||||
if (!iarr.isNull()) {
|
|
||||||
strip.setPixelSegment(id);
|
|
||||||
|
|
||||||
//freeze and init to black
|
|
||||||
if (!seg.getOption(SEG_OPTION_FREEZE)) {
|
|
||||||
seg.setOption(SEG_OPTION_FREEZE, true);
|
|
||||||
strip.fill(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t start = 0, stop = 0;
|
|
||||||
byte set = 0; //0 nothing set, 1 start set, 2 range set
|
|
||||||
|
|
||||||
for (uint16_t i = 0; i < iarr.size(); i++) {
|
|
||||||
if(iarr[i].is<JsonInteger>()) {
|
|
||||||
if (!set) {
|
|
||||||
start = iarr[i];
|
|
||||||
set = 1;
|
|
||||||
} else {
|
|
||||||
stop = iarr[i];
|
|
||||||
set = 2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
JsonArray icol = iarr[i];
|
|
||||||
if (icol.isNull()) break;
|
|
||||||
|
|
||||||
byte sz = icol.size();
|
|
||||||
if (sz == 0 || sz > 4) break;
|
|
||||||
|
|
||||||
int rgbw[] = {0,0,0,0};
|
|
||||||
copyArray(icol, rgbw);
|
|
||||||
|
|
||||||
if (set < 2) stop = start + 1;
|
|
||||||
for (uint16_t i = start; i < stop; i++) {
|
|
||||||
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
|
|
||||||
}
|
|
||||||
if (!set) start++;
|
|
||||||
set = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strip.setPixelSegment(255);
|
|
||||||
strip.trigger();
|
|
||||||
} else { //return to regular effect
|
|
||||||
seg.setOption(SEG_OPTION_FREEZE, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (stop < 0) {
|
||||||
|
uint16_t len = elem[F("len")];
|
||||||
|
stop = (len > 0) ? start + len : seg.stop;
|
||||||
}
|
}
|
||||||
|
uint16_t grp = elem[F("grp")] | seg.grouping;
|
||||||
|
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||||
|
strip.setSegment(id, start, stop, grp, spc);
|
||||||
|
seg.offset = elem[F("of")] | seg.offset;
|
||||||
|
if (stop > start && seg.offset > stop - start -1) seg.offset = stop - start -1;
|
||||||
|
|
||||||
|
int segbri = elem["bri"] | -1;
|
||||||
|
if (segbri == 0) {
|
||||||
|
seg.setOption(SEG_OPTION_ON, 0, id);
|
||||||
|
} else if (segbri > 0) {
|
||||||
|
seg.setOpacity(segbri, id);
|
||||||
|
seg.setOption(SEG_OPTION_ON, 1, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
seg.setOption(SEG_OPTION_ON, elem["on"] | seg.getOption(SEG_OPTION_ON), id);
|
||||||
|
|
||||||
|
JsonArray colarr = elem["col"];
|
||||||
|
if (!colarr.isNull())
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
int rgbw[] = {0,0,0,0};
|
||||||
|
bool colValid = false;
|
||||||
|
JsonArray colX = colarr[i];
|
||||||
|
if (colX.isNull()) {
|
||||||
|
byte brgbw[] = {0,0,0,0};
|
||||||
|
const char* hexCol = colarr[i];
|
||||||
|
if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400
|
||||||
|
int kelvin = colarr[i] | -1;
|
||||||
|
if (kelvin < 0) continue;
|
||||||
|
if (kelvin == 0) seg.setColor(i, 0, id);
|
||||||
|
if (kelvin > 0) colorKtoRGB(kelvin, brgbw);
|
||||||
|
colValid = true;
|
||||||
|
} else { //HEX string, e.g. "FFAA00"
|
||||||
|
colValid = colorFromHexString(brgbw, hexCol);
|
||||||
|
}
|
||||||
|
for (uint8_t c = 0; c < 4; c++) rgbw[c] = brgbw[c];
|
||||||
|
} else { //Array of ints (RGB or RGBW color), e.g. [255,160,0]
|
||||||
|
byte sz = colX.size();
|
||||||
|
if (sz == 0) continue; //do nothing on empty array
|
||||||
|
|
||||||
|
byte cp = copyArray(colX, rgbw, 4);
|
||||||
|
if (cp == 1 && rgbw[0] == 0)
|
||||||
|
seg.setColor(i, 0, id);
|
||||||
|
colValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!colValid) continue;
|
||||||
|
if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
|
||||||
|
{
|
||||||
|
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
|
||||||
|
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
|
||||||
|
} else { //normal case, apply directly to segment
|
||||||
|
seg.setColor(i, ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))), id);
|
||||||
|
if (seg.mode == FX_MODE_STATIC) strip.trigger(); //instant refresh
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lx parser
|
||||||
|
#ifdef WLED_ENABLE_LOXONE
|
||||||
|
int lx = elem[F("lx")] | -1;
|
||||||
|
if (lx > 0) {
|
||||||
|
parseLxJson(lx, id, false);
|
||||||
|
}
|
||||||
|
int ly = elem[F("ly")] | -1;
|
||||||
|
if (ly > 0) {
|
||||||
|
parseLxJson(ly, id, true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
||||||
|
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
||||||
|
seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED));
|
||||||
|
seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR ));
|
||||||
|
|
||||||
|
//temporary, strip object gets updated via colorUpdated()
|
||||||
|
if (id == strip.getMainSegmentId()) {
|
||||||
|
byte effectPrev = effectCurrent;
|
||||||
|
effectCurrent = elem[F("fx")] | effectCurrent;
|
||||||
|
if (!presetId && effectCurrent != effectPrev) unloadPlaylist(); //stop playlist if active and FX changed manually
|
||||||
|
effectSpeed = elem[F("sx")] | effectSpeed;
|
||||||
|
effectIntensity = elem[F("ix")] | effectIntensity;
|
||||||
|
effectPalette = elem["pal"] | effectPalette;
|
||||||
|
} else { //permanent
|
||||||
|
byte fx = elem[F("fx")] | seg.mode;
|
||||||
|
if (fx != seg.mode && fx < strip.getModeCount()) {
|
||||||
|
strip.setMode(id, fx);
|
||||||
|
if (!presetId) unloadPlaylist(); //stop playlist if active and FX changed manually
|
||||||
|
}
|
||||||
|
seg.speed = elem[F("sx")] | seg.speed;
|
||||||
|
seg.intensity = elem[F("ix")] | seg.intensity;
|
||||||
|
seg.palette = elem["pal"] | seg.palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray iarr = elem[F("i")]; //set individual LEDs
|
||||||
|
if (!iarr.isNull()) {
|
||||||
|
strip.setPixelSegment(id);
|
||||||
|
|
||||||
|
//freeze and init to black
|
||||||
|
if (!seg.getOption(SEG_OPTION_FREEZE)) {
|
||||||
|
seg.setOption(SEG_OPTION_FREEZE, true);
|
||||||
|
strip.fill(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t start = 0, stop = 0;
|
||||||
|
byte set = 0; //0 nothing set, 1 start set, 2 range set
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < iarr.size(); i++) {
|
||||||
|
if(iarr[i].is<JsonInteger>()) {
|
||||||
|
if (!set) {
|
||||||
|
start = iarr[i];
|
||||||
|
set = 1;
|
||||||
|
} else {
|
||||||
|
stop = iarr[i];
|
||||||
|
set = 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
JsonArray icol = iarr[i];
|
||||||
|
if (icol.isNull()) break;
|
||||||
|
|
||||||
|
byte sz = icol.size();
|
||||||
|
if (sz == 0 || sz > 4) break;
|
||||||
|
|
||||||
|
int rgbw[] = {0,0,0,0};
|
||||||
|
copyArray(icol, rgbw);
|
||||||
|
|
||||||
|
if (set < 2) stop = start + 1;
|
||||||
|
for (uint16_t i = start; i < stop; i++) {
|
||||||
|
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
|
||||||
|
}
|
||||||
|
if (!set) start++;
|
||||||
|
set = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strip.setPixelSegment(255);
|
||||||
|
strip.trigger();
|
||||||
|
} else { //return to regular effect
|
||||||
|
seg.setOption(SEG_OPTION_FREEZE, false);
|
||||||
|
}
|
||||||
|
return; // seg.hasChanged(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deserializeState(JsonObject root, byte presetId)
|
bool deserializeState(JsonObject root, byte presetId)
|
||||||
@ -300,6 +302,8 @@ bool deserializeState(JsonObject root, byte presetId)
|
|||||||
if (!playlist.isNull()) {
|
if (!playlist.isNull()) {
|
||||||
loadPlaylist(playlist, presetId);
|
loadPlaylist(playlist, presetId);
|
||||||
noNotification = true; //do not notify both for this request and the first playlist entry
|
noNotification = true; //do not notify both for this request and the first playlist entry
|
||||||
|
} else {
|
||||||
|
interfaceUpdateCallMode = NOTIFIER_CALL_MODE_WS_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
|
||||||
|
@ -115,7 +115,7 @@ void colorUpdated(int callMode)
|
|||||||
|
|
||||||
notify(callMode);
|
notify(callMode);
|
||||||
|
|
||||||
//set flag to update blynk and mqtt
|
//set flag to update blynk, ws and mqtt
|
||||||
interfaceUpdateCallMode = callMode;
|
interfaceUpdateCallMode = callMode;
|
||||||
} else {
|
} else {
|
||||||
if (nightlightActive && !nightlightActiveOld &&
|
if (nightlightActive && !nightlightActiveOld &&
|
||||||
@ -180,6 +180,11 @@ void colorUpdated(int callMode)
|
|||||||
void updateInterfaces(uint8_t callMode)
|
void updateInterfaces(uint8_t callMode)
|
||||||
{
|
{
|
||||||
sendDataWs();
|
sendDataWs();
|
||||||
|
if (callMode == NOTIFIER_CALL_MODE_WS_SEND) {
|
||||||
|
lastInterfaceUpdate = millis();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_ALEXA
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) {
|
if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) {
|
||||||
espalexaDevice->setValue(bri);
|
espalexaDevice->setValue(bri);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2107011
|
#define VERSION 2107020
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
|
@ -41,7 +41,8 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
|||||||
|
|
||||||
verboseResponse = deserializeState(root);
|
verboseResponse = deserializeState(root);
|
||||||
}
|
}
|
||||||
if (verboseResponse || millis() - lastInterfaceUpdate < 1900) sendDataWs(client); //update if it takes longer than 100ms until next "broadcast"
|
//update if it takes longer than 300ms until next "broadcast"
|
||||||
|
if (verboseResponse && (millis() - lastInterfaceUpdate < 1700 || !interfaceUpdateCallMode)) sendDataWs(client);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//message is comprised of multiple frames or the frame is split into multiple packets
|
//message is comprised of multiple frames or the frame is split into multiple packets
|
||||||
|
Loading…
Reference in New Issue
Block a user