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:
commit
6ace46eece
2
.github/workflows/wled-ci.yml
vendored
2
.github/workflows/wled-ci.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: PlatformIO CI
|
||||
|
||||
on: [push]
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
40
CHANGELOG.md
40
CHANGELOG.md
@ -1,6 +1,42 @@
|
||||
## 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
|
||||
|
||||
@ -204,7 +240,7 @@
|
||||
#### Build 2011153
|
||||
|
||||
- Fixed an ESP32 end-of-file issue
|
||||
- Fixed useRGBW not read from cfg.json
|
||||
- Fixed strip.isRgbw not read from cfg.json
|
||||
|
||||
#### Build 2011152
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wled",
|
||||
"version": "0.12.0-b3",
|
||||
"version": "0.12.0-b4",
|
||||
"description": "Tools for WLED project",
|
||||
"main": "tools/cdata.js",
|
||||
"directories": {
|
||||
|
@ -9,10 +9,10 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# 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
|
||||
; default_envs = nodemcuv2, esp01_1m_full, esp32dev
|
||||
default_envs = nodemcuv2, esp01_1m_full, esp32dev, esp32_eth
|
||||
|
||||
# Single binaries (uncomment your board)
|
||||
; default_envs = nodemcuv2
|
||||
@ -259,7 +259,7 @@ build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
|
||||
|
||||
[env:esp32dev]
|
||||
board = esp32dev
|
||||
platform = espressif32@2.0
|
||||
platform = espressif32@3.1.1
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp32}
|
||||
lib_ignore =
|
||||
@ -268,7 +268,7 @@ lib_ignore =
|
||||
|
||||
[env:esp32_eth]
|
||||
board = esp32-poe
|
||||
platform = espressif32@2.0
|
||||
platform = espressif32@3.1.1
|
||||
upload_speed = 921600
|
||||
build_unflags = ${common.build_unflags}
|
||||
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]
|
||||
board = esp32dev
|
||||
platform = espressif32@2.0
|
||||
platform = espressif32@3.1.1
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp32} -D TOUCHPIN=T0
|
||||
lib_ignore =
|
||||
@ -355,7 +355,7 @@ lib_ignore =
|
||||
|
||||
[env:wemos_shield_esp32]
|
||||
board = esp32dev
|
||||
platform = espressif32@2.0
|
||||
platform = espressif32@3.1.1
|
||||
upload_port = /dev/cu.SLAB_USBtoUART
|
||||
monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
upload_speed = 460800
|
||||
@ -372,7 +372,7 @@ build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39
|
||||
lib_ignore =
|
||||
ESPAsyncTCP
|
||||
ESPAsyncUDP
|
||||
platform = espressif32@2.0
|
||||
platform = espressif32@3.1.1
|
||||
|
||||
[env:sp501e]
|
||||
board = esp_wroom_02
|
||||
|
5
usermods/Artemis_reciever/readme.md
Normal file
5
usermods/Artemis_reciever/readme.md
Normal 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
|
93
usermods/Artemis_reciever/usermod.cpp
Normal file
93
usermods/Artemis_reciever/usermod.cpp
Normal 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();
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ default_envs = d1_mini
|
||||
|
||||
[env:esp32dev]
|
||||
board = esp32dev
|
||||
platform = espressif32@2.0
|
||||
platform = espressif32@3.1.1
|
||||
build_unflags = ${common.build_unflags}
|
||||
build_flags =
|
||||
${common.build_flags_esp32}
|
||||
|
@ -604,10 +604,10 @@ class WS2812FX {
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
show(void),
|
||||
setRgbwPwm(void),
|
||||
// setColorOrder(uint8_t co),
|
||||
setPixelSegment(uint8_t n);
|
||||
|
||||
bool
|
||||
isRgbw = false,
|
||||
gammaCorrectBri = false,
|
||||
gammaCorrectCol = true,
|
||||
applyToAllSelected = true,
|
||||
@ -630,7 +630,6 @@ class WS2812FX {
|
||||
getMaxSegments(void),
|
||||
//getFirstSelectedSegment(void),
|
||||
getMainSegmentId(void),
|
||||
// getColorOrder(void),
|
||||
gamma8(uint8_t),
|
||||
gamma8_cal(uint8_t, float),
|
||||
get_random_wheel_index(uint8_t);
|
||||
@ -805,7 +804,6 @@ class WS2812FX {
|
||||
void handle_palette(void);
|
||||
|
||||
bool
|
||||
_useRgbw = false,
|
||||
_triggered;
|
||||
|
||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
|
@ -27,10 +27,6 @@
|
||||
#include "FX.h"
|
||||
#include "palettes.h"
|
||||
|
||||
#ifndef PWM_INDEX
|
||||
#define PWM_INDEX 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
Custom per-LED mapping has moved!
|
||||
|
||||
@ -51,7 +47,7 @@
|
||||
void WS2812FX::finalizeInit(void)
|
||||
{
|
||||
RESET_RUNTIME;
|
||||
_useRgbw = false;
|
||||
isRgbw = false;
|
||||
|
||||
//if busses failed to load, add default (fresh install, FS issue, ...)
|
||||
if (busses.getNumBusses() == 0) {
|
||||
@ -81,7 +77,8 @@ void WS2812FX::finalizeInit(void)
|
||||
for (uint8_t i=0; i<busses.getNumBusses(); i++) {
|
||||
Bus *bus = busses.getBus(i);
|
||||
if (bus == nullptr) continue;
|
||||
_useRgbw |= bus->isRgbw();
|
||||
if (_length+bus->getLength() > MAX_LEDS) break;
|
||||
isRgbw |= bus->isRgbw();
|
||||
_length += bus->getLength();
|
||||
}
|
||||
/*
|
||||
@ -161,8 +158,6 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||
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
|
||||
uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
||||
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)
|
||||
{
|
||||
//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)))
|
||||
{
|
||||
//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 = powerSum >> 2; //same as /= 4
|
||||
|
@ -67,7 +67,7 @@ void onAlexaChange(EspalexaDevice* dev)
|
||||
if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white
|
||||
{
|
||||
uint16_t ct = espalexaDevice->getCt();
|
||||
if (useRGBW)
|
||||
if (strip.isRgbw)
|
||||
{
|
||||
switch (ct) { //these values empirically look good on RGBW
|
||||
case 199: col[0]=255; col[1]=255; col[2]=255; col[3]=255; break;
|
||||
|
@ -81,6 +81,10 @@ class Bus {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool skipFirstLed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint8_t getType() {
|
||||
return _type;
|
||||
}
|
||||
@ -177,6 +181,10 @@ class BusDigital : public Bus {
|
||||
return _rgbw;
|
||||
}
|
||||
|
||||
inline bool skipFirstLed() {
|
||||
return (bool)_skip;
|
||||
}
|
||||
|
||||
inline void reinit() {
|
||||
PolyBus::begin(_busPtr, _iType, _pins);
|
||||
}
|
||||
@ -239,6 +247,7 @@ class BusPwm : public Bus {
|
||||
ledcAttachPin(_pins[i], _ledcStart + i);
|
||||
#endif
|
||||
}
|
||||
reversed = bc.reversed;
|
||||
_valid = true;
|
||||
};
|
||||
|
||||
@ -272,6 +281,7 @@ class BusPwm : public Bus {
|
||||
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||
for (uint8_t i = 0; i < numPins; i++) {
|
||||
uint8_t scaled = (_data[i] * _bri) / 255;
|
||||
if (reversed) scaled = 255 - scaled;
|
||||
#ifdef ESP8266
|
||||
analogWrite(_pins[i], scaled);
|
||||
#else
|
||||
|
@ -102,8 +102,8 @@ void deserializeConfig() {
|
||||
|
||||
JsonArray ins = hw_led["ins"];
|
||||
uint8_t s = 0; // bus iterator
|
||||
bool skipFirst = skipFirstLed = false;
|
||||
useRGBW = false;
|
||||
bool skipFirst = false;
|
||||
strip.isRgbw = false;
|
||||
busses.removeAll();
|
||||
uint32_t mem = 0;
|
||||
for (JsonObject elm : ins) {
|
||||
@ -125,12 +125,12 @@ void deserializeConfig() {
|
||||
//if (start + length > ledCount) length = ledCount - start;
|
||||
uint8_t colorOrder = (int)elm[F("order")];
|
||||
//(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;
|
||||
bool reversed = elm["rev"];
|
||||
//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)
|
||||
useRGBW |= (bool)elm[F("rgbw")];
|
||||
strip.isRgbw |= (bool)elm[F("rgbw")]; //(strip.isRgbw || BusManager::isRgbw(ledType));
|
||||
s++;
|
||||
lC += length;
|
||||
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)
|
||||
//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];
|
||||
CJSON(buttonEnabled, hw_btn_ins_0["type"]);
|
||||
@ -456,7 +457,6 @@ void serializeConfig() {
|
||||
hw_led[F("total")] = ledCount;
|
||||
hw_led[F("maxpwr")] = strip.ablMilliampsMax;
|
||||
hw_led[F("ledma")] = strip.milliampsPerLed;
|
||||
hw_led["rev"] = false; //strip.reverseMode; // not used anymore, reversing per-strip
|
||||
hw_led[F("rgbwm")] = strip.rgbwMode;
|
||||
|
||||
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]);
|
||||
ins[F("order")] = bus->getColorOrder();
|
||||
ins["rev"] = bus->reversed;
|
||||
ins[F("skip")] = skipFirstLed ? 1 : 0;
|
||||
ins[F("skip")] = bus->skipFirstLed();
|
||||
ins["type"] = bus->getType();
|
||||
ins[F("rgbw")] = bus->isRgbw();
|
||||
}
|
||||
|
@ -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 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
|
||||
@ -111,7 +111,7 @@ void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb, bins
|
||||
} else {
|
||||
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
|
||||
@ -169,7 +169,7 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
|
||||
rgb[0] = 255.0*r;
|
||||
rgb[1] = 255.0*g;
|
||||
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)
|
||||
|
@ -915,7 +915,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
|
||||
.lstI {
|
||||
position: relative;
|
||||
border-bottom: 1px solid var(--c-3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -943,7 +942,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
|
||||
.lstI.sticky, .lstI.selected {
|
||||
/* position: sticky;*/
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
//check for pin conflicts
|
||||
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 > 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;}
|
||||
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 (d.Sf.reportValidity()) d.Sf.submit();
|
||||
}
|
||||
function S(){GetV();setABL(); d.getElementById('m1').innerHTML = maxM;}
|
||||
function S(){GetV();setABL();}
|
||||
function enABL()
|
||||
{
|
||||
var en = d.getElementById('able').checked;
|
||||
@ -65,6 +66,7 @@
|
||||
case 255: d.Sf.LAsel.value = 255; break;
|
||||
default: d.getElementById('LAdis').style.display = 'inline';
|
||||
}
|
||||
d.getElementById('m1').innerHTML = maxM;
|
||||
UI();
|
||||
}
|
||||
//returns mem usage
|
||||
@ -74,8 +76,9 @@
|
||||
if (maxM < 10000 && p0==3) { //8266 DMA uses 5x the mem
|
||||
if (type > 29) return len*20; //RGBW
|
||||
return len*15;
|
||||
} else if (maxM > 10000) { //ESP32 RMT uses double buffer?
|
||||
if (type > 29) return len*8; //RGBW
|
||||
} else if (maxM >= 10000) //ESP32 RMT uses double buffer?
|
||||
{
|
||||
if (type > 29) return len*8; //RGBW
|
||||
return len*6;
|
||||
}
|
||||
if (type > 29) return len*4; //RGBW
|
||||
@ -88,12 +91,12 @@
|
||||
function UI(change=false)
|
||||
{
|
||||
var isRGBW = false, memu = 0;
|
||||
|
||||
|
||||
d.getElementById('ampwarning').style.display = (d.Sf.MA.value > 7200) ? 'inline':'none';
|
||||
|
||||
|
||||
if (d.Sf.LA.value == 255) laprev = 12;
|
||||
else if (d.Sf.LA.value > 0) laprev = d.Sf.LA.value;
|
||||
|
||||
|
||||
var s = d.getElementsByTagName("select");
|
||||
for (i=0; i<s.length; i++) {
|
||||
if (s[i].name.substring(0,2)=="LT") {
|
||||
@ -253,7 +256,7 @@ Color Order:
|
||||
<br>
|
||||
<span id="psd${i}">Start:</span> <input type="number" name="LS${i}" id="ls${i}" min="0" max="8191" value="${lastEnd(i)}" required />
|
||||
<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}">
|
||||
</div>
|
||||
RGBW: <input id="ew${i}" type="checkbox" name="EW${i}"><br>
|
||||
|
@ -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}
|
||||
</style></head><body><h2>WLED Software Update</h2><form method="POST"
|
||||
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
|
||||
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>
|
||||
|
File diff suppressed because one or more lines are too long
4160
wled00/html_ui.h
4160
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -345,19 +345,19 @@ void decodeIR40(uint32_t code)
|
||||
case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break;
|
||||
case IR40_PINK : colorFromUint24(COLOR_PINK); break;
|
||||
case IR40_WARMWHITE2 : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_WARMWHITE2); } break;
|
||||
case IR40_WARMWHITE : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_WARMWHITE); } break;
|
||||
case IR40_WHITE : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_NEUTRALWHITE); } break;
|
||||
case IR40_COLDWHITE : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_COLDWHITE); } break;
|
||||
case IR40_COLDWHITE2 : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_COLDWHITE2); } break;
|
||||
case IR40_WPLUS : relativeChangeWhite(10); 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_PINK : colorFromUint24(COLOR_PINK); break;
|
||||
case IR44_WHITE : {
|
||||
if (useRGBW) {
|
||||
if (strip.isRgbw) {
|
||||
if (col[3] > 0) col[3] = 0;
|
||||
else { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; }
|
||||
} else colorFromUint24(COLOR_NEUTRALWHITE); } break;
|
||||
case IR44_WARMWHITE2 : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_WARMWHITE2); } break;
|
||||
case IR44_WARMWHITE : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_WARMWHITE); } break;
|
||||
case IR44_COLDWHITE : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_COLDWHITE); } break;
|
||||
case IR44_COLDWHITE2 : {
|
||||
if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
|
||||
if (strip.isRgbw) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; }
|
||||
else colorFromUint24(COLOR_COLDWHITE2); } break;
|
||||
case IR44_REDPLUS : relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break;
|
||||
case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break;
|
||||
|
@ -203,7 +203,7 @@ bool deserializeState(JsonObject root)
|
||||
JsonObject nl = root["nl"];
|
||||
nightlightActive = nl["on"] | nightlightActive;
|
||||
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;
|
||||
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++)
|
||||
{
|
||||
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)));
|
||||
else colarr.add((unsigned long)((colSec[0]<<16) | (colSec[1]<<8) | colSec[2] | (useRGBW?colSec[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] | (strip.isRgbw?colSec[3]<<24:0)));
|
||||
else
|
||||
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 (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 {
|
||||
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 {
|
||||
colX.add((seg.colors[i] >> 16) & 0xFF);
|
||||
colX.add((seg.colors[i] >> 8) & 0xFF);
|
||||
colX.add((seg.colors[i]) & 0xFF);
|
||||
if (useRGBW)
|
||||
if (strip.isRgbw)
|
||||
colX.add((seg.colors[i] >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
@ -443,8 +443,8 @@ void serializeInfo(JsonObject root)
|
||||
|
||||
JsonObject leds = root.createNestedObject("leds");
|
||||
leds[F("count")] = ledCount;
|
||||
leds[F("rgbw")] = useRGBW;
|
||||
leds[F("wv")] = useRGBW && (strip.rgbwMode == RGBW_MODE_MANUAL_ONLY || strip.rgbwMode == RGBW_MODE_DUAL); //should a white channel slider be displayed?
|
||||
leds[F("rgbw")] = strip.isRgbw;
|
||||
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");
|
||||
for (uint8_t s=0; s<busses.getNumBusses(); s++) {
|
||||
|
@ -50,14 +50,14 @@ void setAllLeds() {
|
||||
{
|
||||
strip.setBrightness(scaledBri(briT));
|
||||
}
|
||||
if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY)
|
||||
if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY)
|
||||
{
|
||||
colorRGBtoRGBW(col);
|
||||
colorRGBtoRGBW(colSec);
|
||||
}
|
||||
strip.setColor(0, col[0], col[1], col[2], col[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;
|
||||
}
|
||||
@ -101,7 +101,7 @@ void colorUpdated(int callMode)
|
||||
//Notifier: apply received FX to selected segments only if actually receiving FX
|
||||
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();
|
||||
|
||||
//Notifier: apply received color to selected segments only if actually receiving color
|
||||
@ -109,6 +109,7 @@ void colorUpdated(int callMode)
|
||||
|
||||
if (fxChanged || colChanged)
|
||||
{
|
||||
effectChanged = false;
|
||||
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
||||
if (isPreset) {isPreset = false;}
|
||||
else {currentPreset = -1;}
|
||||
|
@ -83,8 +83,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
#endif
|
||||
if (btnPin>=0 && pinManager.isPinAllocated(btnPin)) pinManager.deallocatePin(btnPin);
|
||||
|
||||
skipFirstLed = request->hasArg(F("SL"));
|
||||
useRGBW = false;
|
||||
bool skip = request->hasArg(F("SL"));
|
||||
strip.isRgbw = false;
|
||||
|
||||
uint8_t colorOrder, type;
|
||||
uint16_t length, start;
|
||||
@ -108,7 +108,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
}
|
||||
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)
|
||||
useRGBW |= request->hasArg(ew);
|
||||
strip.isRgbw = strip.isRgbw || request->hasArg(ew);
|
||||
|
||||
colorOrder = request->arg(co).toInt();
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -162,8 +162,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
||||
strip.milliampsPerLed = request->arg(F("LA")).toInt();
|
||||
|
||||
// useRGBW = request->hasArg(F("EW"));
|
||||
strip.rgbwMode = request->arg(F("AW")).toInt(); // auto white calculation
|
||||
strip.rgbwMode = request->arg(F("AW")).toInt();
|
||||
|
||||
briS = request->arg(F("CA")).toInt();
|
||||
|
||||
@ -188,8 +187,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
|
||||
t = request->arg(F("PB")).toInt();
|
||||
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();
|
||||
if (t > 0) briMultiplier = t;
|
||||
}
|
||||
@ -822,10 +819,22 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
{
|
||||
WS2812FX::Segment& seg = strip.getSegment(i);
|
||||
if (!seg.isSelected()) continue;
|
||||
if (effectCurrent != prevEffect) seg.mode = effectCurrent;
|
||||
if (effectSpeed != prevSpeed) seg.speed = effectSpeed;
|
||||
if (effectIntensity != prevIntensity) seg.intensity = effectIntensity;
|
||||
if (effectPalette != prevPalette) seg.palette = effectPalette;
|
||||
if (effectCurrent != prevEffect) {
|
||||
seg.mode = effectCurrent;
|
||||
effectChanged = true;
|
||||
}
|
||||
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) {
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
/*
|
||||
* @title Espalexa library
|
||||
* @version 2.5.0
|
||||
* @version 2.7.0
|
||||
* @author Christian Schwinne
|
||||
* @license MIT
|
||||
* @contributors d-999
|
||||
@ -25,7 +25,7 @@
|
||||
//#define ESPALEXA_NO_SUBPAGE
|
||||
|
||||
#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
|
||||
|
||||
//#define ESPALEXA_DEBUG
|
||||
@ -50,7 +50,7 @@
|
||||
#include "../network/Network.h"
|
||||
|
||||
#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_DEBUGLN(x) Serial.println (x)
|
||||
#else
|
||||
@ -76,13 +76,14 @@ private:
|
||||
#endif
|
||||
uint8_t currentDeviceCount = 0;
|
||||
bool discoverable = true;
|
||||
bool udpConnected = false;
|
||||
|
||||
EspalexaDevice* devices[ESPALEXA_MAXDEVICES] = {};
|
||||
//Keep in mind that Device IDs go from 1 to DEVICES, cpp arrays from 0 to DEVICES-1!!
|
||||
|
||||
WiFiUDP espalexaUdp;
|
||||
IPAddress ipMulti;
|
||||
bool udpConnected = false;
|
||||
uint32_t mac24; //bottom 24 bits of mac
|
||||
String escapedMac=""; //lowercase mac address
|
||||
|
||||
//private member functions
|
||||
@ -119,33 +120,32 @@ private:
|
||||
|
||||
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];
|
||||
WiFi.macAddress(mac);
|
||||
|
||||
//shift the mac address to the left (discard first byte)
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
mac[i] = mac[i+1];
|
||||
}
|
||||
mac[5] = idx;
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
sprintf(out + i*2, "%.2x", mac[i]);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
//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)
|
||||
|
||||
// construct 'globally unique' Json dict key fitting into signed int
|
||||
inline int encodeLightKey(uint8_t idx)
|
||||
{
|
||||
deviceId--;
|
||||
if (deviceId >= currentDeviceCount) {strcpy(buf,"{}"); return;} //error
|
||||
EspalexaDevice* dev = devices[deviceId];
|
||||
|
||||
char buf_lightid[13];
|
||||
encodeLightId(deviceId + 1, buf_lightid);
|
||||
//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)
|
||||
void deviceJsonString(EspalexaDevice* dev, char* buf)
|
||||
{
|
||||
char buf_lightid[27];
|
||||
encodeLightId(dev->getId() + 1, buf_lightid);
|
||||
|
||||
char buf_col[80] = "";
|
||||
//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},"
|
||||
"\"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->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\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);
|
||||
}
|
||||
#endif
|
||||
@ -335,6 +335,9 @@ public:
|
||||
escapedMac.replace(":", "");
|
||||
escapedMac.toLowerCase();
|
||||
|
||||
String macSubStr = escapedMac.substring(6, 12);
|
||||
mac24 = strtol(macSubStr.c_str(), 0, 16);
|
||||
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
serverAsync = externalServer;
|
||||
#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_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
if (d == nullptr) return false;
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
|
||||
if (d == nullptr) return 0;
|
||||
d->setId(currentDeviceCount);
|
||||
devices[currentDeviceCount] = d;
|
||||
currentDeviceCount++;
|
||||
return true;
|
||||
return ++currentDeviceCount;
|
||||
}
|
||||
|
||||
//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_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
|
||||
return addDevice(d);
|
||||
}
|
||||
|
||||
//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_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
|
||||
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_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, t, initialValue);
|
||||
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
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
bool handleAlexaApiCall(AsyncWebServerRequest* request)
|
||||
@ -450,6 +460,8 @@ public:
|
||||
bool handleAlexaApiCall(String req, String body)
|
||||
{
|
||||
#endif
|
||||
EA_DEBUG("URL: ");
|
||||
EA_DEBUGLN(req);
|
||||
EA_DEBUGLN("AlexaApiCall");
|
||||
if (req.indexOf("api") <0) return false; //return if not an API call
|
||||
EA_DEBUGLN("ok");
|
||||
@ -458,34 +470,36 @@ public:
|
||||
{
|
||||
EA_DEBUGLN("devType");
|
||||
body = "";
|
||||
server->send(200, "application/json", F("[{\"success\":{\"username\":\"2WLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBQr\"}}]"));
|
||||
server->send(200, "application/json", F("[{\"success\":{\"username\":\"2BLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBGr\"}}]"));
|
||||
return true;
|
||||
}
|
||||
|
||||
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();
|
||||
EA_DEBUG("ls"); EA_DEBUGLN(devId);
|
||||
EA_DEBUGLN(devId);
|
||||
devId--; //zero-based for devices array
|
||||
if (devId >= currentDeviceCount) return true; //return if invalid ID
|
||||
unsigned idx = decodeLightKey(devId);
|
||||
EA_DEBUGLN(idx);
|
||||
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
|
||||
{
|
||||
devices[devId]->setValue(0);
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::off);
|
||||
devices[devId]->doCallback();
|
||||
dev->setValue(0);
|
||||
dev->setPropertyChanged(EspalexaDeviceProperty::off);
|
||||
dev->doCallback();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (body.indexOf("true") >0) //ON command
|
||||
{
|
||||
devices[devId]->setValue(devices[devId]->getLastValue());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::on);
|
||||
dev->setValue(dev->getLastValue());
|
||||
dev->setPropertyChanged(EspalexaDeviceProperty::on);
|
||||
}
|
||||
|
||||
if (body.indexOf("bri") >0) //BRIGHTNESS command
|
||||
@ -493,35 +507,35 @@ public:
|
||||
uint8_t briL = body.substring(body.indexOf("bri") +5).toInt();
|
||||
if (briL == 255)
|
||||
{
|
||||
devices[devId]->setValue(255);
|
||||
dev->setValue(255);
|
||||
} 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)
|
||||
{
|
||||
devices[devId]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::xy);
|
||||
dev->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
|
||||
dev->setPropertyChanged(EspalexaDeviceProperty::xy);
|
||||
}
|
||||
|
||||
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());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::hs);
|
||||
dev->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
|
||||
dev->setPropertyChanged(EspalexaDeviceProperty::hs);
|
||||
}
|
||||
|
||||
if (body.indexOf("ct") >0) //COLOR TEMP command (white spectrum)
|
||||
{
|
||||
devices[devId]->setColor(body.substring(body.indexOf("ct") +4).toInt());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::ct);
|
||||
dev->setColor(body.substring(body.indexOf("ct") +4).toInt());
|
||||
dev->setPropertyChanged(EspalexaDeviceProperty::ct);
|
||||
}
|
||||
|
||||
devices[devId]->doCallback();
|
||||
dev->doCallback();
|
||||
|
||||
#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)");
|
||||
#endif
|
||||
return true;
|
||||
@ -539,25 +553,31 @@ public:
|
||||
String jsonTemp = "{";
|
||||
for (int i = 0; i<currentDeviceCount; i++)
|
||||
{
|
||||
jsonTemp += "\"" + String(i+1) + "\":";
|
||||
jsonTemp += '"';
|
||||
jsonTemp += encodeLightKey(i);
|
||||
jsonTemp += '"';
|
||||
jsonTemp += ':';
|
||||
|
||||
char buf[512];
|
||||
deviceJsonString(i+1, buf);
|
||||
deviceJsonString(devices[i], buf);
|
||||
jsonTemp += buf;
|
||||
if (i < currentDeviceCount-1) jsonTemp += ",";
|
||||
if (i < currentDeviceCount-1) jsonTemp += ',';
|
||||
}
|
||||
jsonTemp += "}";
|
||||
jsonTemp += '}';
|
||||
server->send(200, "application/json", jsonTemp);
|
||||
} else //client wants one light (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", "{}");
|
||||
} else {
|
||||
char buf[512];
|
||||
deviceJsonString(devId, buf);
|
||||
server->send(200, "application/json", buf);
|
||||
return true;
|
||||
}
|
||||
char buf[512];
|
||||
deviceJsonString(devices[idx], buf);
|
||||
server->send(200, "application/json", buf);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -65,6 +65,11 @@ uint8_t EspalexaDevice::getValue()
|
||||
return _val;
|
||||
}
|
||||
|
||||
bool EspalexaDevice::getState()
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
uint8_t EspalexaDevice::getPercent()
|
||||
{
|
||||
uint16_t perc = _val * 100;
|
||||
@ -111,7 +116,7 @@ uint32_t EspalexaDevice::getKelvin()
|
||||
uint32_t EspalexaDevice::getRGB()
|
||||
{
|
||||
if (_rgb != 0) return _rgb; //color has not changed
|
||||
byte rgb[4]{0, 0, 0, 0};
|
||||
byte rgb[4]{0, 0, 0, 0};
|
||||
|
||||
if (_mode == EspalexaColorMode::none) return 0;
|
||||
|
||||
@ -277,6 +282,16 @@ void EspalexaDevice::setValue(uint8_t val)
|
||||
_val = val;
|
||||
}
|
||||
|
||||
void EspalexaDevice::setState(bool onoff)
|
||||
{
|
||||
if (onoff)
|
||||
{
|
||||
setValue(_val_last);
|
||||
} else {
|
||||
setValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
void EspalexaDevice::setPercent(uint8_t perc)
|
||||
{
|
||||
uint16_t val = perc * 255;
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
uint8_t getId();
|
||||
EspalexaDeviceProperty getLastChangedProperty();
|
||||
uint8_t getValue();
|
||||
uint8_t getLastValue(); //last value that was not off (1-255)
|
||||
bool getState();
|
||||
uint8_t getPercent();
|
||||
uint8_t getDegrees();
|
||||
uint16_t getHue();
|
||||
@ -59,6 +61,7 @@ public:
|
||||
void setId(uint8_t id);
|
||||
void setPropertyChanged(EspalexaDeviceProperty p);
|
||||
void setValue(uint8_t bri);
|
||||
void setState(bool onoff);
|
||||
void setPercent(uint8_t perc);
|
||||
void setName(String name);
|
||||
void setColor(uint16_t ct);
|
||||
@ -67,8 +70,6 @@ public:
|
||||
void setColor(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
void doCallback();
|
||||
|
||||
uint8_t getLastValue(); //last value that was not off (1-255)
|
||||
};
|
||||
|
||||
#endif
|
@ -191,9 +191,6 @@ void WLED::loop()
|
||||
|
||||
handleOverlays();
|
||||
yield();
|
||||
#ifdef WLED_USE_ANALOG_LEDS
|
||||
strip.setRgbwPwm();
|
||||
#endif
|
||||
|
||||
if (doReboot)
|
||||
reset();
|
||||
@ -217,24 +214,6 @@ void WLED::loop()
|
||||
handleHue();
|
||||
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();
|
||||
|
||||
if (!offMode)
|
||||
@ -263,6 +242,24 @@ void WLED::loop()
|
||||
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();
|
||||
handleWs();
|
||||
handleStatusLED();
|
||||
|
@ -3,12 +3,12 @@
|
||||
/*
|
||||
Main sketch, global variable declarations
|
||||
@title WLED project sketch
|
||||
@version 0.12.0-a0
|
||||
@version 0.12.0-b4
|
||||
@author Christian Schwinne
|
||||
*/
|
||||
|
||||
// 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
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -148,11 +148,6 @@
|
||||
#define WLED_FS LITTLEFS
|
||||
#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
|
||||
// both declared and defined in header (solution from http://www.keil.com/support/docs/1868.htm)
|
||||
//
|
||||
@ -173,7 +168,7 @@
|
||||
#endif
|
||||
|
||||
// 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"
|
||||
|
||||
// AP and OTA default passwords (for maximum security change them!)
|
||||
@ -230,7 +225,6 @@ WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling
|
||||
|
||||
// LED CONFIG
|
||||
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 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 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)
|
||||
|
||||
// User Interface CONFIG
|
||||
@ -419,6 +412,7 @@ WLED_GLOBAL byte effectCurrent _INIT(0);
|
||||
WLED_GLOBAL byte effectSpeed _INIT(128);
|
||||
WLED_GLOBAL byte effectIntensity _INIT(128);
|
||||
WLED_GLOBAL byte effectPalette _INIT(0);
|
||||
WLED_GLOBAL bool effectChanged _INIT(false);
|
||||
|
||||
// network
|
||||
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
|
||||
WLED_GLOBAL BusManager busses _INIT(BusManager());
|
||||
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);
|
||||
|
||||
// Usermod manager
|
||||
|
@ -115,7 +115,6 @@ void loadSettingsFromEEPROM()
|
||||
}
|
||||
receiveNotificationBrightness = EEPROM.read(250);
|
||||
fadeTransition = EEPROM.read(251);
|
||||
// strip.reverseMode = EEPROM.read(252);
|
||||
transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00);
|
||||
transitionDelay = transitionDelayDefault;
|
||||
briMultiplier = EEPROM.read(255);
|
||||
@ -144,7 +143,7 @@ void loadSettingsFromEEPROM()
|
||||
arlsOffset = EEPROM.read(368);
|
||||
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
|
||||
turnOnAtBoot = EEPROM.read(369);
|
||||
useRGBW = EEPROM.read(372);
|
||||
strip.isRgbw = EEPROM.read(372);
|
||||
//374 - strip.paletteFade
|
||||
|
||||
apBehavior = EEPROM.read(376);
|
||||
@ -318,7 +317,7 @@ void loadSettingsFromEEPROM()
|
||||
notifyMacro = EEPROM.read(2201);
|
||||
|
||||
strip.rgbwMode = EEPROM.read(2203);
|
||||
skipFirstLed = EEPROM.read(2204);
|
||||
//was skipFirstLed = EEPROM.read(2204);
|
||||
|
||||
if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
|
||||
{
|
||||
@ -407,7 +406,7 @@ void deEEP() {
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
if (ClientApis[i].c) continue; // used slot
|
||||
ClientApis[i].c = client->id();
|
||||
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;
|
||||
}
|
||||
sendDataWs(client);
|
||||
@ -36,7 +36,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
if (ClientApis[i].c != client->id()) continue;
|
||||
ClientApis[i].c = 0; // clear slot
|
||||
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;
|
||||
}
|
||||
} else if(type == WS_EVT_DATA){
|
||||
|
@ -322,6 +322,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
|
||||
sappend('v',SET_F("LC"),ledCount);
|
||||
|
||||
bool skip = false;
|
||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||
Bus* bus = busses.getBus(s);
|
||||
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('c',cv,bus->reversed);
|
||||
sappend('c',ew,bus->isRgbw());
|
||||
skip = skip || bus->skipFirstLed();
|
||||
}
|
||||
sappend('v',SET_F("MA"),strip.ablMilliampsMax);
|
||||
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("TW"),nightlightMode);
|
||||
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('c',SET_F("RM"),rlyMde);
|
||||
sappend('v',SET_F("BT"),btnPin);
|
||||
|
Loading…
Reference in New Issue
Block a user