Merge branch 'master' into groupfinal
This commit is contained in:
commit
6bc927c535
@ -4,14 +4,17 @@
|
|||||||
[platformio]
|
[platformio]
|
||||||
src_dir = ./wled00
|
src_dir = ./wled00
|
||||||
data_dir = ./wled00/data
|
data_dir = ./wled00/data
|
||||||
lib_extra_dirs = ./wled00/src
|
;lib_extra_dirs = ./wled00/src
|
||||||
|
lib_dir = ./wled00/src
|
||||||
; Please uncomment one of the 5 lines below to select your board
|
; Please uncomment one of the 5 lines below to select your board
|
||||||
; env_default = nodemcuv2
|
; env_default = nodemcuv2
|
||||||
; env_default = esp01
|
; env_default = esp01
|
||||||
; env_default = esp01_1m
|
; env_default = esp01_1m
|
||||||
; env_default = d1_mini
|
; env_default = d1_mini
|
||||||
; env_default = esp32dev
|
; env_default = esp32dev
|
||||||
|
; env_default = esp8285_4CH_MagicHome
|
||||||
|
; env_default = esp8285_4CH_H801
|
||||||
|
; env_default = esp8285_5CH_H801
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
framework = arduino
|
framework = arduino
|
||||||
@ -38,6 +41,8 @@ lib_deps_external =
|
|||||||
IRremoteESP8266@2.5.5
|
IRremoteESP8266@2.5.5
|
||||||
#Time@1.5
|
#Time@1.5
|
||||||
#Timezone@1.2.1
|
#Timezone@1.2.1
|
||||||
|
#For use SSD1306 0.91" OLED display uncomment following
|
||||||
|
#U8g2@~2.27.2
|
||||||
|
|
||||||
[common:esp8266]
|
[common:esp8266]
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -77,7 +82,7 @@ build_flags =
|
|||||||
-D WLED_DISABLE_BLYNK
|
-D WLED_DISABLE_BLYNK
|
||||||
-D WLED_DISABLE_CRONIXIE
|
-D WLED_DISABLE_CRONIXIE
|
||||||
; -D WLED_DISABLE_HUESYNC
|
; -D WLED_DISABLE_HUESYNC
|
||||||
-D WLED_DISABLE_INFRARED
|
; -D WLED_DISABLE_INFRARED
|
||||||
|
|
||||||
[common:esp8266_512k]
|
[common:esp8266_512k]
|
||||||
platform = espressif8266@1.8.0
|
platform = espressif8266@1.8.0
|
||||||
@ -89,8 +94,8 @@ build_flags =
|
|||||||
; -D WLED_DISABLE_ALEXA
|
; -D WLED_DISABLE_ALEXA
|
||||||
-D WLED_DISABLE_BLYNK
|
-D WLED_DISABLE_BLYNK
|
||||||
-D WLED_DISABLE_CRONIXIE
|
-D WLED_DISABLE_CRONIXIE
|
||||||
; -D WLED_DISABLE_HUESYNC
|
-D WLED_DISABLE_HUESYNC
|
||||||
-D WLED_DISABLE_INFRARED
|
; -D WLED_DISABLE_INFRARED
|
||||||
|
|
||||||
[common:esp32]
|
[common:esp32]
|
||||||
platform = espressif32@1.11.1
|
platform = espressif32@1.11.1
|
||||||
@ -147,6 +152,7 @@ framework = ${common.framework}
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
${common:esp8266_512k.build_flags}
|
${common:esp8266_512k.build_flags}
|
||||||
|
-D WLED_DISABLE_INFRARED
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps_external}
|
${common.lib_deps_external}
|
||||||
|
|
||||||
@ -165,3 +171,49 @@ lib_deps =
|
|||||||
lib_ignore =
|
lib_ignore =
|
||||||
IRremoteESP8266
|
IRremoteESP8266
|
||||||
ESPAsyncUDP
|
ESPAsyncUDP
|
||||||
|
|
||||||
|
[env:esp8285_4CH_MagicHome]
|
||||||
|
board = esp8285
|
||||||
|
platform = ${common:esp8266_1M.platform}
|
||||||
|
monitor_speed = ${common.monitor_speed}
|
||||||
|
upload_speed = ${common.upload_speed}
|
||||||
|
framework = ${common.framework}
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
${common:esp8266_1M.build_flags}
|
||||||
|
-D WLED_DISABLE_HUESYNC
|
||||||
|
-D WLED_ENABLE_ANALOG_LEDS
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps_external}
|
||||||
|
|
||||||
|
[env:esp8285_4CH_H801]
|
||||||
|
board = esp8285
|
||||||
|
platform = ${common:esp8266_1M.platform}
|
||||||
|
monitor_speed = ${common.monitor_speed}
|
||||||
|
upload_speed = ${common.upload_speed}
|
||||||
|
framework = ${common.framework}
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
${common:esp8266_1M.build_flags}
|
||||||
|
-D WLED_DISABLE_HUESYNC
|
||||||
|
-D WLED_ENABLE_ANALOG_LEDS
|
||||||
|
-D WLED_USE_H801
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps_external}
|
||||||
|
|
||||||
|
[env:esp8285_5CH_H801]
|
||||||
|
board = esp8285
|
||||||
|
platform = ${common:esp8266_1M.platform}
|
||||||
|
monitor_speed = ${common.monitor_speed}
|
||||||
|
upload_speed = ${common.upload_speed}
|
||||||
|
framework = ${common.framework}
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
${common:esp8266_1M.build_flags}
|
||||||
|
-D WLED_DISABLE_HUESYNC
|
||||||
|
-D WLED_ENABLE_ANALOG_LEDS
|
||||||
|
-D WLED_USE_H801
|
||||||
|
-D WLED_ENABLE_5CH_LEDS
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps_external}
|
||||||
|
|
||||||
|
@ -10,13 +10,14 @@
|
|||||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
|
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
|
||||||
|
|
||||||
### Features:
|
### Features:
|
||||||
- WS2812FX library integrated for 80 special effects
|
- WS2812FX library integrated for almost 90 special effects
|
||||||
- FastLED noise effects and palettes
|
- FastLED noise effects and palettes
|
||||||
- Customizable Mobile and desktop UI with color and effect controls
|
- Modern UI with color, effect and segment controls
|
||||||
|
- Segments to set different effects and colors to parts of the LEDs
|
||||||
- Settings page - configuration over network
|
- Settings page - configuration over network
|
||||||
- Access Point and station mode - automatic failsafe AP
|
- Access Point and station mode - automatic failsafe AP
|
||||||
- Support for RGBW strips
|
- Support for RGBW strips
|
||||||
- 25 user presets to save and load colors/effects easily, supports cycling through them.
|
- 16 user presets to save and load colors/effects easily, supports cycling through them.
|
||||||
- Macro functions to automatically execute API calls
|
- Macro functions to automatically execute API calls
|
||||||
- Nightlight function (gradually dims down)
|
- Nightlight function (gradually dims down)
|
||||||
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
||||||
|
@ -4,5 +4,5 @@ This code uses Aircookie's WLED software. It has a premade file for user modific
|
|||||||
|
|
||||||
To install:
|
To install:
|
||||||
|
|
||||||
Add the enties in the WLED00 file to the top of the same file from Aircoookies WLED.
|
Add the entries in the WLED00 file to the top of the same file from Aircoookies WLED.
|
||||||
Replace the WLED06_usermod.ino file in Aircoookies WLED folder.
|
Replace the WLED06_usermod.ino file in Aircoookies WLED folder.
|
||||||
|
45
usermods/rotary_encoder_change_effect/wled06_usermod.ino
Normal file
45
usermods/rotary_encoder_change_effect/wled06_usermod.ino
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
|
||||||
|
|
||||||
|
long lastTime = 0;
|
||||||
|
int delayMs = 10;
|
||||||
|
const int pinA = D6; //data
|
||||||
|
const int pinB = D7; //clk
|
||||||
|
int oldA = LOW;
|
||||||
|
|
||||||
|
//gets called once at boot. Do all initialization that doesn't depend on network here
|
||||||
|
void userSetup() {
|
||||||
|
pinMode(pinA, INPUT_PULLUP);
|
||||||
|
pinMode(pinB, INPUT_PULLUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
|
||||||
|
void userConnected() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
|
||||||
|
void userLoop() {
|
||||||
|
if (millis()-lastTime > delayMs) {
|
||||||
|
int A = digitalRead(pinA);
|
||||||
|
int B = digitalRead(pinB);
|
||||||
|
|
||||||
|
if (oldA == LOW && A == HIGH) {
|
||||||
|
if (oldB == HIGH) {
|
||||||
|
// bri += 10;
|
||||||
|
// if (bri > 250) bri = 10;
|
||||||
|
effectCurrent += 1;
|
||||||
|
if (effectCurrent >= MODE_COUNT) effectCurrent = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// bri -= 10;
|
||||||
|
// if (bri < 10) bri = 250;
|
||||||
|
effectCurrent -= 1;
|
||||||
|
if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1);
|
||||||
|
}
|
||||||
|
oldA = A;
|
||||||
|
|
||||||
|
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
||||||
|
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
||||||
|
colorUpdated(6);
|
||||||
|
lastTime = millis();
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,18 @@
|
|||||||
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
||||||
|
|
||||||
|
//The SCL and SDA pins are defined here.
|
||||||
|
//Lolin32 boards use SCL=5 SDA=4
|
||||||
|
#define U8X8_PIN_SCL 5
|
||||||
|
#define U8X8_PIN_SDA 4
|
||||||
|
|
||||||
|
|
||||||
// If display does not work or looks corrupted check the
|
// If display does not work or looks corrupted check the
|
||||||
// constructor reference:
|
// constructor reference:
|
||||||
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
|
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
|
||||||
// or check the gallery:
|
// or check the gallery:
|
||||||
// https://github.com/olikraus/u8g2/wiki/gallery
|
// https://github.com/olikraus/u8g2/wiki/gallery
|
||||||
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, 5,
|
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL,
|
||||||
4); // Pins are Reset, SCL, SDA
|
U8X8_PIN_SDA); // Pins are Reset, SCL, SDA
|
||||||
|
|
||||||
// gets called once at boot. Do all initialization that doesn't depend on
|
// gets called once at boot. Do all initialization that doesn't depend on
|
||||||
// network here
|
// network here
|
||||||
@ -63,7 +69,11 @@ void userLoop() {
|
|||||||
needRedraw = false;
|
needRedraw = false;
|
||||||
|
|
||||||
// Update last known values.
|
// Update last known values.
|
||||||
|
#if defined(ESP8266)
|
||||||
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
|
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
|
||||||
|
#else
|
||||||
|
knownSsid = WiFi.SSID();
|
||||||
|
#endif
|
||||||
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
|
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
|
||||||
knownBrightness = bri;
|
knownBrightness = bri;
|
||||||
knownMode = strip.getMode();
|
knownMode = strip.getMode();
|
||||||
@ -74,9 +84,9 @@ void userLoop() {
|
|||||||
|
|
||||||
// First row with Wifi name
|
// First row with Wifi name
|
||||||
u8x8.setCursor(1, 0);
|
u8x8.setCursor(1, 0);
|
||||||
u8x8.print(ssid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0));
|
u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0));
|
||||||
// Print `~` char to indicate that SSID is longer, than owr dicplay
|
// Print `~` char to indicate that SSID is longer, than owr dicplay
|
||||||
if (ssid.length() > u8x8.getCols())
|
if (knownSsid.length() > u8x8.getCols())
|
||||||
u8x8.print("~");
|
u8x8.print("~");
|
||||||
|
|
||||||
// Second row with IP or Psssword
|
// Second row with IP or Psssword
|
||||||
@ -85,7 +95,7 @@ void userLoop() {
|
|||||||
if (apActive && bri == 0)
|
if (apActive && bri == 0)
|
||||||
u8x8.print(apPass);
|
u8x8.print(apPass);
|
||||||
else
|
else
|
||||||
u8x8.print(ip);
|
u8x8.print(knownIp);
|
||||||
|
|
||||||
// Third row with mode name
|
// Third row with mode name
|
||||||
u8x8.setCursor(2, 2);
|
u8x8.setCursor(2, 2);
|
||||||
|
995
wled00/FX.cpp
995
wled00/FX.cpp
File diff suppressed because it is too large
Load Diff
105
wled00/FX.h
105
wled00/FX.h
@ -42,12 +42,19 @@
|
|||||||
|
|
||||||
/* Not used in all effects yet */
|
/* Not used in all effects yet */
|
||||||
#define WLED_FPS 42
|
#define WLED_FPS 42
|
||||||
#define FRAMETIME 1000/WLED_FPS
|
#define FRAMETIME (1000/WLED_FPS)
|
||||||
|
|
||||||
/* each segment uses 41 bytes of SRAM memory, so if you're application fails because of
|
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
#define MAX_NUM_SEGMENTS 10
|
#define MAX_NUM_SEGMENTS 10
|
||||||
|
|
||||||
|
/* How much data bytes all segments combined may allocate */
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define MAX_SEGMENT_DATA 2048
|
||||||
|
#else
|
||||||
|
#define MAX_SEGMENT_DATA 8192
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NUM_COLORS 3 /* number of colors per segment */
|
#define NUM_COLORS 3 /* number of colors per segment */
|
||||||
#define SEGMENT _segments[_segment_index]
|
#define SEGMENT _segments[_segment_index]
|
||||||
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
|
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
|
||||||
@ -84,7 +91,7 @@
|
|||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
||||||
|
|
||||||
#define MODE_COUNT 87
|
#define MODE_COUNT 96
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -173,11 +180,23 @@
|
|||||||
#define FX_MODE_TRI_STATIC_PATTERN 84
|
#define FX_MODE_TRI_STATIC_PATTERN 84
|
||||||
#define FX_MODE_SPOTS 85
|
#define FX_MODE_SPOTS 85
|
||||||
#define FX_MODE_SPOTS_FADE 86
|
#define FX_MODE_SPOTS_FADE 86
|
||||||
|
#define FX_MODE_GLITTER 87
|
||||||
|
#define FX_MODE_CANDLE 88
|
||||||
|
#define FX_MODE_STARBURST 89
|
||||||
|
#define FX_MODE_EXPLODING_FIREWORKS 90
|
||||||
|
#define FX_MODE_BOUNCINGBALLS 91
|
||||||
|
#define FX_MODE_SINELON 92
|
||||||
|
#define FX_MODE_SINELON_DUAL 93
|
||||||
|
#define FX_MODE_SINELON_RAINBOW 94
|
||||||
|
#define FX_MODE_POPCORN 95
|
||||||
|
|
||||||
|
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||||
|
|
||||||
|
// pre show callback
|
||||||
|
typedef void (*show_callback) (void);
|
||||||
|
|
||||||
// segment parameters
|
// segment parameters
|
||||||
public:
|
public:
|
||||||
typedef struct Segment { // 25 bytes
|
typedef struct Segment { // 25 bytes
|
||||||
@ -223,13 +242,33 @@ class WS2812FX {
|
|||||||
} segment;
|
} segment;
|
||||||
|
|
||||||
// segment runtime parameters
|
// segment runtime parameters
|
||||||
typedef struct Segment_runtime { // 16 bytes
|
typedef struct Segment_runtime { // 28 bytes
|
||||||
unsigned long next_time;
|
unsigned long next_time;
|
||||||
uint32_t step;
|
uint32_t step;
|
||||||
uint32_t call;
|
uint32_t call;
|
||||||
uint16_t aux0;
|
uint16_t aux0;
|
||||||
uint16_t aux1;
|
uint16_t aux1;
|
||||||
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;};
|
byte* data = nullptr;
|
||||||
|
bool allocateData(uint16_t len){
|
||||||
|
if (data && _dataLen == len) return true; //already allocated
|
||||||
|
deallocateData();
|
||||||
|
if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory
|
||||||
|
data = new (std::nothrow) byte[len];
|
||||||
|
if (!data) return false; //allocation failed
|
||||||
|
WS2812FX::_usedSegmentData += len;
|
||||||
|
_dataLen = len;
|
||||||
|
memset(data, 0, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void deallocateData(){
|
||||||
|
delete[] data;
|
||||||
|
data = nullptr;
|
||||||
|
WS2812FX::_usedSegmentData -= _dataLen;
|
||||||
|
_dataLen = 0;
|
||||||
|
}
|
||||||
|
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();}
|
||||||
|
private:
|
||||||
|
uint16_t _dataLen = 0;
|
||||||
} segment_runtime;
|
} segment_runtime;
|
||||||
|
|
||||||
WS2812FX() {
|
WS2812FX() {
|
||||||
@ -321,6 +360,15 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
||||||
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
||||||
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
||||||
|
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
|
||||||
|
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
|
||||||
|
_mode[FX_MODE_STARBURST] = &WS2812FX::mode_starburst;
|
||||||
|
_mode[FX_MODE_EXPLODING_FIREWORKS] = &WS2812FX::mode_exploding_fireworks;
|
||||||
|
_mode[FX_MODE_BOUNCINGBALLS] = &WS2812FX::mode_bouncing_balls;
|
||||||
|
_mode[FX_MODE_SINELON] = &WS2812FX::mode_sinelon;
|
||||||
|
_mode[FX_MODE_SINELON_DUAL] = &WS2812FX::mode_sinelon_dual;
|
||||||
|
_mode[FX_MODE_SINELON_RAINBOW] = &WS2812FX::mode_sinelon_rainbow;
|
||||||
|
_mode[FX_MODE_POPCORN] = &WS2812FX::mode_popcorn;
|
||||||
|
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
@ -328,8 +376,6 @@ class WS2812FX {
|
|||||||
ablMilliampsMax = 850;
|
ablMilliampsMax = 850;
|
||||||
currentMilliamps = 0;
|
currentMilliamps = 0;
|
||||||
timebase = 0;
|
timebase = 0;
|
||||||
_locked = nullptr;
|
|
||||||
_modeUsesLock = false;
|
|
||||||
bus = new NeoPixelWrapper();
|
bus = new NeoPixelWrapper();
|
||||||
resetSegments();
|
resetSegments();
|
||||||
}
|
}
|
||||||
@ -346,13 +392,8 @@ class WS2812FX {
|
|||||||
driverModeCronixie(bool b),
|
driverModeCronixie(bool b),
|
||||||
setCronixieDigits(byte* d),
|
setCronixieDigits(byte* d),
|
||||||
setCronixieBacklight(bool b),
|
setCronixieBacklight(bool b),
|
||||||
setIndividual(uint16_t i, uint32_t col),
|
|
||||||
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
||||||
lock(uint16_t i),
|
setShowCallback(show_callback cb),
|
||||||
lockRange(uint16_t i, uint16_t i2),
|
|
||||||
unlock(uint16_t i),
|
|
||||||
unlockRange(uint16_t i, uint16_t i2),
|
|
||||||
unlockAll(void),
|
|
||||||
setTransitionMode(bool t),
|
setTransitionMode(bool t),
|
||||||
trigger(void),
|
trigger(void),
|
||||||
setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing),
|
setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing),
|
||||||
@ -502,7 +543,17 @@ class WS2812FX {
|
|||||||
mode_static_pattern(void),
|
mode_static_pattern(void),
|
||||||
mode_tri_static_pattern(void),
|
mode_tri_static_pattern(void),
|
||||||
mode_spots(void),
|
mode_spots(void),
|
||||||
mode_spots_fade(void);
|
mode_spots_fade(void),
|
||||||
|
mode_glitter(void),
|
||||||
|
mode_candle(void),
|
||||||
|
mode_starburst(void),
|
||||||
|
mode_exploding_fireworks(void),
|
||||||
|
mode_bouncing_balls(void),
|
||||||
|
mode_sinelon(void),
|
||||||
|
mode_sinelon_dual(void),
|
||||||
|
mode_sinelon_rainbow(void),
|
||||||
|
mode_popcorn(void);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -516,24 +567,24 @@ class WS2812FX {
|
|||||||
uint16_t _length;
|
uint16_t _length;
|
||||||
uint16_t _rand16seed;
|
uint16_t _rand16seed;
|
||||||
uint8_t _brightness;
|
uint8_t _brightness;
|
||||||
|
static uint16_t _usedSegmentData;
|
||||||
|
|
||||||
void handle_palette(void);
|
void handle_palette(void);
|
||||||
void fill(uint32_t);
|
void fill(uint32_t);
|
||||||
bool modeUsesLock(uint8_t);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_modeUsesLock,
|
|
||||||
_rgbwMode,
|
_rgbwMode,
|
||||||
_cronixieMode,
|
_cronixieMode,
|
||||||
_cronixieBacklightEnabled,
|
_cronixieBacklightEnabled,
|
||||||
_skipFirstMode,
|
_skipFirstMode,
|
||||||
_triggered;
|
_triggered;
|
||||||
|
|
||||||
byte* _locked;
|
|
||||||
byte _cronixieDigits[6];
|
byte _cronixieDigits[6];
|
||||||
|
|
||||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||||
|
|
||||||
|
show_callback _callback = nullptr;
|
||||||
|
|
||||||
// mode helper functions
|
// mode helper functions
|
||||||
uint16_t
|
uint16_t
|
||||||
blink(uint32_t, uint32_t, bool strobe, bool),
|
blink(uint32_t, uint32_t, bool strobe, bool),
|
||||||
@ -541,6 +592,8 @@ class WS2812FX {
|
|||||||
scan(bool),
|
scan(bool),
|
||||||
theater_chase(uint32_t, uint32_t, bool),
|
theater_chase(uint32_t, uint32_t, bool),
|
||||||
running_base(bool),
|
running_base(bool),
|
||||||
|
larson_scanner(bool),
|
||||||
|
sinelon_base(bool,bool),
|
||||||
dissolve(uint32_t),
|
dissolve(uint32_t),
|
||||||
chase(uint32_t, uint32_t, uint32_t, bool),
|
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||||
gradient_base(bool),
|
gradient_base(bool),
|
||||||
@ -561,7 +614,9 @@ class WS2812FX {
|
|||||||
// start, stop, length, speed, intensity, palette, mode, options, group, spacing, opacity (unused), color[]
|
// start, stop, length, speed, intensity, palette, mode, options, group, spacing, opacity (unused), color[]
|
||||||
{ 0, 7, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
|
{ 0, 7, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
|
||||||
};
|
};
|
||||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
|
|
||||||
|
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
|
||||||
|
friend class Segment_runtime;
|
||||||
|
|
||||||
uint16_t realPixelIndex(uint16_t i);
|
uint16_t realPixelIndex(uint16_t i);
|
||||||
};
|
};
|
||||||
@ -570,14 +625,15 @@ class WS2812FX {
|
|||||||
//10 names per line
|
//10 names per line
|
||||||
const char JSON_mode_names[] PROGMEM = R"=====([
|
const char JSON_mode_names[] PROGMEM = R"=====([
|
||||||
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
|
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
|
||||||
"Scan","Dual Scan","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
|
"Scan","Scan Dual","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
|
||||||
"Sparkle","Dark Sparkle","Sparkle+","Strobe","Strobe Rainbow","Mega Strobe","Blink Rainbow","Android","Chase","Chase Random",
|
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
|
||||||
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
||||||
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
|
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
|
||||||
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||||
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
||||||
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
|
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
|
||||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade"
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
||||||
|
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
@ -586,7 +642,8 @@ const char JSON_palette_names[] PROGMEM = R"=====([
|
|||||||
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
|
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
|
||||||
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
||||||
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
||||||
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura"
|
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
|
||||||
|
"Aurora"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst)
|
void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint8_t spacing, bool skipFirst)
|
||||||
{
|
{
|
||||||
if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && group == _group && spacing == _spacing) return;
|
if (supportWhite == _rgbwMode && countPixels == _length && disableNLeds == _disableNLeds) return;
|
||||||
RESET_RUNTIME;
|
RESET_RUNTIME;
|
||||||
_rgbwMode = supportWhite;
|
_rgbwMode = supportWhite;
|
||||||
_skipFirstMode = skipFirst;
|
_skipFirstMode = skipFirst;
|
||||||
@ -46,16 +46,13 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t group, uint
|
|||||||
|
|
||||||
bus->Begin((NeoPixelType)ty, lengthRaw);
|
bus->Begin((NeoPixelType)ty, lengthRaw);
|
||||||
|
|
||||||
delete[] _locked;
|
|
||||||
_locked = new byte[_length];
|
|
||||||
|
|
||||||
_segments[0].start = 0;
|
_segments[0].start = 0;
|
||||||
|
|
||||||
_segments[0].group = _group;
|
_segments[0].group = _group;
|
||||||
_segments[0].spacing = _spacing;
|
_segments[0].spacing = _spacing;
|
||||||
_segments[0].stop = getUsableCount();
|
_segments[0].stop = getUsableCount();
|
||||||
_segments[0].rawLength = _length;
|
_segments[0].rawLength = _length;
|
||||||
|
|
||||||
unlockAll();
|
|
||||||
setBrightness(_brightness);
|
setBrightness(_brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,14 +88,6 @@ void WS2812FX::service() {
|
|||||||
_triggered = false;
|
_triggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WS2812FX::modeUsesLock(uint8_t m)
|
|
||||||
{
|
|
||||||
if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE ||
|
|
||||||
m == FX_MODE_METEOR || m == FX_MODE_METEOR_SMOOTH ||
|
|
||||||
m == FX_MODE_RIPPLE || m == FX_MODE_DYNAMIC ) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||||
uint8_t w = (c >> 24);
|
uint8_t w = (c >> 24);
|
||||||
uint8_t r = (c >> 16);
|
uint8_t r = (c >> 16);
|
||||||
@ -124,10 +113,10 @@ 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)
|
||||||
{
|
{
|
||||||
if (_locked[i] && !_modeUsesLock) return;
|
|
||||||
|
|
||||||
RgbwColor color;
|
RgbwColor color;
|
||||||
color.W = w;
|
color.W = w;
|
||||||
|
|
||||||
switch (colorOrder) //0 = Grb, default
|
switch (colorOrder) //0 = Grb, default
|
||||||
{
|
{
|
||||||
case 0: color.G = g; color.R = r; color.B = b; break; // 0 = GRB
|
case 0: color.G = g; color.R = r; color.B = b; break; // 0 = GRB
|
||||||
@ -218,6 +207,8 @@ void WS2812FX::setCronixieDigits(byte d[])
|
|||||||
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
||||||
|
|
||||||
void WS2812FX::show(void) {
|
void WS2812FX::show(void) {
|
||||||
|
if (_callback) _callback();
|
||||||
|
|
||||||
//power limit calculation
|
//power limit calculation
|
||||||
//each LED can draw up 195075 "power units" (approx. 53mA)
|
//each LED can draw up 195075 "power units" (approx. 53mA)
|
||||||
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
||||||
@ -283,7 +274,6 @@ void WS2812FX::trigger() {
|
|||||||
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
||||||
if (segid >= MAX_NUM_SEGMENTS) return;
|
if (segid >= MAX_NUM_SEGMENTS) return;
|
||||||
|
|
||||||
bool anyUsedLock = _modeUsesLock, anyUseLock = false;
|
|
||||||
if (m >= MODE_COUNT) m = MODE_COUNT - 1;
|
if (m >= MODE_COUNT) m = MODE_COUNT - 1;
|
||||||
|
|
||||||
if (_segments[segid].mode != m)
|
if (_segments[segid].mode != m)
|
||||||
@ -291,13 +281,6 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
|||||||
_segment_runtimes[segid].reset();
|
_segment_runtimes[segid].reset();
|
||||||
_segments[segid].mode = m;
|
_segments[segid].mode = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
|
||||||
{
|
|
||||||
if (modeUsesLock(_segments[i].mode)) anyUseLock = true;
|
|
||||||
}
|
|
||||||
if (anyUsedLock && !anyUseLock) unlockAll();
|
|
||||||
_modeUsesLock = anyUseLock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::getModeCount()
|
uint8_t WS2812FX::getModeCount()
|
||||||
@ -457,13 +440,9 @@ uint32_t WS2812FX::getLastShow(void) {
|
|||||||
void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing) {
|
void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t group, uint8_t spacing) {
|
||||||
if (n >= MAX_NUM_SEGMENTS) return;
|
if (n >= MAX_NUM_SEGMENTS) return;
|
||||||
Segment& seg = _segments[n];
|
Segment& seg = _segments[n];
|
||||||
|
|
||||||
if (seg.start == start && seg.rawLength == length && seg.group == group && seg.spacing == spacing) return;
|
if (seg.start == start && seg.rawLength == length && seg.group == group && seg.spacing == spacing) return;
|
||||||
if (seg.isActive() && modeUsesLock(seg.mode))
|
|
||||||
{
|
|
||||||
_modeUsesLock = false;
|
|
||||||
unlockRange(seg.start, seg.stop);
|
|
||||||
_modeUsesLock = true;
|
|
||||||
}
|
|
||||||
_segment_index = n; fill(0); //turn old segment range off
|
_segment_index = n; fill(0); //turn old segment range off
|
||||||
|
|
||||||
seg.rawLength = min(_length - start, length);
|
seg.rawLength = min(_length - start, length);
|
||||||
@ -482,7 +461,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t length, uint8_t gr
|
|||||||
|
|
||||||
void WS2812FX::resetSegments() {
|
void WS2812FX::resetSegments() {
|
||||||
memset(_segments, 0, sizeof(_segments));
|
memset(_segments, 0, sizeof(_segments));
|
||||||
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
|
//memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
|
||||||
_segment_index = 0;
|
_segment_index = 0;
|
||||||
_segments[0].mode = DEFAULT_MODE;
|
_segments[0].mode = DEFAULT_MODE;
|
||||||
_segments[0].colors[0] = DEFAULT_COLOR;
|
_segments[0].colors[0] = DEFAULT_COLOR;
|
||||||
@ -491,65 +470,32 @@ void WS2812FX::resetSegments() {
|
|||||||
_segments[0].stop = getUsableCount();
|
_segments[0].stop = getUsableCount();
|
||||||
_segments[0].rawLength = _length;
|
_segments[0].rawLength = _length;
|
||||||
_segments[0].setOption(0, 1); //select
|
_segments[0].setOption(0, 1); //select
|
||||||
|
|
||||||
_segments[0].group = _group;
|
_segments[0].group = _group;
|
||||||
_segments[0].spacing = _spacing;
|
_segments[0].spacing = _spacing;
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
|
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
||||||
{
|
|
||||||
if (modeUsesLock(SEGMENT.mode)) return;
|
|
||||||
if (i >= 0 && i < _length)
|
|
||||||
{
|
{
|
||||||
_locked[i] = false;
|
_segments[i].colors[0] = color_wheel(i*51);
|
||||||
setPixelColor(i, col);
|
_segment_runtimes[i].reset();
|
||||||
_locked[i] = true;
|
|
||||||
}
|
}
|
||||||
|
_segment_runtimes[0].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
|
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
|
||||||
{
|
{
|
||||||
if (i2 >= i)
|
if (i2 >= i)
|
||||||
{
|
{
|
||||||
for (uint16_t x = i; x <= i2; x++) setIndividual(x,col);
|
for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
for (uint16_t x = i2; x <= i; x++) setIndividual(x,col);
|
for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::lock(uint16_t i)
|
void WS2812FX::setShowCallback(show_callback cb)
|
||||||
{
|
{
|
||||||
if (_modeUsesLock) return;
|
_callback = cb;
|
||||||
if (i < _length) _locked[i] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::lockRange(uint16_t i, uint16_t i2)
|
|
||||||
{
|
|
||||||
if (_modeUsesLock) return;
|
|
||||||
for (uint16_t x = i; x < i2; x++)
|
|
||||||
{
|
|
||||||
if (x < _length) _locked[i] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::unlock(uint16_t i)
|
|
||||||
{
|
|
||||||
if (_modeUsesLock) return;
|
|
||||||
if (i < _length) _locked[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::unlockRange(uint16_t i, uint16_t i2)
|
|
||||||
{
|
|
||||||
if (_modeUsesLock) return;
|
|
||||||
for (uint16_t x = i; x < i2; x++)
|
|
||||||
{
|
|
||||||
if (x < _length) _locked[x] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::unlockAll()
|
|
||||||
{
|
|
||||||
for (int i=0; i < _length; i++) _locked[i] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setTransitionMode(bool t)
|
void WS2812FX::setTransitionMode(bool t)
|
||||||
@ -723,7 +669,8 @@ void WS2812FX::handle_palette(void)
|
|||||||
_segment_index_palette_last = _segment_index;
|
_segment_index_palette_last = _segment_index;
|
||||||
|
|
||||||
byte paletteIndex = SEGMENT.palette;
|
byte paletteIndex = SEGMENT.palette;
|
||||||
if ((SEGMENT.mode >= FX_MODE_METEOR) && SEGMENT.palette == 0) paletteIndex = 4;
|
if (SEGMENT.mode == FX_MODE_GLITTER && paletteIndex == 0) paletteIndex = 11;
|
||||||
|
if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4;
|
||||||
|
|
||||||
switch (paletteIndex)
|
switch (paletteIndex)
|
||||||
{
|
{
|
||||||
@ -737,6 +684,7 @@ void WS2812FX::handle_palette(void)
|
|||||||
case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow
|
case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow
|
||||||
case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
||||||
case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
||||||
|
//case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break;
|
||||||
|
|
||||||
default: targetPalette = PartyColors_p; break;//palette, bpm
|
default: targetPalette = PartyColors_p; break;//palette, bpm
|
||||||
}
|
}
|
||||||
@ -775,7 +723,8 @@ void WS2812FX::handle_palette(void)
|
|||||||
case 5: {//based on primary + secondary
|
case 5: {//based on primary + secondary
|
||||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||||
targetPalette = CRGBPalette16(sec,prim,CRGB::White); break;}
|
CRGB ter = col_to_crgb(SEGCOLOR(2));
|
||||||
|
targetPalette = CRGBPalette16(ter,sec,prim); break;}
|
||||||
case 6: //Party colors
|
case 6: //Party colors
|
||||||
targetPalette = PartyColors_p; break;
|
targetPalette = PartyColors_p; break;
|
||||||
case 7: //Cloud colors
|
case 7: //Cloud colors
|
||||||
@ -867,3 +816,5 @@ uint32_t WS2812FX::gamma32(uint32_t color)
|
|||||||
b = gammaT[b];
|
b = gammaT[b];
|
||||||
return ((w << 24) | (r << 16) | (g << 8) | (b));
|
return ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::_usedSegmentData = 0;
|
||||||
|
@ -5,12 +5,18 @@
|
|||||||
//PIN CONFIGURATION
|
//PIN CONFIGURATION
|
||||||
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
||||||
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
||||||
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13)
|
||||||
#define IR_PIN 4 //infrared pin (-1 to disable)
|
//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
|
||||||
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
|
//#define WLED_USE_5CH //5 Channel H801 for cold and warm white
|
||||||
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
|
|
||||||
|
|
||||||
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
||||||
|
#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
|
||||||
|
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
|
||||||
|
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
|
||||||
|
|
||||||
|
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
||||||
|
|
||||||
|
//END CONFIGURATION
|
||||||
|
|
||||||
#ifdef USE_APA102
|
#ifdef USE_APA102
|
||||||
#define CLKPIN 0
|
#define CLKPIN 0
|
||||||
@ -20,6 +26,27 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
//PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller
|
||||||
|
#ifdef WLED_USE_H801
|
||||||
|
#define RPIN 15 //R pin for analog LED strip
|
||||||
|
#define GPIN 13 //G pin for analog LED strip
|
||||||
|
#define BPIN 12 //B pin for analog LED strip
|
||||||
|
#define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04)
|
||||||
|
#define W2PIN 04 //W2 pin for analog LED strip
|
||||||
|
#undef BTNPIN
|
||||||
|
#undef IR_PIN
|
||||||
|
#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
|
||||||
|
#else
|
||||||
|
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
|
||||||
|
#define RPIN 5 //R pin for analog LED strip
|
||||||
|
#define GPIN 12 //G pin for analog LED strip
|
||||||
|
#define BPIN 15 //B pin for analog LED strip
|
||||||
|
#define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04)
|
||||||
|
#endif
|
||||||
|
#undef RLYPIN
|
||||||
|
#define RLYPIN -1 //disable as pin 12 is used by analog LEDs
|
||||||
|
#endif
|
||||||
|
|
||||||
//automatically uses the right driver method for each platform
|
//automatically uses the right driver method for each platform
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
@ -103,41 +130,94 @@ public:
|
|||||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
|
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
|
||||||
#endif
|
#endif
|
||||||
_pGrbw->Begin();
|
_pGrbw->Begin();
|
||||||
|
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
pinMode(WPIN, OUTPUT);
|
||||||
|
#ifdef WLED_USE_5CH_LEDS
|
||||||
|
pinMode(W2PIN, OUTPUT);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
//init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
|
||||||
|
pinMode(RPIN, OUTPUT);
|
||||||
|
pinMode(GPIN, OUTPUT);
|
||||||
|
pinMode(BPIN, OUTPUT);
|
||||||
|
analogWriteRange(255); //same range as one RGB channel
|
||||||
|
analogWriteFreq(880); //PWM frequency proven as good for LEDs
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0)
|
||||||
|
{
|
||||||
|
analogWrite(RPIN, r);
|
||||||
|
analogWrite(GPIN, g);
|
||||||
|
analogWrite(BPIN, b);
|
||||||
|
switch (_type) {
|
||||||
|
case NeoPixelType_Grb: break;
|
||||||
|
#ifdef WLED_USE_5CH_LEDS
|
||||||
|
case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break;
|
||||||
|
#else
|
||||||
|
case NeoPixelType_Grbw: analogWrite(WPIN, w); break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Show()
|
void Show()
|
||||||
{
|
{
|
||||||
|
byte b;
|
||||||
switch (_type)
|
switch (_type)
|
||||||
{
|
{
|
||||||
case NeoPixelType_Grb: _pGrb->Show(); break;
|
case NeoPixelType_Grb: _pGrb->Show(); break;
|
||||||
case NeoPixelType_Grbw: _pGrbw->Show(); break;
|
case NeoPixelType_Grbw: _pGrbw->Show(); break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CanShow() const
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->CanShow(); break;
|
|
||||||
case NeoPixelType_Grbw: _pGrbw->CanShow(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPixelColor(uint16_t indexPixel, RgbColor color)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
|
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
|
||||||
{
|
{
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
|
case NeoPixelType_Grb: {
|
||||||
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
|
_pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
if (indexPixel != 0) return; //set analog LEDs from first pixel
|
||||||
|
byte b = _pGrb->GetBrightness();
|
||||||
|
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NeoPixelType_Grbw: {
|
||||||
|
_pGrbw->SetPixelColor(indexPixel, color);
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
if (indexPixel != 0) return; //set analog LEDs from first pixel
|
||||||
|
byte b = _pGrbw->GetBrightness();
|
||||||
|
// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
|
||||||
|
#ifdef WLED_USE_5CH_LEDS
|
||||||
|
if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, 0, color.W * b / 255);
|
||||||
|
} else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 512, colorW.W * b / 255);
|
||||||
|
} else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
|
||||||
|
} else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512);
|
||||||
|
} else if (color.R == 255 & color.G == 153 && color.B == 0 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
|
||||||
|
} else { // not only white colors
|
||||||
|
SetRgbwPwm(color.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, color.W * b / 255);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBrightness(byte b)
|
void SetBrightness(byte b)
|
||||||
@ -148,15 +228,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbColor GetPixelColor(uint16_t indexPixel) const
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
|
|
||||||
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Due to feature differences, some support RGBW but the method name
|
// NOTE: Due to feature differences, some support RGBW but the method name
|
||||||
// here needs to be unique, thus GetPixeColorRgbw
|
// here needs to be unique, thus GetPixeColorRgbw
|
||||||
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
|
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
|
||||||
@ -168,21 +239,6 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearTo(RgbColor color)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearTo(RgbwColor color)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelType _type;
|
NeoPixelType _type;
|
||||||
|
File diff suppressed because one or more lines are too long
@ -23,16 +23,19 @@
|
|||||||
<script>
|
<script>
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
var tmout = null;
|
||||||
function update()
|
function update()
|
||||||
{
|
{
|
||||||
if (document.hidden) {
|
if (document.hidden) {
|
||||||
setTimeout(update, 250);
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 250);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fetch('/json/live')
|
fetch('/json/live')
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
setTimeout(update, 2500);
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 2500);
|
||||||
}
|
}
|
||||||
return res.json();
|
return res.json();
|
||||||
})
|
})
|
||||||
@ -47,10 +50,12 @@
|
|||||||
}
|
}
|
||||||
str += ")";
|
str += ")";
|
||||||
document.getElementById("canv").style.background = str;
|
document.getElementById("canv").style.background = str;
|
||||||
setTimeout(update, 40);
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 40);
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
setTimeout(update, 2500);
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 2500);
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||||
<h3>About</h3>
|
<h3>About</h3>
|
||||||
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.4<br><br>
|
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.9.0<br><br>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||||
(c) 2016-2019 Christian Schwinne <br>
|
(c) 2016-2019 Christian Schwinne <br>
|
||||||
|
@ -103,6 +103,30 @@
|
|||||||
Device Auth token: <input name="BK" maxlength="33"><br>
|
Device Auth token: <input name="BK" maxlength="33"><br>
|
||||||
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
||||||
<h3>MQTT</h3>
|
<h3>MQTT</h3>
|
||||||
|
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||||
Broker: <input name="MS" maxlength="32"><br>
|
Broker: <input name="MS" maxlength="32"><br>
|
||||||
唉敳湲浡㩥㰠湩異⁴慮敭∽免呔单剅•慭汸湥瑧㵨㌢∲㰾牢ਾऀऀ慐獳潷摲›椼灮瑵琠灹㵥瀢獡睳牯≤椠灮瑵渠浡㵥䴢呑偔十≓洠硡敬杮桴∽㈳㸢戼㹲
|
Username: <input name="MQTTUSER" maxlength="32"><br>
|
||||||
䌉楬湥⁴䑉›椼灮瑵渠浡㵥䴢呑䍔䑉•慭汸湥瑧㵨㌢∲㰾牢ਾऀऀ䐀攀瘀椀挀攀 吀漀瀀椀挀㨀 㰀椀渀瀀甀琀 渀愀洀攀㴀∀䴀䐀∀ 洀愀砀氀攀渀最琀栀㴀∀㌀㈀∀㸀㰀戀爀㸀ഀऀऀ䜀爀漀甀瀀 吀漀瀀椀挀㨀 㰀椀渀瀀甀琀 渀愀洀攀㴀∀䴀䜀∀ 洀愀砀氀攀渀最琀栀㴀∀㌀㈀∀㸀㰀戀爀㸀ഀऀऀ㰀愀 栀爀攀昀㴀∀栀琀琀瀀猀㨀⼀⼀最椀琀栀甀戀⸀挀漀洀⼀䄀椀爀挀漀漀漀欀椀攀⼀圀䰀䔀䐀⼀眀椀欀椀⼀䴀儀吀吀∀ 琀愀爀最攀琀㴀∀开戀氀愀渀欀∀㸀䴀儀吀吀 椀渀昀漀㰀⼀愀㸀ഀऀऀ㰀栀㌀㸀倀栀椀氀椀瀀猀 䠀甀攀㰀⼀栀㌀㸀ഀऀऀ㰀椀㸀夀漀甀 挀愀渀 昀椀渀搀 琀栀攀 戀爀椀搀最攀 䤀倀 愀渀搀 琀栀攀 氀椀最栀琀 渀甀洀戀攀爀 椀渀 琀栀攀 ✀䄀戀漀甀琀✀ 猀攀挀琀椀漀渀 漀昀 琀栀攀 栀甀攀 愀瀀瀀⸀㰀⼀椀㸀㰀戀爀㸀ഀऀऀ倀漀氀氀 䠀甀攀 氀椀最栀琀 㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀䰀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀∀ 洀愀砀㴀∀㤀㤀∀ 爀攀焀甀椀爀攀搀㸀 攀瘀攀爀礀 㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀䤀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㘀㔀 ∀ 爀攀焀甀椀爀攀搀㸀 洀猀㨀 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀倀∀㸀㰀戀爀㸀ഀऀऀ吀栀攀渀Ⰰ 爀攀挀攀椀瘀攀 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀伀∀㸀 伀渀⼀伀昀昀Ⰰ 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀䈀∀㸀 䈀爀椀最栀琀渀攀猀猀Ⰰ 愀渀搀 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀䌀∀㸀 䌀漀氀漀爀㰀戀爀㸀ഀऀऀ䠀甀攀 䈀爀椀搀最攀 䤀倀㨀㰀戀爀㸀ഀऀऀ㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀 ∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㈀㔀㔀∀ 爀攀焀甀椀爀攀搀㸀 ⸀ഀऀऀ㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㈀㔀㔀∀ 爀攀焀甀椀爀攀搀㸀 ⸀ഀऀऀ㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀㈀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㈀㔀㔀∀ 爀攀焀甀椀爀攀搀㸀 ⸀ഀऀऀ㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀㌀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㈀㔀㔀∀ 爀攀焀甀椀爀攀搀㸀㰀戀爀㸀ഀऀऀ㰀戀㸀倀爀攀猀猀 琀栀攀 瀀甀猀栀氀椀渀欀 戀甀琀琀漀渀 漀渀 琀栀攀 戀爀椀搀最攀Ⰰ 愀昀琀攀爀 琀栀愀琀 猀愀瘀攀 琀栀椀猀 瀀愀最攀℀㰀⼀戀㸀㰀戀爀㸀ഀऀऀ⠀眀栀攀渀 昀椀爀猀琀 挀漀渀渀攀挀琀椀渀最⤀㰀戀爀㸀ഀऀऀ㰀℀ⴀⴀ唀瀀搀愀琀攀 䠀甀攀 最爀漀甀瀀 㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀唀䔀䜀刀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㤀㤀∀ 爀攀焀甀椀爀攀搀㸀 㰀戀爀㸀ഀऀऀ匀攀渀搀 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀唀䔀䤀伀∀㸀 伀渀⼀伀昀昀Ⰰ 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀唀䔀䈀刀∀㸀 䈀爀椀最栀琀渀攀猀猀Ⰰ 愀渀搀 㰀椀渀瀀甀琀 琀礀瀀攀㴀∀挀栀攀挀欀戀漀砀∀ 渀愀洀攀㴀∀䠀唀䔀䌀䰀∀㸀 䌀漀氀漀爀㰀戀爀㸀ⴀⴀ㸀ഀऀऀ㰀℀ⴀⴀ䄀昀琀攀爀 搀攀瘀椀挀攀 挀漀氀漀爀 甀瀀搀愀琀攀Ⰰ 椀最渀漀爀攀 䠀甀攀 甀瀀搀愀琀攀猀 昀漀爀 㰀椀渀瀀甀琀 渀愀洀攀㴀∀䠀唀䔀䰀䤀∀ 琀礀瀀攀㴀∀渀甀洀戀攀爀∀ 洀椀渀㴀∀ ∀ 洀愀砀㴀∀㈀㔀㔀∀ 爀攀焀甀椀爀攀搀㸀 洀椀渀甀琀攀猀㰀戀爀㸀ⴀⴀ㸀ഀऀऀ䠀甀攀 猀琀愀琀甀猀㨀 㰀猀瀀愀渀 挀氀愀猀猀㴀∀栀洀猀∀㸀 䤀渀琀攀爀渀愀氀 䔀匀倀 䔀爀爀漀爀℀ 㰀⼀猀瀀愀渀㸀㰀栀爀㸀ഀऀऀ㰀戀甀琀琀漀渀 琀礀瀀攀㴀∀戀甀琀琀漀渀∀ 漀渀挀氀椀挀欀㴀∀䈀⠀⤀∀㸀䈀愀挀欀㰀⼀戀甀琀琀漀渀㸀㰀戀甀琀琀漀渀 琀礀瀀攀㴀∀猀甀戀洀椀琀∀㸀匀愀瘀攀㰀⼀戀甀琀琀漀渀㸀ഀऀ㰀⼀昀漀爀洀㸀ഀ㰀⼀戀漀搀礀㸀ഀ㰀⼀栀琀洀氀㸀
|
Password: <input type="password" input name="MQTTPASS" maxlength="32"><br>
|
||||||
|
Client ID: <input name="MQTTCID" maxlength="32"><br>
|
||||||
|
Device Topic: <input name="MD" maxlength="32"><br>
|
||||||
|
Group Topic: <input name="MG" maxlength="32"><br>
|
||||||
|
<a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
||||||
|
<h3>Philips Hue</h3>
|
||||||
|
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||||
|
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
|
||||||
|
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||||
|
Hue Bridge IP:<br>
|
||||||
|
<input name="H0" type="number" min="0" max="255" required> .
|
||||||
|
<input name="H1" type="number" min="0" max="255" required> .
|
||||||
|
<input name="H2" type="number" min="0" max="255" required> .
|
||||||
|
<input name="H3" type="number" min="0" max="255" required><br>
|
||||||
|
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||||
|
(when first connecting)<br>
|
||||||
|
<!--Update Hue group <input name="HUEGR" type="number" min="0" max="99" required> <br>
|
||||||
|
Send <input type="checkbox" name="HUEIO"> On/Off, <input type="checkbox" name="HUEBR"> Brightness, and <input type="checkbox" name="HUECL"> Color<br>-->
|
||||||
|
<!--After device color update, ignore Hue updates for <input name="HUELI" type="number" min="0" max="255" required> minutes<br>-->
|
||||||
|
Hue status: <span class="hms"> Internal ESP Error! </span><hr>
|
||||||
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -98,7 +98,8 @@
|
|||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
<h2>Web Setup</h2>
|
<h2>Web Setup</h2>
|
||||||
Server description: <input name="DS" maxlength="32"><br><br>
|
Server description: <input name="DS" maxlength="32"><br>
|
||||||
|
Sync button toggles both send and receive: <input type="checkbox" name="ST"><br><br>
|
||||||
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
@ -20,7 +20,7 @@ const char PAGE_msg[] PROGMEM = R"=====(<!DOCTYPE html>
|
|||||||
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta content='width=device-width' name='viewport'><title>WLED Update</title><script>function B(){window.history.back()}</script>
|
<html><head><meta content='width=device-width' name='viewport'><title>WLED Update</title><script>function B(){window.history.back()}</script>
|
||||||
<style>.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%}</style></head>
|
<style>.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%}</style></head>
|
||||||
<body><h2>WLED Software Update</h2>Installed version: 0.9.0-dev<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>)=====";
|
<body><h2>WLED Software Update</h2>Installed version: 0.9.0-b1<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
//new user welcome page
|
//new user welcome page
|
||||||
@ -36,14 +36,50 @@ const char PAGE_liveview[] PROGMEM = R"=====(<!DOCTYPE html>
|
|||||||
<meta charset=utf-8>
|
<meta charset=utf-8>
|
||||||
<meta name=theme-color content=#222222>
|
<meta name=theme-color content=#222222>
|
||||||
<title>WLED Live Preview</title>
|
<title>WLED Live Preview</title>
|
||||||
<style>body{margin:0}#canv{background:black;filter:brightness(175%);width:100%;height:100%;position:absolute}</style>
|
<style>
|
||||||
</head>
|
body {margin: 0;}
|
||||||
<body><div id=canv />
|
#canv {background: black;filter: brightness(175%);width: 100%;height: 100%;position: absolute;}
|
||||||
<script>update();function update()
|
</style></head>
|
||||||
{if(document.hidden){setTimeout(update,250);return;}
|
<body>
|
||||||
fetch('/json/live').then(res=>{if(!res.ok){setTimeout(update,2500);}
|
<div id="canv" />
|
||||||
return res.json();}).then(json=>{var str="linear-gradient(90deg,";var len=json.leds.length;for(i=0;i<len;i++){var leddata=json.leds[i];if(leddata.length>6)leddata=leddata.substring(2);str+="#"+leddata;if(i<len-1)str+=","}
|
<script>
|
||||||
str+=")";document.getElementById("canv").style.background=str;setTimeout(update,40);}).catch(function(error){setTimeout(update,2500);})}</script>
|
update();
|
||||||
|
var tmout = null;
|
||||||
|
function update()
|
||||||
|
{
|
||||||
|
if (document.hidden) {
|
||||||
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 250);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetch('/json/live')
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 2500);
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
var str = "linear-gradient(90deg,";
|
||||||
|
var len = json.leds.length;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
var leddata = json.leds[i];
|
||||||
|
if (leddata.length > 6) leddata = leddata.substring(2);
|
||||||
|
str += "#" + leddata;
|
||||||
|
if (i < len -1) str += ","
|
||||||
|
}
|
||||||
|
str += ")";
|
||||||
|
document.getElementById("canv").style.background = str;
|
||||||
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 40);
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
clearTimeout(tmout);
|
||||||
|
tmout = setTimeout(update, 2500);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body></html>)=====";
|
</body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ Color order:
|
|||||||
<select name=CO>
|
<select name=CO>
|
||||||
<option value=0>GRB</option>
|
<option value=0>GRB</option>
|
||||||
<option value=1>RGB</option>
|
<option value=1>RGB</option>
|
||||||
<option value=2 disabled>BRG</option>
|
<option value=2>BRG</option>
|
||||||
<option value=3>RBG</option>
|
<option value=3>RBG</option>
|
||||||
</select>
|
</select>
|
||||||
<h3>Defaults</h3>
|
<h3>Defaults</h3>
|
||||||
@ -168,7 +168,8 @@ function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}fun
|
|||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
<h2>Web Setup</h2>
|
<h2>Web Setup</h2>
|
||||||
Server description: <input name="DS" maxlength="32"><br><br>
|
Server description: <input name="DS" maxlength="32"><br>
|
||||||
|
Sync button toggles both send and receive: <input type="checkbox" name="ST"><br><br>
|
||||||
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
@ -219,6 +220,7 @@ For best results, only use one of these services at a time.<br>
|
|||||||
Device Auth token: <input name="BK" maxlength="33"><br>
|
Device Auth token: <input name="BK" maxlength="33"><br>
|
||||||
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
||||||
<h3>MQTT</h3>
|
<h3>MQTT</h3>
|
||||||
|
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||||
Broker: <input name="MS" maxlength="32">
|
Broker: <input name="MS" maxlength="32">
|
||||||
Port: <input name="MQPORT" type="number" min="1" max="65535" required><br>
|
Port: <input name="MQPORT" type="number" min="1" max="65535" required><br>
|
||||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||||
@ -280,6 +282,7 @@ Time zone:
|
|||||||
<option value="12">NZST/NZDT</option>
|
<option value="12">NZST/NZDT</option>
|
||||||
<option value="13">North Korea</option>
|
<option value="13">North Korea</option>
|
||||||
<option value="14">IST (India)</option>
|
<option value="14">IST (India)</option>
|
||||||
|
<option value="15">CA-Saskatchewan</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||||
Current local time is <span class="times">unknown</span>.
|
Current local time is <span class="times">unknown</span>.
|
||||||
@ -288,7 +291,7 @@ Clock Overlay:
|
|||||||
<select name="OL" onchange="Cs()">
|
<select name="OL" onchange="Cs()">
|
||||||
<option value="0" id="cn" selected>None</option>
|
<option value="0" id="cn" selected>None</option>
|
||||||
<option value="1" id="ca">Analog Clock</option>
|
<option value="1" id="ca">Analog Clock</option>
|
||||||
<option value="2">Single Digit Clock</option>
|
<option value="2" disabled>-</option>
|
||||||
<option value="3" id="cc">Cronixie Clock</option>
|
<option value="3" id="cc">Cronixie Clock</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<div id="coc">
|
<div id="coc">
|
||||||
@ -366,10 +369,10 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
|
|||||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||||
<h3>About</h3>
|
<h3>About</h3>
|
||||||
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.9.0-dev<br><br>
|
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.9.0-b2<br><br>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||||
(c) 2016-2019 Christian Schwinne <br>
|
(c) 2016-2020 Christian Schwinne <br>
|
||||||
<i>Licensed under the MIT license</i><br><br>
|
<i>Licensed under the MIT license</i><br><br>
|
||||||
Server message: <span class="msg"> Response error! </span><hr>
|
Server message: <span class="msg"> Response error! </span><hr>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||||
|
2902
wled00/html_ui.h
2902
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -565,6 +565,14 @@ DEFINE_GRADIENT_PALETTE( Sakura_gp ) {
|
|||||||
195, 255, 82,103,
|
195, 255, 82,103,
|
||||||
255, 223, 13, 17};
|
255, 223, 13, 17};
|
||||||
|
|
||||||
|
DEFINE_GRADIENT_PALETTE( Aurora_gp ) {
|
||||||
|
0, 1, 5, 45, //deep blue
|
||||||
|
64, 0,200, 23,
|
||||||
|
128, 0,255, 0, //green
|
||||||
|
170, 0,243, 45,
|
||||||
|
200, 0,135, 7,
|
||||||
|
255, 1, 5, 45};//deep blue
|
||||||
|
|
||||||
|
|
||||||
// Single array of defined cpt-city color palettes.
|
// Single array of defined cpt-city color palettes.
|
||||||
// This will let us programmatically choose one based on
|
// This will let us programmatically choose one based on
|
||||||
@ -614,6 +622,7 @@ const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
|
|||||||
Orangery_gp, //47-34 Orangery
|
Orangery_gp, //47-34 Orangery
|
||||||
C9_gp, //48-35 C9
|
C9_gp, //48-35 C9
|
||||||
Sakura_gp, //49-36 Sakura
|
Sakura_gp, //49-36 Sakura
|
||||||
|
Aurora_gp, //50-37 Aurora
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,8 +110,8 @@ uint32_t EspalexaDevice::getKelvin()
|
|||||||
uint32_t EspalexaDevice::getRGB()
|
uint32_t EspalexaDevice::getRGB()
|
||||||
{
|
{
|
||||||
if (_rgb != 0) return _rgb; //color has not changed
|
if (_rgb != 0) return _rgb; //color has not changed
|
||||||
uint8_t rgb[3];
|
byte rgb[4]{0, 0, 0, 0};
|
||||||
float r, g, b;
|
float r, g, b, w;
|
||||||
|
|
||||||
if (_mode == EspalexaColorMode::none) return 0;
|
if (_mode == EspalexaColorMode::none) return 0;
|
||||||
|
|
||||||
@ -122,6 +122,15 @@ uint32_t EspalexaDevice::getRGB()
|
|||||||
float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100)
|
float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100)
|
||||||
float r, g, b;
|
float r, g, b;
|
||||||
|
|
||||||
|
// Cold white to warm white receiving from Alexa: _ct = 199, 234, 284, 350, 383 (from cold white to warm white)
|
||||||
|
switch (_ct) {
|
||||||
|
case 199: rgb[0]=255,rgb[1]=255,rgb[2]=255;rgb[3]=255;break;
|
||||||
|
case 234: rgb[0]=127,rgb[1]=127,rgb[2]=127;rgb[3]=255;break;
|
||||||
|
case 284: rgb[0]=0,rgb[1]=0,rgb[2]=0;rgb[3]=255;break;
|
||||||
|
case 350: rgb[0]=130,rgb[1]=90,rgb[2]=0;rgb[3]=255;break;
|
||||||
|
case 383: rgb[0]=255,rgb[1]=153,rgb[2]=0;rgb[3]=255;break;
|
||||||
|
default: {
|
||||||
|
|
||||||
if( temp <= 66 ){
|
if( temp <= 66 ){
|
||||||
r = 255;
|
r = 255;
|
||||||
g = temp;
|
g = temp;
|
||||||
@ -143,6 +152,9 @@ uint32_t EspalexaDevice::getRGB()
|
|||||||
rgb[0] = (byte)constrain(r,0.1,255.1);
|
rgb[0] = (byte)constrain(r,0.1,255.1);
|
||||||
rgb[1] = (byte)constrain(g,0.1,255.1);
|
rgb[1] = (byte)constrain(g,0.1,255.1);
|
||||||
rgb[2] = (byte)constrain(b,0.1,255.1);
|
rgb[2] = (byte)constrain(b,0.1,255.1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (_mode == EspalexaColorMode::hs)
|
} else if (_mode == EspalexaColorMode::hs)
|
||||||
{
|
{
|
||||||
float h = ((float)_hue)/65535.0;
|
float h = ((float)_hue)/65535.0;
|
||||||
@ -216,7 +228,7 @@ uint32_t EspalexaDevice::getRGB()
|
|||||||
rgb[1] = 255.0*g;
|
rgb[1] = 255.0*g;
|
||||||
rgb[2] = 255.0*b;
|
rgb[2] = 255.0*b;
|
||||||
}
|
}
|
||||||
_rgb = ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2]));
|
_rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); //white value is only >0 if Alexa did provide a CT value, RGB colors will not be touched.
|
||||||
return _rgb;
|
return _rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include "ArduinoJson-v6.h"
|
#include "ArduinoJson-v6.h"
|
||||||
#include <Print.h>
|
#include <Print.h>
|
||||||
|
|
||||||
#define DYNAMYC_JSON_DOCUMENT_SIZE 8192
|
#define DYNAMIC_JSON_DOCUMENT_SIZE 8192
|
||||||
|
|
||||||
constexpr const char* JSON_MIMETYPE = "application/json";
|
constexpr const char* JSON_MIMETYPE = "application/json";
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMYC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_contentType = JSON_MIMETYPE;
|
_contentType = JSON_MIMETYPE;
|
||||||
if(isArray)
|
if(isArray)
|
||||||
@ -90,7 +90,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<void(AsyncWebServerRequest *request, JsonObject json)> ArJsonRequestHandlerFunction;
|
typedef std::function<void(AsyncWebServerRequest *request)> ArJsonRequestHandlerFunction;
|
||||||
|
|
||||||
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
||||||
private:
|
private:
|
||||||
@ -103,7 +103,7 @@ protected:
|
|||||||
int _maxContentLength;
|
int _maxContentLength;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMYC_JSON_DOCUMENT_SIZE)
|
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE)
|
||||||
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
|
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
|
||||||
|
|
||||||
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
||||||
@ -127,15 +127,8 @@ public:
|
|||||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||||
if(_onRequest) {
|
if(_onRequest) {
|
||||||
if (request->_tempObject != NULL) {
|
if (request->_tempObject != NULL) {
|
||||||
|
_onRequest(request);
|
||||||
DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize);
|
return;
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
|
|
||||||
if(!error) {
|
|
||||||
JsonObject json = jsonBuffer.as<JsonObject>();
|
|
||||||
|
|
||||||
_onRequest(request, json);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* @title WLED project sketch
|
* @title WLED project sketch
|
||||||
* @version 0.9.0-dev
|
* @version 0.9.0-b2
|
||||||
* @author Christian Schwinne
|
* @author Christian Schwinne
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -14,15 +14,16 @@
|
|||||||
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
|
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
|
||||||
|
|
||||||
//You are required to disable over-the-air updates:
|
//You are required to disable over-the-air updates:
|
||||||
//#define WLED_DISABLE_OTA
|
//#define WLED_DISABLE_OTA //saves 14kb
|
||||||
|
|
||||||
//You need to choose some of these features to disable:
|
//You need to choose some of these features to disable:
|
||||||
//#define WLED_DISABLE_ALEXA
|
//#define WLED_DISABLE_ALEXA //saves 11kb
|
||||||
//#define WLED_DISABLE_BLYNK
|
//#define WLED_DISABLE_BLYNK //saves 6kb
|
||||||
//#define WLED_DISABLE_CRONIXIE
|
//#define WLED_DISABLE_CRONIXIE //saves 3kb
|
||||||
//#define WLED_DISABLE_HUESYNC
|
//#define WLED_DISABLE_HUESYNC //saves 4kb
|
||||||
//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01
|
//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 25kb (!)
|
||||||
#define WLED_ENABLE_ADALIGHT //only saves about 500b
|
#define WLED_ENABLE_MQTT //saves 12kb
|
||||||
|
#define WLED_ENABLE_ADALIGHT //saves 500b only
|
||||||
|
|
||||||
#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet
|
#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet
|
||||||
//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version
|
//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version
|
||||||
@ -31,7 +32,6 @@
|
|||||||
//to toggle usb serial debug (un)comment the following line
|
//to toggle usb serial debug (un)comment the following line
|
||||||
//#define WLED_DEBUG
|
//#define WLED_DEBUG
|
||||||
|
|
||||||
|
|
||||||
//library inclusions
|
//library inclusions
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -84,6 +84,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#undef WLED_USE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet
|
||||||
/*#ifndef WLED_DISABLE_INFRARED
|
/*#ifndef WLED_DISABLE_INFRARED
|
||||||
#include <IRremote.h>
|
#include <IRremote.h>
|
||||||
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
|
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
|
||||||
@ -97,8 +98,8 @@
|
|||||||
|
|
||||||
|
|
||||||
//version code in format yymmddb (b = daily build)
|
//version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 1912051
|
#define VERSION 2001051
|
||||||
char versionString[] = "0.9.0-dev";
|
char versionString[] = "0.9.0-b2";
|
||||||
|
|
||||||
|
|
||||||
//AP and OTA default passwords (for maximum change them!)
|
//AP and OTA default passwords (for maximum change them!)
|
||||||
@ -147,7 +148,6 @@ bool fadeTransition = true; //enable crossfading color transit
|
|||||||
bool enableSecTransition = true; //also enable transition for secondary color
|
bool enableSecTransition = true; //also enable transition for secondary color
|
||||||
uint16_t transitionDelay = 750; //default crossfade duration in ms
|
uint16_t transitionDelay = 750; //default crossfade duration in ms
|
||||||
|
|
||||||
//bool strip.reverseMode = false; //flip entire LED strip (reverses all effect directions) --> edit in WS2812FX.h
|
|
||||||
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
|
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
|
||||||
uint8_t spacing = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look)
|
uint8_t spacing = 0; //disables N LEDs between active nodes. (Useful for spacing out lights for more traditional christmas light look)
|
||||||
uint8_t group = 1; //Group LEDs into one logical LED
|
uint8_t group = 1; //Group LEDs into one logical LED
|
||||||
@ -156,6 +156,7 @@ byte briMultiplier = 100; //% of brightness to set (to limit
|
|||||||
|
|
||||||
//User Interface CONFIG
|
//User Interface CONFIG
|
||||||
char serverDescription[33] = "WLED"; //Name of module
|
char serverDescription[33] = "WLED"; //Name of module
|
||||||
|
bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise
|
||||||
|
|
||||||
|
|
||||||
//Sync CONFIG
|
//Sync CONFIG
|
||||||
@ -189,6 +190,7 @@ bool arlsForceMaxBri = false; //enable to force max brightness i
|
|||||||
uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol
|
uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol
|
||||||
bool e131Multicast = false;
|
bool e131Multicast = false;
|
||||||
|
|
||||||
|
bool mqttEnabled = false;
|
||||||
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
|
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
|
||||||
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
|
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
|
||||||
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
|
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
|
||||||
@ -329,11 +331,6 @@ byte overlayCurrent = overlayDefault;
|
|||||||
byte overlaySpeed = 200;
|
byte overlaySpeed = 200;
|
||||||
unsigned long overlayRefreshMs = 200;
|
unsigned long overlayRefreshMs = 200;
|
||||||
unsigned long overlayRefreshedTime;
|
unsigned long overlayRefreshedTime;
|
||||||
int overlayArr[6];
|
|
||||||
uint16_t overlayDur[6];
|
|
||||||
uint16_t overlayPauseDur[6];
|
|
||||||
int nixieClockI = -1;
|
|
||||||
bool nixiePause = false;
|
|
||||||
|
|
||||||
//cronixie
|
//cronixie
|
||||||
byte dP[]{0,0,0,0,0,0};
|
byte dP[]{0,0,0,0,0,0};
|
||||||
@ -428,6 +425,7 @@ AsyncMqttClient* mqtt = NULL;
|
|||||||
void colorFromUint32(uint32_t,bool=false);
|
void colorFromUint32(uint32_t,bool=false);
|
||||||
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);
|
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);
|
||||||
void handleE131Packet(e131_packet_t*, IPAddress);
|
void handleE131Packet(e131_packet_t*, IPAddress);
|
||||||
|
void handleOverlayDraw();
|
||||||
|
|
||||||
#define E131_MAX_UNIVERSE_COUNT 9
|
#define E131_MAX_UNIVERSE_COUNT 9
|
||||||
|
|
||||||
@ -483,7 +481,7 @@ void reset()
|
|||||||
|
|
||||||
|
|
||||||
//append new c string to temp buffer efficiently
|
//append new c string to temp buffer efficiently
|
||||||
bool oappend(char* txt)
|
bool oappend(const char* txt)
|
||||||
{
|
{
|
||||||
uint16_t len = strlen(txt);
|
uint16_t len = strlen(txt);
|
||||||
if (olen + len >= OMAX) return false; //buffer full
|
if (olen + len >= OMAX) return false; //buffer full
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#define EEPSIZE 2560
|
#define EEPSIZE 2560
|
||||||
|
|
||||||
//eeprom Version code, enables default settings instead of 0 init on update
|
//eeprom Version code, enables default settings instead of 0 init on update
|
||||||
#define EEPVER 13
|
#define EEPVER 14
|
||||||
//0 -> old version, default
|
//0 -> old version, default
|
||||||
//1 -> 0.4p 1711272 and up
|
//1 -> 0.4p 1711272 and up
|
||||||
//2 -> 0.4p 1711302 and up
|
//2 -> 0.4p 1711302 and up
|
||||||
@ -20,7 +20,8 @@
|
|||||||
//10-> 0.8.2
|
//10-> 0.8.2
|
||||||
//11-> 0.8.5-dev #mqttauth @TimothyBrown
|
//11-> 0.8.5-dev #mqttauth @TimothyBrown
|
||||||
//12-> 0.8.7-dev
|
//12-> 0.8.7-dev
|
||||||
//13-> 0.9.0
|
//13-> 0.9.0-dev
|
||||||
|
//14-> 0.9.0-b1
|
||||||
|
|
||||||
void commit()
|
void commit()
|
||||||
{
|
{
|
||||||
@ -152,7 +153,7 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
|
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
|
||||||
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
||||||
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
||||||
//397 was initLedsLast
|
EEPROM.write(397, syncToggleReceive);
|
||||||
EEPROM.write(398, (ledCount >> 8) & 0xFF);
|
EEPROM.write(398, (ledCount >> 8) & 0xFF);
|
||||||
EEPROM.write(399, !enableSecTransition);
|
EEPROM.write(399, !enableSecTransition);
|
||||||
|
|
||||||
@ -242,6 +243,7 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(2290 + i, timerMacro[i] );
|
EEPROM.write(2290 + i, timerMacro[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EEPROM.write(2299, mqttEnabled);
|
||||||
writeStringToEEPROM(2300, mqttServer, 32);
|
writeStringToEEPROM(2300, mqttServer, 32);
|
||||||
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
|
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
|
||||||
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
||||||
@ -463,6 +465,14 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
{
|
{
|
||||||
readStringFromEEPROM(990, ntpServerName, 32);
|
readStringFromEEPROM(990, ntpServerName, 32);
|
||||||
}
|
}
|
||||||
|
if (lastEEPROMversion > 13)
|
||||||
|
{
|
||||||
|
mqttEnabled = EEPROM.read(2299);
|
||||||
|
syncToggleReceive = EEPROM.read(397);
|
||||||
|
} else {
|
||||||
|
mqttEnabled = true;
|
||||||
|
syncToggleReceive = false;
|
||||||
|
}
|
||||||
|
|
||||||
receiveDirect = !EEPROM.read(2200);
|
receiveDirect = !EEPROM.read(2200);
|
||||||
notifyMacro = EEPROM.read(2201);
|
notifyMacro = EEPROM.read(2201);
|
||||||
@ -497,6 +507,7 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
//1024-2047 reserved
|
//1024-2047 reserved
|
||||||
|
|
||||||
readStringFromEEPROM(2220, blynkApiKey, 35);
|
readStringFromEEPROM(2220, blynkApiKey, 35);
|
||||||
|
if (strlen(blynkApiKey) < 25) blynkApiKey[0] = 0;
|
||||||
|
|
||||||
//user MOD memory
|
//user MOD memory
|
||||||
//2944 - 3071 reserved
|
//2944 - 3071 reserved
|
||||||
@ -552,6 +563,7 @@ bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool load
|
|||||||
col[j] = EEPROM.read(i+j+2);
|
col[j] = EEPROM.read(i+j+2);
|
||||||
colSec[j] = EEPROM.read(i+j+6);
|
colSec[j] = EEPROM.read(i+j+6);
|
||||||
}
|
}
|
||||||
|
strip.setColor(2, EEPROM.read(i+12), EEPROM.read(i+13), EEPROM.read(i+14), EEPROM.read(i+15)); //tertiary color
|
||||||
}
|
}
|
||||||
if (loadFX)
|
if (loadFX)
|
||||||
{
|
{
|
||||||
@ -590,6 +602,12 @@ void savePreset(byte index)
|
|||||||
EEPROM.write(i+10, effectCurrent);
|
EEPROM.write(i+10, effectCurrent);
|
||||||
EEPROM.write(i+11, effectSpeed);
|
EEPROM.write(i+11, effectSpeed);
|
||||||
|
|
||||||
|
uint32_t colTer = strip.getSegment(strip.getMainSegmentId()).colors[2];
|
||||||
|
EEPROM.write(i+12, (colTer >> 16) & 0xFF);
|
||||||
|
EEPROM.write(i+13, (colTer >> 8) & 0xFF);
|
||||||
|
EEPROM.write(i+14, (colTer >> 0) & 0xFF);
|
||||||
|
EEPROM.write(i+15, (colTer >> 24) & 0xFF);
|
||||||
|
|
||||||
EEPROM.write(i+16, effectIntensity);
|
EEPROM.write(i+16, effectIntensity);
|
||||||
EEPROM.write(i+17, effectPalette);
|
EEPROM.write(i+17, effectPalette);
|
||||||
} else { //segment 16 can save segments
|
} else { //segment 16 can save segments
|
||||||
|
@ -82,7 +82,7 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//append a numeric setting to string buffer
|
//append a numeric setting to string buffer
|
||||||
void sappend(char stype, char* key, int val)
|
void sappend(char stype, const char* key, int val)
|
||||||
{
|
{
|
||||||
char ds[] = "d.Sf.";
|
char ds[] = "d.Sf.";
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ void sappend(char stype, char* key, int val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//append a string setting to buffer
|
//append a string setting to buffer
|
||||||
void sappends(char stype, char* key, char* val)
|
void sappends(char stype, const char* key, char* val)
|
||||||
{
|
{
|
||||||
switch(stype)
|
switch(stype)
|
||||||
{
|
{
|
||||||
@ -244,6 +244,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
if (subPage == 3)
|
if (subPage == 3)
|
||||||
{
|
{
|
||||||
sappends('s',"DS",serverDescription);
|
sappends('s',"DS",serverDescription);
|
||||||
|
sappend('c',"ST",syncToggleReceive);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 4)
|
if (subPage == 4)
|
||||||
@ -270,6 +271,9 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappends('s',"AI",alexaInvocationName);
|
sappends('s',"AI",alexaInvocationName);
|
||||||
sappend('c',"SA",notifyAlexa);
|
sappend('c',"SA",notifyAlexa);
|
||||||
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
|
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_MQTT
|
||||||
|
sappend('c',"MQ",mqttEnabled);
|
||||||
sappends('s',"MS",mqttServer);
|
sappends('s',"MS",mqttServer);
|
||||||
sappend('v',"MQPORT",mqttPort);
|
sappend('v',"MQPORT",mqttPort);
|
||||||
sappends('s',"MQUSER",mqttUser);
|
sappends('s',"MQUSER",mqttUser);
|
||||||
@ -282,6 +286,11 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappends('s',"MQCID",mqttClientID);
|
sappends('s',"MQCID",mqttClientID);
|
||||||
sappends('s',"MD",mqttDeviceTopic);
|
sappends('s',"MD",mqttDeviceTopic);
|
||||||
sappends('s',"MG",mqttGroupTopic);
|
sappends('s',"MG",mqttGroupTopic);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLED_DISABLE_HUESYNC
|
||||||
|
sappends('m',"(\"hms\")[0]","Unsupported in build");
|
||||||
|
#else
|
||||||
sappend('v',"H0",hueIP[0]);
|
sappend('v',"H0",hueIP[0]);
|
||||||
sappend('v',"H1",hueIP[1]);
|
sappend('v',"H1",hueIP[1]);
|
||||||
sappend('v',"H2",hueIP[2]);
|
sappend('v',"H2",hueIP[2]);
|
||||||
@ -293,6 +302,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',"HB",hueApplyBri);
|
sappend('c',"HB",hueApplyBri);
|
||||||
sappend('c',"HC",hueApplyColor);
|
sappend('c',"HC",hueApplyColor);
|
||||||
sappends('m',"(\"hms\")[0]",hueError);
|
sappends('m',"(\"hms\")[0]",hueError);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 5)
|
if (subPage == 5)
|
||||||
|
@ -14,6 +14,16 @@ void _setRandomColor(bool _sec,bool fromButton=false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isAsterisksOnly(const char* str, byte maxLen)
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < maxLen; i++) {
|
||||||
|
if (str[i] == 0) break;
|
||||||
|
if (str[i] != '*') return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//called upon POST settings form submit
|
//called upon POST settings form submit
|
||||||
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
{
|
{
|
||||||
@ -24,7 +34,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (subPage == 1)
|
if (subPage == 1)
|
||||||
{
|
{
|
||||||
strlcpy(clientSSID,request->arg("CS").c_str(), 33);
|
strlcpy(clientSSID,request->arg("CS").c_str(), 33);
|
||||||
if (request->arg("CP").charAt(0) != '*') strlcpy(clientPass, request->arg("CP").c_str(), 65);
|
|
||||||
|
if (!isAsterisksOnly(request->arg("CP").c_str(), 65)) strlcpy(clientPass, request->arg("CP").c_str(), 65);
|
||||||
|
|
||||||
strlcpy(cmDNS, request->arg("CM").c_str(), 33);
|
strlcpy(cmDNS, request->arg("CM").c_str(), 33);
|
||||||
|
|
||||||
@ -32,7 +43,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
strlcpy(apSSID, request->arg("AS").c_str(), 33);
|
strlcpy(apSSID, request->arg("AS").c_str(), 33);
|
||||||
apHide = request->hasArg("AH");
|
apHide = request->hasArg("AH");
|
||||||
int passlen = request->arg("AP").length();
|
int passlen = request->arg("AP").length();
|
||||||
if (passlen == 0 || (passlen > 7 && request->arg("AP").charAt(0) != '*')) strlcpy(apPass, request->arg("AP").c_str(), 65);
|
if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg("AP").c_str(), 65))) strlcpy(apPass, request->arg("AP").c_str(), 65);
|
||||||
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
||||||
|
|
||||||
char k[3]; k[2] = 0;
|
char k[3]; k[2] = 0;
|
||||||
@ -103,6 +114,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (subPage == 3)
|
if (subPage == 3)
|
||||||
{
|
{
|
||||||
strlcpy(serverDescription, request->arg("DS").c_str(), 33);
|
strlcpy(serverDescription, request->arg("DS").c_str(), 33);
|
||||||
|
syncToggleReceive = request->hasArg("ST");
|
||||||
}
|
}
|
||||||
|
|
||||||
//SYNC
|
//SYNC
|
||||||
@ -142,15 +154,19 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
strlcpy(blynkApiKey, request->arg("BK").c_str(), 36); initBlynk(blynkApiKey);
|
strlcpy(blynkApiKey, request->arg("BK").c_str(), 36); initBlynk(blynkApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_MQTT
|
||||||
|
mqttEnabled = request->hasArg("MQ");
|
||||||
strlcpy(mqttServer, request->arg("MS").c_str(), 33);
|
strlcpy(mqttServer, request->arg("MS").c_str(), 33);
|
||||||
t = request->arg("MQPORT").toInt();
|
t = request->arg("MQPORT").toInt();
|
||||||
if (t > 0) mqttPort = t;
|
if (t > 0) mqttPort = t;
|
||||||
strlcpy(mqttUser, request->arg("MQUSER").c_str(), 41);
|
strlcpy(mqttUser, request->arg("MQUSER").c_str(), 41);
|
||||||
if (request->arg("MQPASS").charAt(0) != '*') strlcpy(mqttPass, request->arg("MQPASS").c_str(), 41);
|
if (!isAsterisksOnly(request->arg("MQPASS").c_str(), 41)) strlcpy(mqttPass, request->arg("MQPASS").c_str(), 41);
|
||||||
strlcpy(mqttClientID, request->arg("MQCID").c_str(), 41);
|
strlcpy(mqttClientID, request->arg("MQCID").c_str(), 41);
|
||||||
strlcpy(mqttDeviceTopic, request->arg("MD").c_str(), 33);
|
strlcpy(mqttDeviceTopic, request->arg("MD").c_str(), 33);
|
||||||
strlcpy(mqttGroupTopic, request->arg("MG").c_str(), 33);
|
strlcpy(mqttGroupTopic, request->arg("MG").c_str(), 33);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_HUESYNC
|
||||||
for (int i=0;i<4;i++){
|
for (int i=0;i<4;i++){
|
||||||
String a = "H"+String(i);
|
String a = "H"+String(i);
|
||||||
hueIP[i] = request->arg(a).toInt();
|
hueIP[i] = request->arg(a).toInt();
|
||||||
@ -168,6 +184,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
huePollingEnabled = request->hasArg("HP");
|
huePollingEnabled = request->hasArg("HP");
|
||||||
hueStoreAllowed = true;
|
hueStoreAllowed = true;
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//TIME
|
//TIME
|
||||||
@ -184,7 +201,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
|
|
||||||
if (request->hasArg("OL")){
|
if (request->hasArg("OL")){
|
||||||
overlayDefault = request->arg("OL").toInt();
|
overlayDefault = request->arg("OL").toInt();
|
||||||
if (overlayCurrent != overlayDefault) strip.unlockAll();
|
|
||||||
overlayCurrent = overlayDefault;
|
overlayCurrent = overlayDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,29 +459,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
pos = req.indexOf("OL=");
|
pos = req.indexOf("OL=");
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
overlayCurrent = getNumVal(&req, pos);
|
overlayCurrent = getNumVal(&req, pos);
|
||||||
strip.unlockAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
//(un)lock pixel (ranges)
|
|
||||||
pos = req.indexOf("&L=");
|
|
||||||
if (pos > 0) {
|
|
||||||
uint16_t index = getNumVal(&req, pos);
|
|
||||||
pos = req.indexOf("L2=");
|
|
||||||
bool unlock = req.indexOf("UL") > 0;
|
|
||||||
if (pos > 0) {
|
|
||||||
uint16_t index2 = getNumVal(&req, pos);
|
|
||||||
if (unlock) {
|
|
||||||
strip.unlockRange(index, index2);
|
|
||||||
} else {
|
|
||||||
strip.lockRange(index, index2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (unlock) {
|
|
||||||
strip.unlock(index);
|
|
||||||
} else {
|
|
||||||
strip.lock(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//apply macro
|
//apply macro
|
||||||
@ -606,6 +599,10 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
|
|
||||||
//cronixie
|
//cronixie
|
||||||
#ifndef WLED_DISABLE_CRONIXIE
|
#ifndef WLED_DISABLE_CRONIXIE
|
||||||
|
//mode, 1 countdown
|
||||||
|
pos = req.indexOf("NM=");
|
||||||
|
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
|
||||||
|
|
||||||
pos = req.indexOf("NX="); //sets digits to code
|
pos = req.indexOf("NX="); //sets digits to code
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6);
|
strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6);
|
||||||
@ -620,9 +617,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
overlayRefreshedTime = 0;
|
overlayRefreshedTime = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//mode, 1 countdown
|
|
||||||
pos = req.indexOf("NM=");
|
|
||||||
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
|
|
||||||
|
|
||||||
pos = req.indexOf("U0="); //user var 0
|
pos = req.indexOf("U0="); //user var 0
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
|
@ -97,6 +97,7 @@ void wledInit()
|
|||||||
void beginStrip()
|
void beginStrip()
|
||||||
{
|
{
|
||||||
// Initialize NeoPixel Strip and button
|
// Initialize NeoPixel Strip and button
|
||||||
|
strip.setShowCallback(handleOverlayDraw);
|
||||||
|
|
||||||
#ifdef BTNPIN
|
#ifdef BTNPIN
|
||||||
pinMode(BTNPIN, INPUT_PULLUP);
|
pinMode(BTNPIN, INPUT_PULLUP);
|
||||||
@ -141,7 +142,10 @@ void initAP(bool resetAP=false){
|
|||||||
if (udpPort > 0 && udpPort != ntpLocalPort)
|
if (udpPort > 0 && udpPort != ntpLocalPort)
|
||||||
{
|
{
|
||||||
udpConnected = notifierUdp.begin(udpPort);
|
udpConnected = notifierUdp.begin(udpPort);
|
||||||
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
}
|
||||||
|
if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort)
|
||||||
|
{
|
||||||
|
udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||||
@ -232,7 +236,7 @@ void initInterfaces() {
|
|||||||
if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||||
|
|
||||||
initBlynk(blynkApiKey);
|
initBlynk(blynkApiKey);
|
||||||
Serial.println(e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT));
|
e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT);
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
initMqtt();
|
initMqtt();
|
||||||
interfacesInited = true;
|
interfacesInited = true;
|
||||||
@ -240,12 +244,26 @@ void initInterfaces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte stacO = 0;
|
byte stacO = 0;
|
||||||
|
uint32_t lastHeap;
|
||||||
|
unsigned long heapTime = 0;
|
||||||
|
|
||||||
void handleConnection() {
|
void handleConnection() {
|
||||||
//TODO: reconnect if heap <8000
|
|
||||||
if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return;
|
if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return;
|
||||||
if (lastReconnectAttempt == 0) initConnection();
|
if (lastReconnectAttempt == 0) initConnection();
|
||||||
|
|
||||||
|
//reconnect WiFi to clear stale allocations if heap gets too low
|
||||||
|
if (millis() - heapTime > 5000)
|
||||||
|
{
|
||||||
|
uint32_t heap = ESP.getFreeHeap();
|
||||||
|
if (heap < 9000 && lastHeap < 9000) {
|
||||||
|
DEBUG_PRINT("Heap too low! ");
|
||||||
|
DEBUG_PRINTLN(heap);
|
||||||
|
forceReconnect = true;
|
||||||
|
}
|
||||||
|
lastHeap = heap;
|
||||||
|
heapTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
byte stac = 0;
|
byte stac = 0;
|
||||||
if (apActive) {
|
if (apActive) {
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
|
@ -38,7 +38,7 @@ void notify(byte callMode, bool followUp=false)
|
|||||||
//0: old 1: supports white 2: supports secondary color
|
//0: old 1: supports white 2: supports secondary color
|
||||||
//3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
//3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
||||||
//6: supports timebase syncing, 29 byte packet 7: supports tertiary color
|
//6: supports timebase syncing, 29 byte packet 7: supports tertiary color
|
||||||
udpOut[11] = 6;
|
udpOut[11] = 7;
|
||||||
udpOut[12] = colSec[0];
|
udpOut[12] = colSec[0];
|
||||||
udpOut[13] = colSec[1];
|
udpOut[13] = colSec[1];
|
||||||
udpOut[14] = colSec[2];
|
udpOut[14] = colSec[2];
|
||||||
@ -47,10 +47,12 @@ void notify(byte callMode, bool followUp=false)
|
|||||||
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
||||||
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
||||||
udpOut[19] = effectPalette;
|
udpOut[19] = effectPalette;
|
||||||
/*udpOut[20] = colTer[0];
|
uint32_t colTer = strip.getSegment(strip.getMainSegmentId()).colors[2];
|
||||||
udpOut[21] = colTer[1];
|
udpOut[20] = (colTer >> 16) & 0xFF;
|
||||||
udpOut[22] = colTer[2];
|
udpOut[21] = (colTer >> 8) & 0xFF;
|
||||||
udpOut[23] = colTer[3];*/
|
udpOut[22] = (colTer >> 0) & 0xFF;
|
||||||
|
udpOut[23] = (colTer >> 24) & 0xFF;
|
||||||
|
|
||||||
udpOut[24] = followUp;
|
udpOut[24] = followUp;
|
||||||
uint32_t t = millis() + strip.timebase;
|
uint32_t t = millis() + strip.timebase;
|
||||||
udpOut[25] = (t >> 24) & 0xFF;
|
udpOut[25] = (t >> 24) & 0xFF;
|
||||||
@ -77,7 +79,6 @@ void arlsLock(uint32_t timeoutMs)
|
|||||||
{
|
{
|
||||||
strip.setPixelColor(i,0,0,0,0);
|
strip.setPixelColor(i,0,0,0,0);
|
||||||
}
|
}
|
||||||
strip.unlockAll();
|
|
||||||
realtimeActive = true;
|
realtimeActive = true;
|
||||||
}
|
}
|
||||||
realtimeTimeout = millis() + timeoutMs;
|
realtimeTimeout = millis() + timeoutMs;
|
||||||
@ -120,13 +121,11 @@ void handleNotifications()
|
|||||||
{
|
{
|
||||||
e131NewData = false;
|
e131NewData = false;
|
||||||
strip.show();
|
strip.show();
|
||||||
Serial.println("Show");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//unlock strip when realtime UDP times out
|
//unlock strip when realtime UDP times out
|
||||||
if (realtimeActive && millis() > realtimeTimeout)
|
if (realtimeActive && millis() > realtimeTimeout)
|
||||||
{
|
{
|
||||||
//strip.unlockAll();
|
|
||||||
strip.setBrightness(bri);
|
strip.setBrightness(bri);
|
||||||
realtimeActive = false;
|
realtimeActive = false;
|
||||||
//strip.setMode(effectCurrent);
|
//strip.setMode(effectCurrent);
|
||||||
@ -180,7 +179,7 @@ void handleNotifications()
|
|||||||
col[0] = udpIn[3];
|
col[0] = udpIn[3];
|
||||||
col[1] = udpIn[4];
|
col[1] = udpIn[4];
|
||||||
col[2] = udpIn[5];
|
col[2] = udpIn[5];
|
||||||
if (udpIn[11] > 0) //check if sending modules white val is inteded
|
if (udpIn[11] > 0) //sending module's white val is intended
|
||||||
{
|
{
|
||||||
col[3] = udpIn[10];
|
col[3] = udpIn[10];
|
||||||
if (udpIn[11] > 1)
|
if (udpIn[11] > 1)
|
||||||
@ -193,17 +192,14 @@ void handleNotifications()
|
|||||||
if (udpIn[11] > 5)
|
if (udpIn[11] > 5)
|
||||||
{
|
{
|
||||||
uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]);
|
uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]);
|
||||||
t -= 2;
|
t += 2;
|
||||||
t -= millis();
|
t -= millis();
|
||||||
strip.timebase = t;
|
strip.timebase = t;
|
||||||
}
|
}
|
||||||
/*if (udpIn[11] > 6)
|
if (udpIn[11] > 6)
|
||||||
{
|
{
|
||||||
colTer[0] = udpIn[20];
|
strip.setColor(2, udpIn[20], udpIn[21], udpIn[22], udpIn[23]); //tertiary color
|
||||||
colTer[1] = udpIn[21];
|
}
|
||||||
colTer[2] = udpIn[22];
|
|
||||||
colSec[3] = udpIn[23];
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,13 @@ void setValuesFromMainSeg()
|
|||||||
effectPalette = seg.palette;
|
effectPalette = seg.palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void resetTimebase()
|
||||||
|
{
|
||||||
|
strip.timebase = 0 - millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void toggleOnOff()
|
void toggleOnOff()
|
||||||
{
|
{
|
||||||
if (bri == 0)
|
if (bri == 0)
|
||||||
@ -81,7 +88,7 @@ void colorUpdated(int callMode)
|
|||||||
{
|
{
|
||||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
||||||
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
||||||
if (callMode != 1 && callMode != 5) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments
|
if (callMode != 0 && callMode != 1 && callMode != 5) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments
|
||||||
|
|
||||||
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
|
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
|
||||||
if (!colorChanged())
|
if (!colorChanged())
|
||||||
@ -113,6 +120,7 @@ void colorUpdated(int callMode)
|
|||||||
colIT[i] = col[i];
|
colIT[i] = col[i];
|
||||||
colSecIT[i] = colSec[i];
|
colSecIT[i] = colSec[i];
|
||||||
}
|
}
|
||||||
|
if (briT == 0 && callMode != 3) resetTimebase();
|
||||||
briIT = bri;
|
briIT = bri;
|
||||||
if (bri > 0) briLast = bri;
|
if (bri > 0) briLast = bri;
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ TimeChangeRule CDT = {Second, Sun, Mar, 2, -300 }; //Daylight time = UTC - 5
|
|||||||
TimeChangeRule CST = {First, Sun, Nov, 2, -360 }; //Standard time = UTC - 6 hours
|
TimeChangeRule CST = {First, Sun, Nov, 2, -360 }; //Standard time = UTC - 6 hours
|
||||||
Timezone tzUSCentral(CDT, CST);
|
Timezone tzUSCentral(CDT, CST);
|
||||||
|
|
||||||
|
Timezone tzCASaskatchewan(CST, CST); //Central without DST
|
||||||
|
|
||||||
TimeChangeRule MDT = {Second, Sun, Mar, 2, -360 }; //Daylight time = UTC - 6 hours
|
TimeChangeRule MDT = {Second, Sun, Mar, 2, -360 }; //Daylight time = UTC - 6 hours
|
||||||
TimeChangeRule MST = {First, Sun, Nov, 2, -420 }; //Standard time = UTC - 7 hours
|
TimeChangeRule MST = {First, Sun, Nov, 2, -420 }; //Standard time = UTC - 7 hours
|
||||||
Timezone tzUSMountain(MDT, MST);
|
Timezone tzUSMountain(MDT, MST);
|
||||||
@ -55,7 +57,7 @@ Timezone tzNK(NKST, NKST);
|
|||||||
TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours
|
TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours
|
||||||
Timezone tzIndia(IST, IST);
|
Timezone tzIndia(IST, IST);
|
||||||
|
|
||||||
Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia};
|
Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan};
|
||||||
|
|
||||||
void handleNetworkTime()
|
void handleNetworkTime()
|
||||||
{
|
{
|
||||||
@ -161,13 +163,16 @@ void setCountdown()
|
|||||||
//returns true if countdown just over
|
//returns true if countdown just over
|
||||||
bool checkCountdown()
|
bool checkCountdown()
|
||||||
{
|
{
|
||||||
long diff = countdownTime - now();
|
unsigned long n = now();
|
||||||
local = abs(diff);
|
local = countdownTime - n;
|
||||||
if (diff <0 && !countdownOverTriggered)
|
if (n > countdownTime) {
|
||||||
{
|
local = n - countdownTime;
|
||||||
if (macroCountdown != 0) applyMacro(macroCountdown);
|
if (!countdownOverTriggered)
|
||||||
countdownOverTriggered = true;
|
{
|
||||||
return true;
|
if (macroCountdown != 0) applyMacro(macroCountdown);
|
||||||
|
countdownOverTriggered = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Used to draw clock overlays over the strip
|
* Used to draw clock overlays over the strip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void initCronixie()
|
void initCronixie()
|
||||||
{
|
{
|
||||||
if (overlayCurrent == 3 && !cronixieInit)
|
if (overlayCurrent == 3 && !cronixieInit)
|
||||||
@ -17,107 +18,6 @@ void initCronixie()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _nixieDisplay(int num[], uint16_t dur[], uint16_t pausedur[], byte cnt)
|
|
||||||
{
|
|
||||||
strip.setRange(overlayMin, overlayMax, 0);
|
|
||||||
if (num[nixieClockI] >= 0 && !nixiePause)
|
|
||||||
{
|
|
||||||
strip.setIndividual(num[nixieClockI],((uint32_t)colT[3] << 24)| ((uint32_t)colT[0] << 16) | ((uint32_t)colT[1] << 8) | colT[2]);
|
|
||||||
strip.unlock(num[nixieClockI]);
|
|
||||||
}
|
|
||||||
if (!nixiePause)
|
|
||||||
{
|
|
||||||
overlayRefreshMs = dur[nixieClockI];
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayRefreshMs = pausedur[nixieClockI];
|
|
||||||
}
|
|
||||||
if (pausedur[nixieClockI] > 0 && !nixiePause)
|
|
||||||
{
|
|
||||||
nixiePause = true;
|
|
||||||
} else {
|
|
||||||
if (nixieClockI < cnt -1)
|
|
||||||
{
|
|
||||||
nixieClockI++;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
nixieClockI = -1;
|
|
||||||
}
|
|
||||||
nixiePause = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _nixieNumber(int number, int dur)
|
|
||||||
{
|
|
||||||
if (nixieClockI < 0)
|
|
||||||
{
|
|
||||||
DEBUG_PRINT(number);
|
|
||||||
int digitCnt = -1;
|
|
||||||
int digits[4];
|
|
||||||
digits[3] = number/1000;
|
|
||||||
digits[2] = (number/100)%10;
|
|
||||||
digits[1] = (number/10)%10;
|
|
||||||
digits[0] = number%10;
|
|
||||||
if (number > 999) //four digits
|
|
||||||
{
|
|
||||||
digitCnt = 4;
|
|
||||||
} else if (number > 99) //three digits
|
|
||||||
{
|
|
||||||
digitCnt = 3;
|
|
||||||
} else if (number > 9) //two digits
|
|
||||||
{
|
|
||||||
digitCnt = 2;
|
|
||||||
} else { //single digit
|
|
||||||
digitCnt = 1;
|
|
||||||
}
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
for (int i = 0; i < digitCnt; i++)
|
|
||||||
{
|
|
||||||
DEBUG_PRINT(digits[i]);
|
|
||||||
overlayArr[digitCnt-1-i] = digits[i];
|
|
||||||
overlayDur[digitCnt-1-i] = ((dur/4)*3)/digitCnt;
|
|
||||||
overlayPauseDur[digitCnt-1-i] = 0;
|
|
||||||
}
|
|
||||||
DEBUG_PRINTLN(" ");
|
|
||||||
for (int i = 1; i < digitCnt; i++)
|
|
||||||
{
|
|
||||||
if (overlayArr[i] == overlayArr[i-1])
|
|
||||||
{
|
|
||||||
overlayPauseDur[i-1] = dur/12;
|
|
||||||
overlayDur[i-1] = overlayDur[i-1]-dur/12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = digitCnt; i < 6; i++)
|
|
||||||
{
|
|
||||||
overlayArr[i] = -1;
|
|
||||||
overlayDur[i] = 0;
|
|
||||||
overlayPauseDur[i] = 0;
|
|
||||||
}
|
|
||||||
overlayPauseDur[5] = dur/4;
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
if (overlayArr[i] != -1)
|
|
||||||
{
|
|
||||||
overlayArr[i] = overlayArr[i] + overlayMin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i <6; i++)
|
|
||||||
{
|
|
||||||
DEBUG_PRINT(overlayArr[i]);
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
DEBUG_PRINT(overlayDur[i]);
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
DEBUG_PRINT(overlayPauseDur[i]);
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
}
|
|
||||||
DEBUG_PRINTLN(" ");
|
|
||||||
nixieClockI = 0;
|
|
||||||
} else {
|
|
||||||
_nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void handleOverlays()
|
void handleOverlays()
|
||||||
{
|
{
|
||||||
if (millis() - overlayRefreshedTime > overlayRefreshMs)
|
if (millis() - overlayRefreshedTime > overlayRefreshMs)
|
||||||
@ -125,22 +25,16 @@ void handleOverlays()
|
|||||||
initCronixie();
|
initCronixie();
|
||||||
updateLocalTime();
|
updateLocalTime();
|
||||||
checkTimers();
|
checkTimers();
|
||||||
switch (overlayCurrent)
|
checkCountdown();
|
||||||
{
|
if (overlayCurrent == 3) _overlayCronixie();//Diamex cronixie clock kit
|
||||||
case 0: break;//no overlay
|
|
||||||
case 1: _overlayAnalogClock(); break;//2 analog clock
|
|
||||||
case 2: _overlayNixieClock(); break;//nixie 1-digit
|
|
||||||
case 3: _overlayCronixie();//Diamex cronixie clock kit
|
|
||||||
}
|
|
||||||
if (!countdownMode || overlayCurrent < 2) checkCountdown(); //countdown macro activation must work
|
|
||||||
overlayRefreshedTime = millis();
|
overlayRefreshedTime = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _overlayAnalogClock()
|
void _overlayAnalogClock()
|
||||||
{
|
{
|
||||||
int overlaySize = overlayMax - overlayMin +1;
|
int overlaySize = overlayMax - overlayMin +1;
|
||||||
strip.unlockAll();
|
|
||||||
if (countdownMode)
|
if (countdownMode)
|
||||||
{
|
{
|
||||||
_overlayAnalogCountdown(); return;
|
_overlayAnalogCountdown(); return;
|
||||||
@ -173,115 +67,19 @@ void _overlayAnalogClock()
|
|||||||
{
|
{
|
||||||
pix = analogClock12pixel + round((overlaySize / 12.0) *i);
|
pix = analogClock12pixel + round((overlaySize / 12.0) *i);
|
||||||
if (pix > overlayMax) pix -= overlaySize;
|
if (pix > overlayMax) pix -= overlaySize;
|
||||||
strip.setIndividual(pix, 0x00FFAA);
|
strip.setPixelColor(pix, 0x00FFAA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!analogClockSecondsTrail) strip.setIndividual(secondPixel, 0xFF0000);
|
if (!analogClockSecondsTrail) strip.setPixelColor(secondPixel, 0xFF0000);
|
||||||
strip.setIndividual(minutePixel, 0x00FF00);
|
strip.setPixelColor(minutePixel, 0x00FF00);
|
||||||
strip.setIndividual(hourPixel, 0x0000FF);
|
strip.setPixelColor(hourPixel, 0x0000FF);
|
||||||
overlayRefreshMs = 998;
|
overlayRefreshMs = 998;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _overlayNixieClock()
|
|
||||||
{
|
|
||||||
#ifdef WLED_DISABLE_CRONIXIE
|
|
||||||
if (countdownMode) checkCountdown();
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (countdownMode)
|
|
||||||
{
|
|
||||||
_overlayNixieCountdown(); return;
|
|
||||||
}
|
|
||||||
if (nixieClockI < 0)
|
|
||||||
{
|
|
||||||
overlayArr[0] = hour(local);
|
|
||||||
if (useAMPM) overlayArr[0] = overlayArr[0]%12;
|
|
||||||
overlayArr[1] = -1;
|
|
||||||
if (overlayArr[0] > 9)
|
|
||||||
{
|
|
||||||
overlayArr[1] = overlayArr[0]%10;
|
|
||||||
overlayArr[0] = overlayArr[0]/10;
|
|
||||||
}
|
|
||||||
overlayArr[2] = minute(local);
|
|
||||||
overlayArr[3] = overlayArr[2]%10;
|
|
||||||
overlayArr[2] = overlayArr[2]/10;
|
|
||||||
overlayArr[4] = -1;
|
|
||||||
overlayArr[5] = -1;
|
|
||||||
if (analogClockSecondsTrail)
|
|
||||||
{
|
|
||||||
overlayArr[4] = second(local);
|
|
||||||
overlayArr[5] = overlayArr[4]%10;
|
|
||||||
overlayArr[4] = overlayArr[4]/10;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
if (overlayArr[i] != -1)
|
|
||||||
{
|
|
||||||
overlayArr[i] = overlayArr[i] + overlayMin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
overlayDur[0] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
if (overlayArr[1] == overlayArr[0])
|
|
||||||
{
|
|
||||||
overlayPauseDur[0] = 3 + 3*(255 - overlaySpeed);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayPauseDur[0] = 0;
|
|
||||||
}
|
|
||||||
if (overlayArr[1] == -1)
|
|
||||||
{
|
|
||||||
overlayDur[1] = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayDur[1] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
}
|
|
||||||
overlayPauseDur[1] = 9 + 9*(255 - overlaySpeed);
|
|
||||||
|
|
||||||
overlayDur[2] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
if (overlayArr[2] == overlayArr[3])
|
|
||||||
{
|
|
||||||
overlayPauseDur[2] = 3 + 3*(255 - overlaySpeed);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayPauseDur[2] = 0;
|
|
||||||
}
|
|
||||||
overlayDur[3] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
overlayPauseDur[3] = 9 + 9*(255 - overlaySpeed);
|
|
||||||
|
|
||||||
if (overlayArr[4] == -1)
|
|
||||||
{
|
|
||||||
overlayDur[4] = 0;
|
|
||||||
overlayPauseDur[4] = 0;
|
|
||||||
overlayDur[5] = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayDur[4] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
if (overlayArr[5] == overlayArr[4])
|
|
||||||
{
|
|
||||||
overlayPauseDur[4] = 3 + 3*(255 - overlaySpeed);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayPauseDur[4] = 0;
|
|
||||||
}
|
|
||||||
overlayDur[5] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
}
|
|
||||||
overlayPauseDur[5] = 22 + 22*(255 - overlaySpeed);
|
|
||||||
|
|
||||||
nixieClockI = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
_nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void _overlayAnalogCountdown()
|
void _overlayAnalogCountdown()
|
||||||
{
|
{
|
||||||
strip.unlockAll();
|
if (now() < countdownTime)
|
||||||
if (now() >= countdownTime)
|
|
||||||
{
|
|
||||||
checkCountdown();
|
|
||||||
} else
|
|
||||||
{
|
{
|
||||||
long diff = countdownTime - now();
|
long diff = countdownTime - now();
|
||||||
double pval = 60;
|
double pval = 60;
|
||||||
@ -321,31 +119,7 @@ void _overlayAnalogCountdown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _overlayNixieCountdown()
|
void handleOverlayDraw() {
|
||||||
{
|
if (overlayCurrent != 1) return; //only analog clock
|
||||||
if (now() >= countdownTime)
|
_overlayAnalogClock();
|
||||||
{
|
|
||||||
if (checkCountdown())
|
|
||||||
{
|
|
||||||
_nixieNumber(2019, 2019);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
long diff = countdownTime - now();
|
|
||||||
if (diff > 86313600L) //display in years if more than 999 days
|
|
||||||
{
|
|
||||||
diff = diff/31557600L;
|
|
||||||
} else if (diff > 3596400) //display in days if more than 999 hours
|
|
||||||
{
|
|
||||||
diff = diff/86400;
|
|
||||||
} else if (diff > 59940) //display in hours if more than 999 minutes
|
|
||||||
{
|
|
||||||
diff = diff/1440;
|
|
||||||
} else if (diff > 999) //display in minutes if more than 999 seconds
|
|
||||||
{
|
|
||||||
diff = diff/60;
|
|
||||||
}
|
|
||||||
_nixieNumber(diff, 800);
|
|
||||||
}
|
|
||||||
overlayRefreshMs = 998;
|
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,11 @@ void onAlexaChange(EspalexaDevice* dev)
|
|||||||
} else //color
|
} else //color
|
||||||
{
|
{
|
||||||
uint32_t color = espalexaDevice->getRGB();
|
uint32_t color = espalexaDevice->getRGB();
|
||||||
|
col[3] = ((color >> 24) & 0xFF); // white color from Alexa is "pure white only"
|
||||||
col[0] = ((color >> 16) & 0xFF);
|
col[0] = ((color >> 16) & 0xFF);
|
||||||
col[1] = ((color >> 8) & 0xFF);
|
col[1] = ((color >> 8) & 0xFF);
|
||||||
col[2] = (color & 0xFF);
|
col[2] = (color & 0xFF);
|
||||||
if (useRGBW) colorRGBtoRGBW(col);
|
if (useRGBW && col[3] == 0) colorRGBtoRGBW(col); // do not touch white value if EspalexaDevice.cpp did set the white channel
|
||||||
colorUpdated(10);
|
colorUpdated(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,7 @@ void setCronixie()
|
|||||||
|
|
||||||
void _overlayCronixie()
|
void _overlayCronixie()
|
||||||
{
|
{
|
||||||
if (countdownMode) checkCountdown();
|
|
||||||
#ifndef WLED_DISABLE_CRONIXIE
|
#ifndef WLED_DISABLE_CRONIXIE
|
||||||
|
|
||||||
byte h = hour(local);
|
byte h = hour(local);
|
||||||
byte h0 = h;
|
byte h0 = h;
|
||||||
byte m = minute(local);
|
byte m = minute(local);
|
||||||
|
@ -165,6 +165,6 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw)
|
|||||||
float low = minf(rgb[0],minf(rgb[1],rgb[2]));
|
float low = minf(rgb[0],minf(rgb[1],rgb[2]));
|
||||||
float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
|
float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
|
||||||
if (high < 0.1f) return;
|
if (high < 0.1f) return;
|
||||||
float sat = 255.0f * ((high - low) / high);
|
float sat = 100.0f * ((high - low) / high);; // maximum saturation is 100 (corrected from 255)
|
||||||
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
|
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
* MQTT communication protocol for home automation
|
* MQTT communication protocol for home automation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_MQTT
|
||||||
|
|
||||||
void parseMQTTBriPayload(char* payload)
|
void parseMQTTBriPayload(char* payload)
|
||||||
{
|
{
|
||||||
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
|
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
|
||||||
@ -104,7 +106,7 @@ void publishMqtt()
|
|||||||
bool initMqtt()
|
bool initMqtt()
|
||||||
{
|
{
|
||||||
lastMqttReconnectAttempt = millis();
|
lastMqttReconnectAttempt = millis();
|
||||||
if (mqttServer[0] == 0 || !WLED_CONNECTED) return false;
|
if (!mqttEnabled || mqttServer[0] == 0 || !WLED_CONNECTED) return false;
|
||||||
|
|
||||||
if (mqtt == nullptr) {
|
if (mqtt == nullptr) {
|
||||||
mqtt = new AsyncMqttClient();
|
mqtt = new AsyncMqttClient();
|
||||||
@ -130,3 +132,8 @@ bool initMqtt()
|
|||||||
mqtt->connect();
|
mqtt->connect();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
bool initMqtt(){return false;}
|
||||||
|
void publishMqtt(){}
|
||||||
|
#endif
|
||||||
|
@ -68,7 +68,7 @@ void initServer()
|
|||||||
|
|
||||||
server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
if (!(wifiLock && otaLock)) handleSettingsSet(request, 1);
|
if (!(wifiLock && otaLock)) handleSettingsSet(request, 1);
|
||||||
serveMessage(request, 200,"WiFi settings saved.","Reconnecting now...",129);
|
serveMessage(request, 200,"WiFi settings saved.","Please connect to the new IP (if changed)",129);
|
||||||
forceReconnect = true;
|
forceReconnect = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ void initServer()
|
|||||||
|
|
||||||
server.on("/settings/ui", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/ui", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
handleSettingsSet(request, 3);
|
handleSettingsSet(request, 3);
|
||||||
serveMessage(request, 200,"UI settings saved.","Reloading to apply theme...",122);
|
serveMessage(request, 200,"UI settings saved.","Redirecting...",1);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
@ -94,7 +94,7 @@ void initServer()
|
|||||||
|
|
||||||
server.on("/settings/sec", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/sec", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
handleSettingsSet(request, 6);
|
handleSettingsSet(request, 6);
|
||||||
if (!doReboot) serveMessage(request, 200,"Security settings saved.","Rebooting now, please wait ~10 seconds...",129);
|
if (!doReboot) serveMessage(request, 200,"Security settings saved.","Rebooting, please wait ~10 seconds...",129);
|
||||||
doReboot = true;
|
doReboot = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -102,9 +102,20 @@ void initServer()
|
|||||||
serveJson(request);
|
serveJson(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request, JsonObject root) {
|
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) {
|
||||||
if (root.isNull()){request->send(500, "application/json", "{\"error\":\"Parsing failed\"}"); return;}
|
bool verboseResponse = false;
|
||||||
if (deserializeState(root)) { serveJson(request); return; } //if JSON contains "v" (verbose response)
|
{ //scope JsonDocument so it releases its buffer
|
||||||
|
DynamicJsonDocument jsonBuffer(8192);
|
||||||
|
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
|
||||||
|
JsonObject root = jsonBuffer.as<JsonObject>();
|
||||||
|
if (error || root.isNull()) {
|
||||||
|
request->send(400, "application/json", "{\"error\":10}"); return;
|
||||||
|
}
|
||||||
|
verboseResponse = deserializeState(root);
|
||||||
|
}
|
||||||
|
if (verboseResponse) { //if JSON contains "v"
|
||||||
|
serveJson(request); return;
|
||||||
|
}
|
||||||
request->send(200, "application/json", "{\"success\":true}");
|
request->send(200, "application/json", "{\"success\":true}");
|
||||||
});
|
});
|
||||||
server.addHandler(handler);
|
server.addHandler(handler);
|
||||||
|
@ -86,8 +86,8 @@ bool deserializeState(JsonObject root)
|
|||||||
int ps = root["ps"] | -1;
|
int ps = root["ps"] | -1;
|
||||||
if (ps >= 0) applyPreset(ps);
|
if (ps >= 0) applyPreset(ps);
|
||||||
|
|
||||||
int cy = root["pl"] | -1;
|
int cy = root["pl"] | -2;
|
||||||
presetCyclingEnabled = (cy >= 0);
|
if (cy > -2) presetCyclingEnabled = (cy >= 0);
|
||||||
JsonObject ccnf = root["ccnf"];
|
JsonObject ccnf = root["ccnf"];
|
||||||
presetCycleMin = ccnf["min"] | presetCycleMin;
|
presetCycleMin = ccnf["min"] | presetCycleMin;
|
||||||
presetCycleMax = ccnf["max"] | presetCycleMax;
|
presetCycleMax = ccnf["max"] | presetCycleMax;
|
||||||
@ -121,15 +121,23 @@ bool deserializeState(JsonObject root)
|
|||||||
if (segVar.is<JsonObject>())
|
if (segVar.is<JsonObject>())
|
||||||
{
|
{
|
||||||
int id = segVar["id"] | -1;
|
int id = segVar["id"] | -1;
|
||||||
|
|
||||||
if (id < 0) { //set all selected segments
|
if (id < 0) { //set all selected segments
|
||||||
|
bool didSet = false;
|
||||||
|
byte lowestActive = 99;
|
||||||
for (byte s = 0; s < strip.getMaxSegments(); s++)
|
for (byte s = 0; s < strip.getMaxSegments(); s++)
|
||||||
{
|
{
|
||||||
WS2812FX::Segment sg = strip.getSegment(s);
|
WS2812FX::Segment sg = strip.getSegment(s);
|
||||||
if (sg.isActive() && sg.isSelected())
|
if (sg.isActive())
|
||||||
{
|
{
|
||||||
deserializeSegment(segVar, s);
|
if (lowestActive == 99) lowestActive = s;
|
||||||
|
if (sg.isSelected()) {
|
||||||
|
deserializeSegment(segVar, s);
|
||||||
|
didSet = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!didSet && lowestActive < strip.getMaxSegments()) deserializeSegment(segVar, lowestActive);
|
||||||
} else { //set only the segment with the specified ID
|
} else { //set only the segment with the specified ID
|
||||||
deserializeSegment(segVar, it);
|
deserializeSegment(segVar, it);
|
||||||
}
|
}
|
||||||
@ -142,7 +150,6 @@ bool deserializeState(JsonObject root)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//fromJson = true;
|
|
||||||
colorUpdated(noNotification ? 5:1);
|
colorUpdated(noNotification ? 5:1);
|
||||||
|
|
||||||
ps = root["psave"] | -1;
|
ps = root["psave"] | -1;
|
||||||
@ -236,10 +243,12 @@ void serializeInfo(JsonObject root)
|
|||||||
leds_pin.add(LEDPIN);
|
leds_pin.add(LEDPIN);
|
||||||
|
|
||||||
leds["pwr"] = strip.currentMilliamps;
|
leds["pwr"] = strip.currentMilliamps;
|
||||||
leds["maxpwr"] = strip.ablMilliampsMax;
|
leds["maxpwr"] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||||
leds["maxseg"] = strip.getMaxSegments();
|
leds["maxseg"] = strip.getMaxSegments();
|
||||||
leds["seglock"] = false; //will be used in the future to prevent modifications to segment config
|
leds["seglock"] = false; //will be used in the future to prevent modifications to segment config
|
||||||
|
|
||||||
|
root["str"] = syncToggleReceive;
|
||||||
|
|
||||||
root["name"] = serverDescription;
|
root["name"] = serverDescription;
|
||||||
root["udpport"] = udpPort;
|
root["udpport"] = udpPort;
|
||||||
root["live"] = realtimeActive;
|
root["live"] = realtimeActive;
|
||||||
@ -295,7 +304,7 @@ void serializeInfo(JsonObject root)
|
|||||||
|
|
||||||
root["brand"] = "WLED";
|
root["brand"] = "WLED";
|
||||||
root["product"] = "DIY light";
|
root["product"] = "DIY light";
|
||||||
root["btype"] = "dev";
|
root["btype"] = "src";
|
||||||
root["mac"] = escapedMac;
|
root["mac"] = escapedMac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user