Merge branch 'master' into dev.

Few other modifications.

Conflicts:
	package.json
	platformio.ini
	wled00/FX.h
	wled00/FX_fcn.cpp
	wled00/bus_wrapper.h
	wled00/cfg.cpp
	wled00/data/index.css
	wled00/data/index.htm
	wled00/data/settings_leds.htm
	wled00/html_other.h
	wled00/html_settings.h
	wled00/html_ui.h
	wled00/json.cpp
	wled00/set.cpp
	wled00/wled.cpp
	wled00/wled.h
	wled00/wled_eeprom.cpp
	wled00/wled_server.cpp
	wled00/xml.cpp
This commit is contained in:
Blaz Kristan 2021-03-29 23:12:19 +02:00
commit 6ace46eece
30 changed files with 2451 additions and 2275 deletions

View File

@ -1,6 +1,6 @@
name: PlatformIO CI name: PlatformIO CI
on: [push] on: [push, pull_request]
jobs: jobs:
build: build:

View File

@ -1,6 +1,42 @@
## WLED changelog ## WLED changelog
### Development versions after 0.11.1 release ### Development versions between 0.11.1 and 0.12.0 releases
#### Build 2103290
- Version bump to 0.12.0-b4 "Hikari"
- Experimental use of espressif32@3.1.1
- Fixed RGBW mode disabled after LED settings saved
- Fixed infrared support not compiled in if IRPIN is not defined
#### Build 2103230
- Fixed current estimation
#### Build 2103220
- Version bump to 0.12.0-b2 "Hikari"
- Worked around an issue causing a critical decrease in framerate (wled.cpp l.240 block)
- Bump to Espalexa v2.7.0, fixing discovery
#### Build 2103210
- Version bump to 0.12.0-b1 "Hikari"
- More colors visible on Palette preview
- Fixed chevron icon not included
- Fixed color order override
- Cleanup
#### Build 2103200
- Version bump to 0.12.0-b0 "Hikari"
- Added palette preview and search (PR #1637)
- Added Reverse checkbox for PWM busses - reverses logic level for on
- Fixed various problems with the Playlist feature (PR #1724)
- Replaced "Layer" icon with "i" icon for Info button
- Chunchun effect more fitting for various segment lengths (PR #1804)
- Removed global reverse (in favor of individual bus reverse)
- Removed some unused icons from UI icon font
#### Build 2103130 #### Build 2103130
@ -204,7 +240,7 @@
#### Build 2011153 #### Build 2011153
- Fixed an ESP32 end-of-file issue - Fixed an ESP32 end-of-file issue
- Fixed useRGBW not read from cfg.json - Fixed strip.isRgbw not read from cfg.json
#### Build 2011152 #### Build 2011152

View File

@ -1,6 +1,6 @@
{ {
"name": "wled", "name": "wled",
"version": "0.12.0-b3", "version": "0.12.0-b4",
"description": "Tools for WLED project", "description": "Tools for WLED project",
"main": "tools/cdata.js", "main": "tools/cdata.js",
"directories": { "directories": {

View File

@ -9,10 +9,10 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Travis CI binaries (comment this out with a ';' when building for your own board) # Travis CI binaries (comment this out with a ';' when building for your own board)
default_envs = travis_esp8266, travis_esp32 ;default_envs = travis_esp8266, travis_esp32
# Release binaries # Release binaries
; default_envs = nodemcuv2, esp01_1m_full, esp32dev default_envs = nodemcuv2, esp01_1m_full, esp32dev, esp32_eth
# Single binaries (uncomment your board) # Single binaries (uncomment your board)
; default_envs = nodemcuv2 ; default_envs = nodemcuv2
@ -259,7 +259,7 @@ build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
[env:esp32dev] [env:esp32dev]
board = esp32dev board = esp32dev
platform = espressif32@2.0 platform = espressif32@3.1.1
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} build_flags = ${common.build_flags_esp32}
lib_ignore = lib_ignore =
@ -268,7 +268,7 @@ lib_ignore =
[env:esp32_eth] [env:esp32_eth]
board = esp32-poe board = esp32-poe
platform = espressif32@2.0 platform = espressif32@3.1.1
upload_speed = 921600 upload_speed = 921600
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 build_flags = ${common.build_flags_esp32} -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
@ -346,7 +346,7 @@ build_flags = ${common.build_flags_esp8266} -D LEDPIN=12 -D IRPIN=-1 -D RLYPIN=2
[env:custom32_TOUCHPIN_T0] [env:custom32_TOUCHPIN_T0]
board = esp32dev board = esp32dev
platform = espressif32@2.0 platform = espressif32@3.1.1
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp32} -D TOUCHPIN=T0 build_flags = ${common.build_flags_esp32} -D TOUCHPIN=T0
lib_ignore = lib_ignore =
@ -355,7 +355,7 @@ lib_ignore =
[env:wemos_shield_esp32] [env:wemos_shield_esp32]
board = esp32dev board = esp32dev
platform = espressif32@2.0 platform = espressif32@3.1.1
upload_port = /dev/cu.SLAB_USBtoUART upload_port = /dev/cu.SLAB_USBtoUART
monitor_port = /dev/cu.SLAB_USBtoUART monitor_port = /dev/cu.SLAB_USBtoUART
upload_speed = 460800 upload_speed = 460800
@ -372,7 +372,7 @@ build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39
lib_ignore = lib_ignore =
ESPAsyncTCP ESPAsyncTCP
ESPAsyncUDP ESPAsyncUDP
platform = espressif32@2.0 platform = espressif32@3.1.1
[env:sp501e] [env:sp501e]
board = esp_wroom_02 board = esp_wroom_02

View File

@ -0,0 +1,5 @@
Usermod to allow WLED to receive via UDP port from RGB.NET (and therefore add as a device to be controlled within artemis on PC)
This is only a very simple code to support a single led strip, it does not support the full function of the RGB.NET sketch for esp8266 only what is needed to be used with Artemis. It will show as a ws281x device in artemis when you provide the correct hostname or ip. Artemis queries the number of LEDs via the web interface (/config) but communication to set the LEDs is all done via the UDP interface.
To install, copy the usermod.cpp file to wled00 folder and recompile

View File

@ -0,0 +1,93 @@
/*
* RGB.NET (artemis) receiver
*
* This works via the UDP, http is not supported apart from reporting LED count
*
*
*/
#include "wled.h"
#include <WiFiUdp.h>
WiFiUDP UDP;
const unsigned int RGBNET_localUdpPort = 1872; // local port to listen on
unsigned char RGBNET_packet[770];
long lastTime = 0;
int delayMs = 10;
bool isRGBNETUDPEnabled;
void RGBNET_readValues() {
int RGBNET_packetSize = UDP.parsePacket();
if (RGBNET_packetSize) {
// receive incoming UDP packets
int sequenceNumber = UDP.read();
int channel = UDP.read();
//channel data is not used we only supports one channel
int len = UDP.read(RGBNET_packet, ledCount*3);
if(len==0){
return;
}
for (int i = 0; i < len; i=i+3) {
strip.setPixelColor(i/3, RGBNET_packet[i], RGBNET_packet[i+1], RGBNET_packet[i+2], 0);
}
//strip.show();
}
}
//update LED strip
void RGBNET_show() {
strip.show();
lastTime = millis();
}
//This function provides a json with info on the number of LEDs connected
// it is needed by artemis to know how many LEDs to display on the surface
void handleConfig(AsyncWebServerRequest *request)
{
String config = (String)"{\
\"channels\": [\
{\
\"channel\": 1,\
\"leds\": " + ledCount + "\
},\
{\
\"channel\": 2,\
\"leds\": " + "0" + "\
},\
{\
\"channel\": 3,\
\"leds\": " + "0" + "\
},\
{\
\"channel\": 4,\
\"leds\": " + "0" + "\
}\
]\
}";
request->send(200, "application/json", config);
}
void userSetup()
{
server.on("/config", HTTP_GET, [](AsyncWebServerRequest *request){
handleConfig(request);
});
}
void userConnected()
{
// new wifi, who dis?
UDP.begin(RGBNET_localUdpPort);
isRGBNETUDPEnabled = true;
}
void userLoop()
{
RGBNET_readValues();
if (millis()-lastTime > delayMs) {
RGBNET_show();
}
}

View File

@ -4,7 +4,7 @@ default_envs = d1_mini
[env:esp32dev] [env:esp32dev]
board = esp32dev board = esp32dev
platform = espressif32@2.0 platform = espressif32@3.1.1
build_unflags = ${common.build_unflags} build_unflags = ${common.build_unflags}
build_flags = build_flags =
${common.build_flags_esp32} ${common.build_flags_esp32}

View File

@ -604,10 +604,10 @@ class WS2812FX {
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void), show(void),
setRgbwPwm(void), setRgbwPwm(void),
// setColorOrder(uint8_t co),
setPixelSegment(uint8_t n); setPixelSegment(uint8_t n);
bool bool
isRgbw = false,
gammaCorrectBri = false, gammaCorrectBri = false,
gammaCorrectCol = true, gammaCorrectCol = true,
applyToAllSelected = true, applyToAllSelected = true,
@ -630,7 +630,6 @@ class WS2812FX {
getMaxSegments(void), getMaxSegments(void),
//getFirstSelectedSegment(void), //getFirstSelectedSegment(void),
getMainSegmentId(void), getMainSegmentId(void),
// getColorOrder(void),
gamma8(uint8_t), gamma8(uint8_t),
gamma8_cal(uint8_t, float), gamma8_cal(uint8_t, float),
get_random_wheel_index(uint8_t); get_random_wheel_index(uint8_t);
@ -805,7 +804,6 @@ class WS2812FX {
void handle_palette(void); void handle_palette(void);
bool bool
_useRgbw = false,
_triggered; _triggered;
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element

View File

@ -27,10 +27,6 @@
#include "FX.h" #include "FX.h"
#include "palettes.h" #include "palettes.h"
#ifndef PWM_INDEX
#define PWM_INDEX 0
#endif
/* /*
Custom per-LED mapping has moved! Custom per-LED mapping has moved!
@ -51,7 +47,7 @@
void WS2812FX::finalizeInit(void) void WS2812FX::finalizeInit(void)
{ {
RESET_RUNTIME; RESET_RUNTIME;
_useRgbw = false; isRgbw = false;
//if busses failed to load, add default (fresh install, FS issue, ...) //if busses failed to load, add default (fresh install, FS issue, ...)
if (busses.getNumBusses() == 0) { if (busses.getNumBusses() == 0) {
@ -81,7 +77,8 @@ void WS2812FX::finalizeInit(void)
for (uint8_t i=0; i<busses.getNumBusses(); i++) { for (uint8_t i=0; i<busses.getNumBusses(); i++) {
Bus *bus = busses.getBus(i); Bus *bus = busses.getBus(i);
if (bus == nullptr) continue; if (bus == nullptr) continue;
_useRgbw |= bus->isRgbw(); if (_length+bus->getLength() > MAX_LEDS) break;
isRgbw |= bus->isRgbw();
_length += bus->getLength(); _length += bus->getLength();
} }
/* /*
@ -161,8 +158,6 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
setPixelColor(n, r, g, b, w); setPixelColor(n, r, g, b, w);
} }
#define REV(i) (_length - 1 - (i))
//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring //used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
uint16_t WS2812FX::realPixelIndex(uint16_t i) { uint16_t WS2812FX::realPixelIndex(uint16_t i) {
int16_t iGroup = i * SEGMENT.groupLength(); int16_t iGroup = i * SEGMENT.groupLength();
@ -184,7 +179,7 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) {
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
{ {
//auto calculate white channel value if enabled //auto calculate white channel value if enabled
if (_useRgbw) { if (isRgbw) {
if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || (w == 0 && (rgbwMode == RGBW_MODE_DUAL || rgbwMode == RGBW_MODE_LEGACY))) if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || (w == 0 && (rgbwMode == RGBW_MODE_DUAL || rgbwMode == RGBW_MODE_LEGACY)))
{ {
//white value is set to lowest RGB channel //white value is set to lowest RGB channel
@ -290,7 +285,7 @@ void WS2812FX::show(void) {
} }
if (_useRgbw) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less if (isRgbw) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
{ {
powerSum *= 3; powerSum *= 3;
powerSum = powerSum >> 2; //same as /= 4 powerSum = powerSum >> 2; //same as /= 4

View File

@ -67,7 +67,7 @@ void onAlexaChange(EspalexaDevice* dev)
if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white
{ {
uint16_t ct = espalexaDevice->getCt(); uint16_t ct = espalexaDevice->getCt();
if (useRGBW) if (strip.isRgbw)
{ {
switch (ct) { //these values empirically look good on RGBW switch (ct) { //these values empirically look good on RGBW
case 199: col[0]=255; col[1]=255; col[2]=255; col[3]=255; break; case 199: col[0]=255; col[1]=255; col[2]=255; col[3]=255; break;

View File

@ -81,6 +81,10 @@ class Bus {
return false; return false;
} }
virtual bool skipFirstLed() {
return false;
}
inline uint8_t getType() { inline uint8_t getType() {
return _type; return _type;
} }
@ -177,6 +181,10 @@ class BusDigital : public Bus {
return _rgbw; return _rgbw;
} }
inline bool skipFirstLed() {
return (bool)_skip;
}
inline void reinit() { inline void reinit() {
PolyBus::begin(_busPtr, _iType, _pins); PolyBus::begin(_busPtr, _iType, _pins);
} }
@ -239,6 +247,7 @@ class BusPwm : public Bus {
ledcAttachPin(_pins[i], _ledcStart + i); ledcAttachPin(_pins[i], _ledcStart + i);
#endif #endif
} }
reversed = bc.reversed;
_valid = true; _valid = true;
}; };
@ -272,6 +281,7 @@ class BusPwm : public Bus {
uint8_t numPins = NUM_PWM_PINS(_type); uint8_t numPins = NUM_PWM_PINS(_type);
for (uint8_t i = 0; i < numPins; i++) { for (uint8_t i = 0; i < numPins; i++) {
uint8_t scaled = (_data[i] * _bri) / 255; uint8_t scaled = (_data[i] * _bri) / 255;
if (reversed) scaled = 255 - scaled;
#ifdef ESP8266 #ifdef ESP8266
analogWrite(_pins[i], scaled); analogWrite(_pins[i], scaled);
#else #else

View File

@ -102,8 +102,8 @@ void deserializeConfig() {
JsonArray ins = hw_led["ins"]; JsonArray ins = hw_led["ins"];
uint8_t s = 0; // bus iterator uint8_t s = 0; // bus iterator
bool skipFirst = skipFirstLed = false; bool skipFirst = false;
useRGBW = false; strip.isRgbw = false;
busses.removeAll(); busses.removeAll();
uint32_t mem = 0; uint32_t mem = 0;
for (JsonObject elm : ins) { for (JsonObject elm : ins) {
@ -125,12 +125,12 @@ void deserializeConfig() {
//if (start + length > ledCount) length = ledCount - start; //if (start + length > ledCount) length = ledCount - start;
uint8_t colorOrder = (int)elm[F("order")]; uint8_t colorOrder = (int)elm[F("order")];
//(this shouldn't have been in ins obj. but remains here for compatibility) //(this shouldn't have been in ins obj. but remains here for compatibility)
skipFirstLed |= skipFirst = (bool) elm[F("skip")]; skipFirst = (bool) elm[F("skip")];
uint8_t ledType = elm["type"] | TYPE_WS2812_RGB; uint8_t ledType = elm["type"] | TYPE_WS2812_RGB;
bool reversed = elm["rev"]; bool reversed = elm["rev"];
//RGBW mode is enabled if at least one of the strips is RGBW //RGBW mode is enabled if at least one of the strips is RGBW
if ((bool)elm[F("rgbw")]) SET_BIT(ledType,7); else UNSET_BIT(ledType,7); // hack bit 7 to indicate RGBW (as an override if necessary) if ((bool)elm[F("rgbw")]) SET_BIT(ledType,7); else UNSET_BIT(ledType,7); // hack bit 7 to indicate RGBW (as an override if necessary)
useRGBW |= (bool)elm[F("rgbw")]; strip.isRgbw |= (bool)elm[F("rgbw")]; //(strip.isRgbw || BusManager::isRgbw(ledType));
s++; s++;
lC += length; lC += length;
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst); BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst);
@ -139,6 +139,7 @@ void deserializeConfig() {
} }
if (lC > ledCount) ledCount = lC; // fix incorrect total length (honour analog setup) if (lC > ledCount) ledCount = lC; // fix incorrect total length (honour analog setup)
//strip.finalizeInit(); // will be done in WLED::beginStrip() //strip.finalizeInit(); // will be done in WLED::beginStrip()
if (hw_led["rev"]) busses.getBus(0)->reversed = true; //set 0.11 global reversed setting for first bus
JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0]; JsonObject hw_btn_ins_0 = hw[F("btn")][F("ins")][0];
CJSON(buttonEnabled, hw_btn_ins_0["type"]); CJSON(buttonEnabled, hw_btn_ins_0["type"]);
@ -456,7 +457,6 @@ void serializeConfig() {
hw_led[F("total")] = ledCount; hw_led[F("total")] = ledCount;
hw_led[F("maxpwr")] = strip.ablMilliampsMax; hw_led[F("maxpwr")] = strip.ablMilliampsMax;
hw_led[F("ledma")] = strip.milliampsPerLed; hw_led[F("ledma")] = strip.milliampsPerLed;
hw_led["rev"] = false; //strip.reverseMode; // not used anymore, reversing per-strip
hw_led[F("rgbwm")] = strip.rgbwMode; hw_led[F("rgbwm")] = strip.rgbwMode;
JsonArray hw_led_ins = hw_led.createNestedArray("ins"); JsonArray hw_led_ins = hw_led.createNestedArray("ins");
@ -474,7 +474,7 @@ void serializeConfig() {
for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]); for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]);
ins[F("order")] = bus->getColorOrder(); ins[F("order")] = bus->getColorOrder();
ins["rev"] = bus->reversed; ins["rev"] = bus->reversed;
ins[F("skip")] = skipFirstLed ? 1 : 0; ins[F("skip")] = bus->skipFirstLed();
ins["type"] = bus->getType(); ins["type"] = bus->getType();
ins[F("rgbw")] = bus->isRgbw(); ins[F("rgbw")] = bus->isRgbw();
} }

View File

@ -64,7 +64,7 @@ void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break; case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q; case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
} }
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col); if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
} }
void colorKtoRGB(uint16_t kelvin, byte* rgb) //white spectrum to rgb, calc void colorKtoRGB(uint16_t kelvin, byte* rgb) //white spectrum to rgb, calc
@ -111,7 +111,7 @@ void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb, bins
} else { } else {
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150 rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
} }
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col); if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
} }
#ifndef WLED_DISABLE_HUESYNC #ifndef WLED_DISABLE_HUESYNC
@ -169,7 +169,7 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
rgb[0] = 255.0*r; rgb[0] = 255.0*r;
rgb[1] = 255.0*g; rgb[1] = 255.0*g;
rgb[2] = 255.0*b; rgb[2] = 255.0*b;
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col); if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
} }
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy) void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)

View File

@ -915,7 +915,6 @@ input[type=number]::-webkit-outer-spin-button {
} }
.lstI { .lstI {
position: relative;
border-bottom: 1px solid var(--c-3); border-bottom: 1px solid var(--c-3);
display: flex; display: flex;
align-items: center; align-items: center;
@ -943,7 +942,6 @@ input[type=number]::-webkit-outer-spin-button {
} }
.lstI.sticky, .lstI.selected { .lstI.sticky, .lstI.selected {
/* position: sticky;*/
z-index: 1; z-index: 1;
} }

View File

@ -25,6 +25,7 @@
//check for pin conflicts //check for pin conflicts
if (nm=="L0" || nm=="L1" || n2=="L2" || n2=="L3" || n2=="L4" || nm=="RL" || nm=="BT" || nm=="IR" || nm=="AX") if (nm=="L0" || nm=="L1" || n2=="L2" || n2=="L3" || n2=="L4" || nm=="RL" || nm=="BT" || nm=="IR" || nm=="AX")
if (LCs[i].value!="" && LCs[i].value!="-1") { if (LCs[i].value!="" && LCs[i].value!="-1") {
/*if (LCs[i].value > 5 && LCs[i].value < 12) {alert("Sorry, pins 6-11 can not be used.");LCs[i].focus();return;}*/
if (d.um_p && d.um_p.some((e)=>e==parseInt(LCs[i].value,10))) {alert("Usermod/reserved pin conflict!");LCs[i].focus();return;} if (d.um_p && d.um_p.some((e)=>e==parseInt(LCs[i].value,10))) {alert("Usermod/reserved pin conflict!");LCs[i].focus();return;}
for (j=i+1; j<LCs.length; j++) for (j=i+1; j<LCs.length; j++)
{ {
@ -37,7 +38,7 @@
if (bquot > 100) {var msg = "Too many LEDs for me to handle!"; if (maxM < 10000) msg += "\n\rConsider using an ESP32."; alert(msg); return;} if (bquot > 100) {var msg = "Too many LEDs for me to handle!"; if (maxM < 10000) msg += "\n\rConsider using an ESP32."; alert(msg); return;}
if (d.Sf.reportValidity()) d.Sf.submit(); if (d.Sf.reportValidity()) d.Sf.submit();
} }
function S(){GetV();setABL(); d.getElementById('m1').innerHTML = maxM;} function S(){GetV();setABL();}
function enABL() function enABL()
{ {
var en = d.getElementById('able').checked; var en = d.getElementById('able').checked;
@ -65,6 +66,7 @@
case 255: d.Sf.LAsel.value = 255; break; case 255: d.Sf.LAsel.value = 255; break;
default: d.getElementById('LAdis').style.display = 'inline'; default: d.getElementById('LAdis').style.display = 'inline';
} }
d.getElementById('m1').innerHTML = maxM;
UI(); UI();
} }
//returns mem usage //returns mem usage
@ -74,8 +76,9 @@
if (maxM < 10000 && p0==3) { //8266 DMA uses 5x the mem if (maxM < 10000 && p0==3) { //8266 DMA uses 5x the mem
if (type > 29) return len*20; //RGBW if (type > 29) return len*20; //RGBW
return len*15; return len*15;
} else if (maxM > 10000) { //ESP32 RMT uses double buffer? } else if (maxM >= 10000) //ESP32 RMT uses double buffer?
if (type > 29) return len*8; //RGBW {
if (type > 29) return len*8; //RGBW
return len*6; return len*6;
} }
if (type > 29) return len*4; //RGBW if (type > 29) return len*4; //RGBW
@ -253,7 +256,7 @@ Color Order:
<br> <br>
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="${lastEnd(i)}" required />&nbsp; <span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="${lastEnd(i)}" required />&nbsp;
<div id="dig${i}" style="display:inline"> <div id="dig${i}" style="display:inline">
Count: <input type="number" name="LC${i}" min="0" max="2048" value="1" required oninput="UI()" /><br> Count: <input type="number" name="LC${i}" min="0" max="${maxPB}" value="1" required oninput="UI()" /><br>
Reverse (rotated 180°): <input type="checkbox" name="CV${i}"> Reverse (rotated 180°): <input type="checkbox" name="CV${i}">
</div> </div>
&nbsp;RGBW: <input id="ew${i}" type="checkbox" name="EW${i}"><br> &nbsp;RGBW: <input id="ew${i}" type="checkbox" name="EW${i}"><br>

View File

@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st
.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none} .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none}
</style></head><body><h2>WLED Software Update</h2><form method="POST" </style></head><body><h2>WLED Software Update</h2><form method="POST"
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()"> action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
Installed version: 0.12.0-b3<br>Download the latest binary: <a Installed version: 0.12.0-b4<br>Download the latest binary: <a
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"> src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
</a><br><input type="file" class="bt" name="update" accept=".bin" required><br> </a><br><input type="file" class="bt" name="update" accept=".bin" required><br>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -345,19 +345,19 @@ void decodeIR40(uint32_t code)
case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break;
case IR40_PINK : colorFromUint24(COLOR_PINK); break; case IR40_PINK : colorFromUint24(COLOR_PINK); break;
case IR40_WARMWHITE2 : { case IR40_WARMWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE2); } break; else colorFromUint24(COLOR_WARMWHITE2); } break;
case IR40_WARMWHITE : { case IR40_WARMWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE); } break; else colorFromUint24(COLOR_WARMWHITE); } break;
case IR40_WHITE : { case IR40_WHITE : {
if (useRGBW) { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_NEUTRALWHITE); } break; else colorFromUint24(COLOR_NEUTRALWHITE); } break;
case IR40_COLDWHITE : { case IR40_COLDWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE); } break; else colorFromUint24(COLOR_COLDWHITE); } break;
case IR40_COLDWHITE2 : { case IR40_COLDWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE2); } break; else colorFromUint24(COLOR_COLDWHITE2); } break;
case IR40_WPLUS : relativeChangeWhite(10); break; case IR40_WPLUS : relativeChangeWhite(10); break;
case IR40_WMINUS : relativeChangeWhite(-10, 5); break; case IR40_WMINUS : relativeChangeWhite(-10, 5); break;
@ -402,21 +402,21 @@ void decodeIR44(uint32_t code)
case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break;
case IR44_PINK : colorFromUint24(COLOR_PINK); break; case IR44_PINK : colorFromUint24(COLOR_PINK); break;
case IR44_WHITE : { case IR44_WHITE : {
if (useRGBW) { if (strip.isRgbw) {
if (col[3] > 0) col[3] = 0; if (col[3] > 0) col[3] = 0;
else { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; } else { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
} else colorFromUint24(COLOR_NEUTRALWHITE); } break; } else colorFromUint24(COLOR_NEUTRALWHITE); } break;
case IR44_WARMWHITE2 : { case IR44_WARMWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE2); } break; else colorFromUint24(COLOR_WARMWHITE2); } break;
case IR44_WARMWHITE : { case IR44_WARMWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_WARMWHITE); } break; else colorFromUint24(COLOR_WARMWHITE); } break;
case IR44_COLDWHITE : { case IR44_COLDWHITE : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE); } break; else colorFromUint24(COLOR_COLDWHITE); } break;
case IR44_COLDWHITE2 : { case IR44_COLDWHITE2 : {
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; } if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
else colorFromUint24(COLOR_COLDWHITE2); } break; else colorFromUint24(COLOR_COLDWHITE2); } break;
case IR44_REDPLUS : relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break; case IR44_REDPLUS : relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break;
case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break; case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break;

View File

@ -203,7 +203,7 @@ bool deserializeState(JsonObject root)
JsonObject nl = root["nl"]; JsonObject nl = root["nl"];
nightlightActive = nl["on"] | nightlightActive; nightlightActive = nl["on"] | nightlightActive;
nightlightDelayMins = nl[F("dur")] | nightlightDelayMins; nightlightDelayMins = nl[F("dur")] | nightlightDelayMins;
nightlightMode = nl[F("fade")] | nightlightMode; //deprecated, remove for v0.12.0 nightlightMode = nl[F("fade")] | nightlightMode; //deprecated, remove for v0.13.0
nightlightMode = nl[F("mode")] | nightlightMode; nightlightMode = nl[F("mode")] | nightlightMode;
nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri; nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri;
@ -320,8 +320,8 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
for (uint8_t i = 0; i < 3; i++) for (uint8_t i = 0; i < 3; i++)
{ {
if (id==strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment if (id==strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
if (i==0) colarr.add((unsigned long)((col[0]<<16) | (col[1]<<8) | col[2] | (useRGBW?col[3]<<24:0))); if (i==0) colarr.add((unsigned long)((col[0]<<16) | (col[1]<<8) | col[2] | (strip.isRgbw?col[3]<<24:0)));
else colarr.add((unsigned long)((colSec[0]<<16) | (colSec[1]<<8) | colSec[2] | (useRGBW?colSec[3]<<24:0))); else colarr.add((unsigned long)((colSec[0]<<16) | (colSec[1]<<8) | colSec[2] | (strip.isRgbw?colSec[3]<<24:0)));
else else
colarr.add((unsigned long)seg.colors[i]); colarr.add((unsigned long)seg.colors[i]);
} }
@ -332,15 +332,15 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
{ {
if (i == 0) { if (i == 0) {
colX.add(col[0]); colX.add(col[1]); colX.add(col[2]); if (useRGBW) colX.add(col[3]); colX.add(col[0]); colX.add(col[1]); colX.add(col[2]); if (strip.isRgbw) colX.add(col[3]);
} else { } else {
colX.add(colSec[0]); colX.add(colSec[1]); colX.add(colSec[2]); if (useRGBW) colX.add(colSec[3]); colX.add(colSec[0]); colX.add(colSec[1]); colX.add(colSec[2]); if (strip.isRgbw) colX.add(colSec[3]);
} }
} else { } else {
colX.add((seg.colors[i] >> 16) & 0xFF); colX.add((seg.colors[i] >> 16) & 0xFF);
colX.add((seg.colors[i] >> 8) & 0xFF); colX.add((seg.colors[i] >> 8) & 0xFF);
colX.add((seg.colors[i]) & 0xFF); colX.add((seg.colors[i]) & 0xFF);
if (useRGBW) if (strip.isRgbw)
colX.add((seg.colors[i] >> 24) & 0xFF); colX.add((seg.colors[i] >> 24) & 0xFF);
} }
} }
@ -443,8 +443,8 @@ void serializeInfo(JsonObject root)
JsonObject leds = root.createNestedObject("leds"); JsonObject leds = root.createNestedObject("leds");
leds[F("count")] = ledCount; leds[F("count")] = ledCount;
leds[F("rgbw")] = useRGBW; leds[F("rgbw")] = strip.isRgbw;
leds[F("wv")] = useRGBW && (strip.rgbwMode == RGBW_MODE_MANUAL_ONLY || strip.rgbwMode == RGBW_MODE_DUAL); //should a white channel slider be displayed? leds[F("wv")] = strip.isRgbw && (strip.rgbwMode == RGBW_MODE_MANUAL_ONLY || strip.rgbwMode == RGBW_MODE_DUAL); //should a white channel slider be displayed?
JsonArray leds_pin = leds.createNestedArray("pin"); JsonArray leds_pin = leds.createNestedArray("pin");
for (uint8_t s=0; s<busses.getNumBusses(); s++) { for (uint8_t s=0; s<busses.getNumBusses(); s++) {

View File

@ -50,14 +50,14 @@ void setAllLeds() {
{ {
strip.setBrightness(scaledBri(briT)); strip.setBrightness(scaledBri(briT));
} }
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY)
{ {
colorRGBtoRGBW(col); colorRGBtoRGBW(col);
colorRGBtoRGBW(colSec); colorRGBtoRGBW(colSec);
} }
strip.setColor(0, col[0], col[1], col[2], col[3]); strip.setColor(0, col[0], col[1], col[2], col[3]);
strip.setColor(1, colSec[0], colSec[1], colSec[2], colSec[3]); strip.setColor(1, colSec[0], colSec[1], colSec[2], colSec[3]);
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY)
{ {
col[3] = 0; colSec[3] = 0; col[3] = 0; colSec[3] = 0;
} }
@ -101,7 +101,7 @@ void colorUpdated(int callMode)
//Notifier: apply received FX to selected segments only if actually receiving FX //Notifier: apply received FX to selected segments only if actually receiving FX
if (someSel) strip.applyToAllSelected = receiveNotificationEffects; if (someSel) strip.applyToAllSelected = receiveNotificationEffects;
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette); bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette) || effectChanged;
bool colChanged = colorChanged(); bool colChanged = colorChanged();
//Notifier: apply received color to selected segments only if actually receiving color //Notifier: apply received color to selected segments only if actually receiving color
@ -109,6 +109,7 @@ void colorUpdated(int callMode)
if (fxChanged || colChanged) if (fxChanged || colChanged)
{ {
effectChanged = false;
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0; if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
if (isPreset) {isPreset = false;} if (isPreset) {isPreset = false;}
else {currentPreset = -1;} else {currentPreset = -1;}

View File

@ -83,8 +83,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
#endif #endif
if (btnPin>=0 && pinManager.isPinAllocated(btnPin)) pinManager.deallocatePin(btnPin); if (btnPin>=0 && pinManager.isPinAllocated(btnPin)) pinManager.deallocatePin(btnPin);
skipFirstLed = request->hasArg(F("SL")); bool skip = request->hasArg(F("SL"));
useRGBW = false; strip.isRgbw = false;
uint8_t colorOrder, type; uint8_t colorOrder, type;
uint16_t length, start; uint16_t length, start;
@ -108,7 +108,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
} }
type = request->arg(lt).toInt(); type = request->arg(lt).toInt();
if (request->hasArg(ew)) SET_BIT(type,7); else UNSET_BIT(type,7); // hack bit 7 to indicate RGBW (as a LED type override if necessary) if (request->hasArg(ew)) SET_BIT(type,7); else UNSET_BIT(type,7); // hack bit 7 to indicate RGBW (as a LED type override if necessary)
useRGBW |= request->hasArg(ew); strip.isRgbw = strip.isRgbw || request->hasArg(ew);
colorOrder = request->arg(co).toInt(); colorOrder = request->arg(co).toInt();
start = (request->hasArg(ls)) ? request->arg(ls).toInt() : t; start = (request->hasArg(ls)) ? request->arg(ls).toInt() : t;
@ -120,7 +120,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
// actual finalization is done in WLED::loop() (removing old busses and adding new) // actual finalization is done in WLED::loop() (removing old busses and adding new)
if (busConfigs[s] != nullptr) delete busConfigs[s]; if (busConfigs[s] != nullptr) delete busConfigs[s];
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder, request->hasArg(cv), skipFirstLed); busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder, request->hasArg(cv), skip);
doInitBusses = true; doInitBusses = true;
} }
@ -162,8 +162,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
strip.ablMilliampsMax = request->arg(F("MA")).toInt(); strip.ablMilliampsMax = request->arg(F("MA")).toInt();
strip.milliampsPerLed = request->arg(F("LA")).toInt(); strip.milliampsPerLed = request->arg(F("LA")).toInt();
// useRGBW = request->hasArg(F("EW")); strip.rgbwMode = request->arg(F("AW")).toInt();
strip.rgbwMode = request->arg(F("AW")).toInt(); // auto white calculation
briS = request->arg(F("CA")).toInt(); briS = request->arg(F("CA")).toInt();
@ -188,8 +187,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
t = request->arg(F("PB")).toInt(); t = request->arg(F("PB")).toInt();
if (t >= 0 && t < 4) strip.paletteBlend = t; if (t >= 0 && t < 4) strip.paletteBlend = t;
// strip.reverseMode = request->hasArg(F("RV"));
// skipFirstLed = request->hasArg(F("SL"));
t = request->arg(F("BF")).toInt(); t = request->arg(F("BF")).toInt();
if (t > 0) briMultiplier = t; if (t > 0) briMultiplier = t;
} }
@ -822,10 +819,22 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
{ {
WS2812FX::Segment& seg = strip.getSegment(i); WS2812FX::Segment& seg = strip.getSegment(i);
if (!seg.isSelected()) continue; if (!seg.isSelected()) continue;
if (effectCurrent != prevEffect) seg.mode = effectCurrent; if (effectCurrent != prevEffect) {
if (effectSpeed != prevSpeed) seg.speed = effectSpeed; seg.mode = effectCurrent;
if (effectIntensity != prevIntensity) seg.intensity = effectIntensity; effectChanged = true;
if (effectPalette != prevPalette) seg.palette = effectPalette; }
if (effectSpeed != prevSpeed) {
seg.speed = effectSpeed;
effectChanged = true;
}
if (effectIntensity != prevIntensity) {
seg.intensity = effectIntensity;
effectChanged = true;
}
if (effectPalette != prevPalette) {
seg.palette = effectPalette;
effectChanged = true;
}
} }
if (col0Changed) { if (col0Changed) {

View File

@ -10,7 +10,7 @@
*/ */
/* /*
* @title Espalexa library * @title Espalexa library
* @version 2.5.0 * @version 2.7.0
* @author Christian Schwinne * @author Christian Schwinne
* @license MIT * @license MIT
* @contributors d-999 * @contributors d-999
@ -25,7 +25,7 @@
//#define ESPALEXA_NO_SUBPAGE //#define ESPALEXA_NO_SUBPAGE
#ifndef ESPALEXA_MAXDEVICES #ifndef ESPALEXA_MAXDEVICES
#define ESPALEXA_MAXDEVICES 10 //this limit only has memory reasons, set it higher should you need to #define ESPALEXA_MAXDEVICES 10 //this limit only has memory reasons, set it higher should you need to, max 128
#endif #endif
//#define ESPALEXA_DEBUG //#define ESPALEXA_DEBUG
@ -50,7 +50,7 @@
#include "../network/Network.h" #include "../network/Network.h"
#ifdef ESPALEXA_DEBUG #ifdef ESPALEXA_DEBUG
#pragma message "Espalexa 2.5.0 debug mode" #pragma message "Espalexa 2.7.0 debug mode"
#define EA_DEBUG(x) Serial.print (x) #define EA_DEBUG(x) Serial.print (x)
#define EA_DEBUGLN(x) Serial.println (x) #define EA_DEBUGLN(x) Serial.println (x)
#else #else
@ -76,13 +76,14 @@ private:
#endif #endif
uint8_t currentDeviceCount = 0; uint8_t currentDeviceCount = 0;
bool discoverable = true; bool discoverable = true;
bool udpConnected = false;
EspalexaDevice* devices[ESPALEXA_MAXDEVICES] = {}; EspalexaDevice* devices[ESPALEXA_MAXDEVICES] = {};
//Keep in mind that Device IDs go from 1 to DEVICES, cpp arrays from 0 to DEVICES-1!! //Keep in mind that Device IDs go from 1 to DEVICES, cpp arrays from 0 to DEVICES-1!!
WiFiUDP espalexaUdp; WiFiUDP espalexaUdp;
IPAddress ipMulti; IPAddress ipMulti;
bool udpConnected = false; uint32_t mac24; //bottom 24 bits of mac
String escapedMac=""; //lowercase mac address String escapedMac=""; //lowercase mac address
//private member functions //private member functions
@ -119,33 +120,32 @@ private:
void encodeLightId(uint8_t idx, char* out) void encodeLightId(uint8_t idx, char* out)
{ {
//Unique id must be 12 character len
//use the last 10 characters of the MAC followed by the device id in hex value
//uniqueId: aabbccddeeii
uint8_t mac[6]; uint8_t mac[6];
WiFi.macAddress(mac); WiFi.macAddress(mac);
//shift the mac address to the left (discard first byte) sprintf_P(out, PSTR("%02X:%02X:%02X:%02X:%02X:%02X:00:11-%02X"), mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], idx);
for (uint8_t i = 0; i < 5; i++) { }
mac[i] = mac[i+1];
}
mac[5] = idx;
for (uint8_t i = 0; i < 6; i++) { // construct 'globally unique' Json dict key fitting into signed int
sprintf(out + i*2, "%.2x", mac[i]); inline int encodeLightKey(uint8_t idx)
} {
//return idx +1;
static_assert(ESPALEXA_MAXDEVICES <= 128, "");
return (mac24<<7) | idx;
}
// get device index from Json key
uint8_t decodeLightKey(int key)
{
//return key -1;
return (((uint32_t)key>>7) == mac24) ? (key & 127U) : 255U;
} }
//device JSON string: color+temperature device emulates LCT015, dimmable device LWB010, (TODO: on/off Plug 01, color temperature device LWT010, color device LST001) //device JSON string: color+temperature device emulates LCT015, dimmable device LWB010, (TODO: on/off Plug 01, color temperature device LWT010, color device LST001)
void deviceJsonString(uint8_t deviceId, char* buf) void deviceJsonString(EspalexaDevice* dev, char* buf)
{ {
deviceId--; char buf_lightid[27];
if (deviceId >= currentDeviceCount) {strcpy(buf,"{}"); return;} //error encodeLightId(dev->getId() + 1, buf_lightid);
EspalexaDevice* dev = devices[deviceId];
char buf_lightid[13];
encodeLightId(deviceId + 1, buf_lightid);
char buf_col[80] = ""; char buf_col[80] = "";
//color support //color support
@ -167,7 +167,7 @@ private:
sprintf_P(buf, PSTR("{\"state\":{\"on\":%s,\"bri\":%u%s%s,\"alert\":\"none%s\",\"mode\":\"homeautomation\",\"reachable\":true}," sprintf_P(buf, PSTR("{\"state\":{\"on\":%s,\"bri\":%u%s%s,\"alert\":\"none%s\",\"mode\":\"homeautomation\",\"reachable\":true},"
"\"type\":\"%s\",\"name\":\"%s\",\"modelid\":\"%s\",\"manufacturername\":\"Philips\",\"productname\":\"E%u" "\"type\":\"%s\",\"name\":\"%s\",\"modelid\":\"%s\",\"manufacturername\":\"Philips\",\"productname\":\"E%u"
"\",\"uniqueid\":\"%s\",\"swversion\":\"espalexa-2.5.0\"}") "\",\"uniqueid\":\"%s\",\"swversion\":\"espalexa-2.7.0\"}")
, (dev->getValue())?"true":"false", dev->getLastValue()-1, buf_col, buf_ct, buf_cm, typeString(dev->getType()), , (dev->getValue())?"true":"false", dev->getLastValue()-1, buf_col, buf_ct, buf_cm, typeString(dev->getType()),
dev->getName().c_str(), modelidString(dev->getType()), static_cast<uint8_t>(dev->getType()), buf_lightid); dev->getName().c_str(), modelidString(dev->getType()), static_cast<uint8_t>(dev->getType()), buf_lightid);
@ -192,7 +192,7 @@ private:
} }
res += "\r\nFree Heap: " + (String)ESP.getFreeHeap(); res += "\r\nFree Heap: " + (String)ESP.getFreeHeap();
res += "\r\nUptime: " + (String)millis(); res += "\r\nUptime: " + (String)millis();
res += "\r\n\r\nEspalexa library v2.5.0 by Christian Schwinne 2020"; res += "\r\n\r\nEspalexa library v2.7.0 by Christian Schwinne 2021";
server->send(200, "text/plain", res); server->send(200, "text/plain", res);
} }
#endif #endif
@ -335,6 +335,9 @@ public:
escapedMac.replace(":", ""); escapedMac.replace(":", "");
escapedMac.toLowerCase(); escapedMac.toLowerCase();
String macSubStr = escapedMac.substring(6, 12);
mac24 = strtol(macSubStr.c_str(), 0, 16);
#ifdef ESPALEXA_ASYNC #ifdef ESPALEXA_ASYNC
serverAsync = externalServer; serverAsync = externalServer;
#else #else
@ -390,48 +393,55 @@ public:
} }
} }
bool addDevice(EspalexaDevice* d) // returns device index or 0 on failure
uint8_t addDevice(EspalexaDevice* d)
{ {
EA_DEBUG("Adding device "); EA_DEBUG("Adding device ");
EA_DEBUGLN((currentDeviceCount+1)); EA_DEBUGLN((currentDeviceCount+1));
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false; if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
if (d == nullptr) return false; if (d == nullptr) return 0;
d->setId(currentDeviceCount); d->setId(currentDeviceCount);
devices[currentDeviceCount] = d; devices[currentDeviceCount] = d;
currentDeviceCount++; return ++currentDeviceCount;
return true;
} }
//brightness-only callback //brightness-only callback
bool addDevice(String deviceName, BrightnessCallbackFunction callback, uint8_t initialValue = 0) uint8_t addDevice(String deviceName, BrightnessCallbackFunction callback, uint8_t initialValue = 0)
{ {
EA_DEBUG("Constructing device "); EA_DEBUG("Constructing device ");
EA_DEBUGLN((currentDeviceCount+1)); EA_DEBUGLN((currentDeviceCount+1));
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false; if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue); EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
return addDevice(d); return addDevice(d);
} }
//brightness-only callback //brightness-only callback
bool addDevice(String deviceName, ColorCallbackFunction callback, uint8_t initialValue = 0) uint8_t addDevice(String deviceName, ColorCallbackFunction callback, uint8_t initialValue = 0)
{ {
EA_DEBUG("Constructing device "); EA_DEBUG("Constructing device ");
EA_DEBUGLN((currentDeviceCount+1)); EA_DEBUGLN((currentDeviceCount+1));
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false; if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue); EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
return addDevice(d); return addDevice(d);
} }
bool addDevice(String deviceName, DeviceCallbackFunction callback, EspalexaDeviceType t = EspalexaDeviceType::dimmable, uint8_t initialValue = 0) uint8_t addDevice(String deviceName, DeviceCallbackFunction callback, EspalexaDeviceType t = EspalexaDeviceType::dimmable, uint8_t initialValue = 0)
{ {
EA_DEBUG("Constructing device "); EA_DEBUG("Constructing device ");
EA_DEBUGLN((currentDeviceCount+1)); EA_DEBUGLN((currentDeviceCount+1));
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false; if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, t, initialValue); EspalexaDevice* d = new EspalexaDevice(deviceName, callback, t, initialValue);
return addDevice(d); return addDevice(d);
} }
void renameDevice(uint8_t id, const String& deviceName)
{
unsigned int index = id - 1;
if (index < currentDeviceCount)
devices[index]->setName(deviceName);
}
//basic implementation of Philips hue api functions needed for basic Alexa control //basic implementation of Philips hue api functions needed for basic Alexa control
#ifdef ESPALEXA_ASYNC #ifdef ESPALEXA_ASYNC
bool handleAlexaApiCall(AsyncWebServerRequest* request) bool handleAlexaApiCall(AsyncWebServerRequest* request)
@ -450,6 +460,8 @@ public:
bool handleAlexaApiCall(String req, String body) bool handleAlexaApiCall(String req, String body)
{ {
#endif #endif
EA_DEBUG("URL: ");
EA_DEBUGLN(req);
EA_DEBUGLN("AlexaApiCall"); EA_DEBUGLN("AlexaApiCall");
if (req.indexOf("api") <0) return false; //return if not an API call if (req.indexOf("api") <0) return false; //return if not an API call
EA_DEBUGLN("ok"); EA_DEBUGLN("ok");
@ -458,34 +470,36 @@ public:
{ {
EA_DEBUGLN("devType"); EA_DEBUGLN("devType");
body = ""; body = "";
server->send(200, "application/json", F("[{\"success\":{\"username\":\"2WLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBQr\"}}]")); server->send(200, "application/json", F("[{\"success\":{\"username\":\"2BLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBGr\"}}]"));
return true; return true;
} }
if ((req.indexOf("state") > 0) && (body.length() > 0)) //client wants to control light if ((req.indexOf("state") > 0) && (body.length() > 0)) //client wants to control light
{ {
server->send(200, "application/json", F("[{\"success\":{\"/lights/1/state/\": true}}]"));
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt(); uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
EA_DEBUG("ls"); EA_DEBUGLN(devId); EA_DEBUG("ls"); EA_DEBUGLN(devId);
EA_DEBUGLN(devId); unsigned idx = decodeLightKey(devId);
devId--; //zero-based for devices array EA_DEBUGLN(idx);
if (devId >= currentDeviceCount) return true; //return if invalid ID char buf[50];
sprintf_P(buf,PSTR("[{\"success\":{\"/lights/%u/state/\": true}}]"),devId);
server->send(200, "application/json", buf);
if (idx >= currentDeviceCount) return true; //return if invalid ID
EspalexaDevice* dev = devices[idx];
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::none); dev->setPropertyChanged(EspalexaDeviceProperty::none);
if (body.indexOf("false")>0) //OFF command if (body.indexOf("false")>0) //OFF command
{ {
devices[devId]->setValue(0); dev->setValue(0);
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::off); dev->setPropertyChanged(EspalexaDeviceProperty::off);
devices[devId]->doCallback(); dev->doCallback();
return true; return true;
} }
if (body.indexOf("true") >0) //ON command if (body.indexOf("true") >0) //ON command
{ {
devices[devId]->setValue(devices[devId]->getLastValue()); dev->setValue(dev->getLastValue());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::on); dev->setPropertyChanged(EspalexaDeviceProperty::on);
} }
if (body.indexOf("bri") >0) //BRIGHTNESS command if (body.indexOf("bri") >0) //BRIGHTNESS command
@ -493,35 +507,35 @@ public:
uint8_t briL = body.substring(body.indexOf("bri") +5).toInt(); uint8_t briL = body.substring(body.indexOf("bri") +5).toInt();
if (briL == 255) if (briL == 255)
{ {
devices[devId]->setValue(255); dev->setValue(255);
} else { } else {
devices[devId]->setValue(briL+1); dev->setValue(briL+1);
} }
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::bri); dev->setPropertyChanged(EspalexaDeviceProperty::bri);
} }
if (body.indexOf("xy") >0) //COLOR command (XY mode) if (body.indexOf("xy") >0) //COLOR command (XY mode)
{ {
devices[devId]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat()); dev->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::xy); dev->setPropertyChanged(EspalexaDeviceProperty::xy);
} }
if (body.indexOf("hue") >0) //COLOR command (HS mode) if (body.indexOf("hue") >0) //COLOR command (HS mode)
{ {
devices[devId]->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt()); dev->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::hs); dev->setPropertyChanged(EspalexaDeviceProperty::hs);
} }
if (body.indexOf("ct") >0) //COLOR TEMP command (white spectrum) if (body.indexOf("ct") >0) //COLOR TEMP command (white spectrum)
{ {
devices[devId]->setColor(body.substring(body.indexOf("ct") +4).toInt()); dev->setColor(body.substring(body.indexOf("ct") +4).toInt());
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::ct); dev->setPropertyChanged(EspalexaDeviceProperty::ct);
} }
devices[devId]->doCallback(); dev->doCallback();
#ifdef ESPALEXA_DEBUG #ifdef ESPALEXA_DEBUG
if (devices[devId]->getLastChangedProperty() == EspalexaDeviceProperty::none) if (dev->getLastChangedProperty() == EspalexaDeviceProperty::none)
EA_DEBUGLN("STATE REQ WITHOUT BODY (likely Content-Type issue #6)"); EA_DEBUGLN("STATE REQ WITHOUT BODY (likely Content-Type issue #6)");
#endif #endif
return true; return true;
@ -539,25 +553,31 @@ public:
String jsonTemp = "{"; String jsonTemp = "{";
for (int i = 0; i<currentDeviceCount; i++) for (int i = 0; i<currentDeviceCount; i++)
{ {
jsonTemp += "\"" + String(i+1) + "\":"; jsonTemp += '"';
jsonTemp += encodeLightKey(i);
jsonTemp += '"';
jsonTemp += ':';
char buf[512]; char buf[512];
deviceJsonString(i+1, buf); deviceJsonString(devices[i], buf);
jsonTemp += buf; jsonTemp += buf;
if (i < currentDeviceCount-1) jsonTemp += ","; if (i < currentDeviceCount-1) jsonTemp += ',';
} }
jsonTemp += "}"; jsonTemp += '}';
server->send(200, "application/json", jsonTemp); server->send(200, "application/json", jsonTemp);
} else //client wants one light (devId) } else //client wants one light (devId)
{ {
EA_DEBUGLN(devId); EA_DEBUGLN(devId);
if (devId > currentDeviceCount) unsigned int idx = decodeLightKey(devId);
{
if (idx >= currentDeviceCount) idx = 0; //send first device if invalid
if (currentDeviceCount == 0) {
server->send(200, "application/json", "{}"); server->send(200, "application/json", "{}");
} else { return true;
char buf[512];
deviceJsonString(devId, buf);
server->send(200, "application/json", buf);
} }
char buf[512];
deviceJsonString(devices[idx], buf);
server->send(200, "application/json", buf);
} }
return true; return true;

View File

@ -65,6 +65,11 @@ uint8_t EspalexaDevice::getValue()
return _val; return _val;
} }
bool EspalexaDevice::getState()
{
return _val;
}
uint8_t EspalexaDevice::getPercent() uint8_t EspalexaDevice::getPercent()
{ {
uint16_t perc = _val * 100; uint16_t perc = _val * 100;
@ -277,6 +282,16 @@ void EspalexaDevice::setValue(uint8_t val)
_val = val; _val = val;
} }
void EspalexaDevice::setState(bool onoff)
{
if (onoff)
{
setValue(_val_last);
} else {
setValue(0);
}
}
void EspalexaDevice::setPercent(uint8_t perc) void EspalexaDevice::setPercent(uint8_t perc)
{ {
uint16_t val = perc * 255; uint16_t val = perc * 255;

View File

@ -40,6 +40,8 @@ public:
uint8_t getId(); uint8_t getId();
EspalexaDeviceProperty getLastChangedProperty(); EspalexaDeviceProperty getLastChangedProperty();
uint8_t getValue(); uint8_t getValue();
uint8_t getLastValue(); //last value that was not off (1-255)
bool getState();
uint8_t getPercent(); uint8_t getPercent();
uint8_t getDegrees(); uint8_t getDegrees();
uint16_t getHue(); uint16_t getHue();
@ -59,6 +61,7 @@ public:
void setId(uint8_t id); void setId(uint8_t id);
void setPropertyChanged(EspalexaDeviceProperty p); void setPropertyChanged(EspalexaDeviceProperty p);
void setValue(uint8_t bri); void setValue(uint8_t bri);
void setState(bool onoff);
void setPercent(uint8_t perc); void setPercent(uint8_t perc);
void setName(String name); void setName(String name);
void setColor(uint16_t ct); void setColor(uint16_t ct);
@ -67,8 +70,6 @@ public:
void setColor(uint8_t r, uint8_t g, uint8_t b); void setColor(uint8_t r, uint8_t g, uint8_t b);
void doCallback(); void doCallback();
uint8_t getLastValue(); //last value that was not off (1-255)
}; };
#endif #endif

View File

@ -191,9 +191,6 @@ void WLED::loop()
handleOverlays(); handleOverlays();
yield(); yield();
#ifdef WLED_USE_ANALOG_LEDS
strip.setRgbwPwm();
#endif
if (doReboot) if (doReboot)
reset(); reset();
@ -217,24 +214,6 @@ void WLED::loop()
handleHue(); handleHue();
handleBlynk(); handleBlynk();
//LED settings have been saved, re-init busses
//This code block causes severe FPS drop on ESP32 with the original "if (busConfigs[0] != nullptr)" conditional. Investigate!
if (doInitBusses) {
doInitBusses = false;
DEBUG_PRINTLN(F("Re-init busses."));
busses.removeAll();
uint32_t mem = 0;
for (uint8_t i = 0; i < WLED_MAX_BUSSES; i++) {
if (busConfigs[i] == nullptr) break;
mem += BusManager::memUsage(*busConfigs[i]);
if (mem <= MAX_LED_MEMORY) busses.add(*busConfigs[i]);
delete busConfigs[i]; busConfigs[i] = nullptr;
}
strip.finalizeInit();
yield();
serializeConfig();
}
yield(); yield();
if (!offMode) if (!offMode)
@ -263,6 +242,24 @@ void WLED::loop()
if (nodeBroadcastEnabled) sendSysInfoUDP(); if (nodeBroadcastEnabled) sendSysInfoUDP();
} }
//LED settings have been saved, re-init busses
//This code block causes severe FPS drop on ESP32 with the original "if (busConfigs[0] != nullptr)" conditional. Investigate!
if (doInitBusses) {
doInitBusses = false;
DEBUG_PRINTLN(F("Re-init busses."));
busses.removeAll();
uint32_t mem = 0;
for (uint8_t i = 0; i < WLED_MAX_BUSSES; i++) {
if (busConfigs[i] == nullptr) break;
mem += BusManager::memUsage(*busConfigs[i]);
if (mem <= MAX_LED_MEMORY) busses.add(*busConfigs[i]);
delete busConfigs[i]; busConfigs[i] = nullptr;
}
strip.finalizeInit();
yield();
serializeConfig();
}
yield(); yield();
handleWs(); handleWs();
handleStatusLED(); handleStatusLED();

View File

@ -3,12 +3,12 @@
/* /*
Main sketch, global variable declarations Main sketch, global variable declarations
@title WLED project sketch @title WLED project sketch
@version 0.12.0-a0 @version 0.12.0-b4
@author Christian Schwinne @author Christian Schwinne
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2103290 #define VERSION 2103291
//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
@ -148,11 +148,6 @@
#define WLED_FS LITTLEFS #define WLED_FS LITTLEFS
#endif #endif
// remove flicker because PWM signal of RGB channels can become out of phase (part of core as of Arduino core v2.7.0)
//#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266)
// #include "src/dependencies/arduino/core_esp8266_waveform.h"
//#endif
// GLOBAL VARIABLES // GLOBAL VARIABLES
// both declared and defined in header (solution from http://www.keil.com/support/docs/1868.htm) // both declared and defined in header (solution from http://www.keil.com/support/docs/1868.htm)
// //
@ -173,7 +168,7 @@
#endif #endif
// Global Variable definitions // Global Variable definitions
WLED_GLOBAL char versionString[] _INIT("0.12.0-b3"); WLED_GLOBAL char versionString[] _INIT("0.12.0-b4");
#define WLED_CODENAME "Hikari" #define WLED_CODENAME "Hikari"
// AP and OTA default passwords (for maximum security change them!) // AP and OTA default passwords (for maximum security change them!)
@ -230,7 +225,6 @@ WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling
// LED CONFIG // LED CONFIG
WLED_GLOBAL uint16_t ledCount _INIT(30); // overcurrent prevented by ABL WLED_GLOBAL uint16_t ledCount _INIT(30); // overcurrent prevented by ABL
WLED_GLOBAL bool useRGBW _INIT(false); // SK6812 strips can contain an extra White channel
WLED_GLOBAL bool turnOnAtBoot _INIT(true); // turn on LEDs at power-up WLED_GLOBAL bool turnOnAtBoot _INIT(true); // turn on LEDs at power-up
WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load after power-up WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load after power-up
@ -244,7 +238,6 @@ WLED_GLOBAL byte nightlightMode _INIT(NL_MODE_FADE); // See const.h for ava
WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition
WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms
WLED_GLOBAL bool skipFirstLed _INIT(false); // ignore first LED in strip (useful if you need the LED as signal repeater)
WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)
// User Interface CONFIG // User Interface CONFIG
@ -419,6 +412,7 @@ WLED_GLOBAL byte effectCurrent _INIT(0);
WLED_GLOBAL byte effectSpeed _INIT(128); WLED_GLOBAL byte effectSpeed _INIT(128);
WLED_GLOBAL byte effectIntensity _INIT(128); WLED_GLOBAL byte effectIntensity _INIT(128);
WLED_GLOBAL byte effectPalette _INIT(0); WLED_GLOBAL byte effectPalette _INIT(0);
WLED_GLOBAL bool effectChanged _INIT(false);
// network // network
WLED_GLOBAL bool udpConnected _INIT(false), udp2Connected _INIT(false), udpRgbConnected _INIT(false); WLED_GLOBAL bool udpConnected _INIT(false), udp2Connected _INIT(false), udpRgbConnected _INIT(false);
@ -563,7 +557,7 @@ WLED_GLOBAL bool e131NewData _INIT(false);
// led fx library object // led fx library object
WLED_GLOBAL BusManager busses _INIT(BusManager()); WLED_GLOBAL BusManager busses _INIT(BusManager());
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX()); WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES]; //temporary, to remember values from network callback until after WLED_GLOBAL BusConfig* busConfigs[WLED_MAX_BUSSES] _INIT({nullptr}); //temporary, to remember values from network callback until after
WLED_GLOBAL bool doInitBusses _INIT(false); WLED_GLOBAL bool doInitBusses _INIT(false);
// Usermod manager // Usermod manager

View File

@ -115,7 +115,6 @@ void loadSettingsFromEEPROM()
} }
receiveNotificationBrightness = EEPROM.read(250); receiveNotificationBrightness = EEPROM.read(250);
fadeTransition = EEPROM.read(251); fadeTransition = EEPROM.read(251);
// strip.reverseMode = EEPROM.read(252);
transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00); transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00);
transitionDelay = transitionDelayDefault; transitionDelay = transitionDelayDefault;
briMultiplier = EEPROM.read(255); briMultiplier = EEPROM.read(255);
@ -144,7 +143,7 @@ void loadSettingsFromEEPROM()
arlsOffset = EEPROM.read(368); arlsOffset = EEPROM.read(368);
if (!EEPROM.read(367)) arlsOffset = -arlsOffset; if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
turnOnAtBoot = EEPROM.read(369); turnOnAtBoot = EEPROM.read(369);
useRGBW = EEPROM.read(372); strip.isRgbw = EEPROM.read(372);
//374 - strip.paletteFade //374 - strip.paletteFade
apBehavior = EEPROM.read(376); apBehavior = EEPROM.read(376);
@ -318,7 +317,7 @@ void loadSettingsFromEEPROM()
notifyMacro = EEPROM.read(2201); notifyMacro = EEPROM.read(2201);
strip.rgbwMode = EEPROM.read(2203); strip.rgbwMode = EEPROM.read(2203);
skipFirstLed = EEPROM.read(2204); //was skipFirstLed = EEPROM.read(2204);
if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212)) if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
{ {
@ -407,7 +406,7 @@ void deEEP() {
JsonArray colarr = segObj.createNestedArray("col"); JsonArray colarr = segObj.createNestedArray("col");
byte numChannels = (useRGBW)? 4:3; byte numChannels = (strip.isRgbw)? 4:3;
for (uint8_t k = 0; k < 3; k++) //k=0 primary (i+2) k=1 secondary (i+6) k=2 tertiary color (i+12) for (uint8_t k = 0; k < 3; k++) //k=0 primary (i+2) k=1 secondary (i+6) k=2 tertiary color (i+12)
{ {

View File

@ -24,7 +24,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if (ClientApis[i].c) continue; // used slot if (ClientApis[i].c) continue; // used slot
ClientApis[i].c = client->id(); ClientApis[i].c = client->id();
ClientApis[i].vAPI = 1; ClientApis[i].vAPI = 1;
DEBUG_PRINTF("New WS client [%d]: %ld\n", (int)i, client->id()); DEBUG_PRINTF("New WS client [%d]: %d\n", (int)i, client->id());
break; break;
} }
sendDataWs(client); sendDataWs(client);
@ -36,7 +36,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
if (ClientApis[i].c != client->id()) continue; if (ClientApis[i].c != client->id()) continue;
ClientApis[i].c = 0; // clear slot ClientApis[i].c = 0; // clear slot
ClientApis[i].vAPI = 1; ClientApis[i].vAPI = 1;
DEBUG_PRINTF("Removed WS client [%d]: %ld\n", (int)i, client->id()); DEBUG_PRINTF("Removed WS client [%d]: %d\n", (int)i, client->id());
break; break;
} }
} else if(type == WS_EVT_DATA){ } else if(type == WS_EVT_DATA){

View File

@ -322,6 +322,7 @@ void getSettingsJS(byte subPage, char* dest)
sappend('v',SET_F("LC"),ledCount); sappend('v',SET_F("LC"),ledCount);
bool skip = false;
for (uint8_t s=0; s < busses.getNumBusses(); s++) { for (uint8_t s=0; s < busses.getNumBusses(); s++) {
Bus* bus = busses.getBus(s); Bus* bus = busses.getBus(s);
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
@ -344,6 +345,7 @@ void getSettingsJS(byte subPage, char* dest)
sappend('v',ls,bus->getStart()); sappend('v',ls,bus->getStart());
sappend('c',cv,bus->reversed); sappend('c',cv,bus->reversed);
sappend('c',ew,bus->isRgbw()); sappend('c',ew,bus->isRgbw());
skip = skip || bus->skipFirstLed();
} }
sappend('v',SET_F("MA"),strip.ablMilliampsMax); sappend('v',SET_F("MA"),strip.ablMilliampsMax);
sappend('v',SET_F("LA"),strip.milliampsPerLed); sappend('v',SET_F("LA"),strip.milliampsPerLed);
@ -371,7 +373,7 @@ void getSettingsJS(byte subPage, char* dest)
sappend('v',SET_F("TL"),nightlightDelayMinsDefault); sappend('v',SET_F("TL"),nightlightDelayMinsDefault);
sappend('v',SET_F("TW"),nightlightMode); sappend('v',SET_F("TW"),nightlightMode);
sappend('i',SET_F("PB"),strip.paletteBlend); sappend('i',SET_F("PB"),strip.paletteBlend);
sappend('c',SET_F("SL"),skipFirstLed); sappend('c',SET_F("SL"),skip);
sappend('v',SET_F("RL"),rlyPin); sappend('v',SET_F("RL"),rlyPin);
sappend('c',SET_F("RM"),rlyMde); sappend('c',SET_F("RM"),rlyMde);
sappend('v',SET_F("BT"),btnPin); sappend('v',SET_F("BT"),btnPin);