mirror of
https://github.com/wled/WLED.git
synced 2025-08-31 13:30:23 +00:00
Compare commits
58 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f4a2ffc5d2 | ||
![]() |
ba1117e10e | ||
![]() |
0cd46f932a | ||
![]() |
937f404583 | ||
![]() |
d13d60d752 | ||
![]() |
31e4e7c709 | ||
![]() |
0d3a8ce31b | ||
![]() |
be185b46a7 | ||
![]() |
90fa5b3b93 | ||
![]() |
733996772b | ||
![]() |
d4c921ea2e | ||
![]() |
2852061699 | ||
![]() |
d8859b9f0a | ||
![]() |
ae1bc96006 | ||
![]() |
f30ffb4413 | ||
![]() |
273c6467c8 | ||
![]() |
846a1d007c | ||
![]() |
1dccc8dc78 | ||
![]() |
e0d67bd057 | ||
![]() |
4b4b93ac04 | ||
![]() |
4390aee1e0 | ||
![]() |
4cddb16788 | ||
![]() |
e1179fd8c8 | ||
![]() |
cb77285277 | ||
![]() |
6c9d161950 | ||
![]() |
40aaac5868 | ||
![]() |
e16b69594e | ||
![]() |
4837bf007a | ||
![]() |
705fd4dafd | ||
![]() |
a3e28d3c66 | ||
![]() |
4a6755c28a | ||
![]() |
188fe5dc52 | ||
![]() |
44a8ae457d | ||
![]() |
92eafcfe1a | ||
![]() |
b12b031fdd | ||
![]() |
492ec489a1 | ||
![]() |
c57124e876 | ||
![]() |
95b33c9c34 | ||
![]() |
c6d8b63e54 | ||
![]() |
f0f02c4ea6 | ||
![]() |
eb2cb6810a | ||
![]() |
b3c090e9ed | ||
![]() |
13366fc9f8 | ||
![]() |
929af7830a | ||
![]() |
13062cf0e4 | ||
![]() |
b897a8a35f | ||
![]() |
117dc5288d | ||
![]() |
4b5a3bd3d5 | ||
![]() |
b224a67ea7 | ||
![]() |
793f919d59 | ||
![]() |
315987b2f6 | ||
![]() |
9b7db548a2 | ||
![]() |
126b70f781 | ||
![]() |
0bbff627e2 | ||
![]() |
961d23e2a1 | ||
![]() |
b03ff9a48a | ||
![]() |
3ffb40fafa | ||
![]() |
1a3b4ac2ac |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,3 +3,5 @@
|
||||
.piolibdeps
|
||||
.vscode
|
||||
!.vscode/extensions.json
|
||||
/wled00/Release
|
||||
/wled00/extLibs
|
||||
|
BIN
.vs/wled00/v15/.suo
Normal file
BIN
.vs/wled00/v15/.suo
Normal file
Binary file not shown.
@@ -21,15 +21,15 @@ upload_speed = 115200
|
||||
upload_speed_fast = 921600
|
||||
build_flags =
|
||||
-w ; supresses all C/C++ warnings
|
||||
; -D VERSION=0.8.4
|
||||
; -D VERSION=0.8.5
|
||||
; -D DEBUG
|
||||
# TODO replace libs in /lib with managed libs in here if possible.
|
||||
# If they are not changed it's just a matter of setting the correct version and change the import statement
|
||||
lib_deps_external =
|
||||
#Blynk@0.5.4(changed)
|
||||
#E131@1.0.0(changed)
|
||||
FastLED@3.2.6
|
||||
NeoPixelBus@2.4.3
|
||||
FastLED@3.3.2
|
||||
NeoPixelBus@2.5.1
|
||||
ESPAsyncTCP@1.2.0
|
||||
AsyncTCP@1.0.3
|
||||
Esp Async WebServer@1.2.0
|
||||
@@ -56,8 +56,9 @@ arduino_core_2_4_0 = espressif8266@1.6.0
|
||||
arduino_core_2_4_1 = espressif8266@1.7.3
|
||||
arduino_core_2_4_2 = espressif8266@1.8.0
|
||||
arduino_core_2_5_0 = espressif8266@2.0.4
|
||||
arduino_core_2_5_2 = espressif8266@2.2.3
|
||||
arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
||||
platform = ${common:esp8266.arduino_core_2_4_2}
|
||||
platform = ${common:esp8266.arduino_core_2_5_2}
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
-Wl,-Teagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs
|
||||
@@ -70,8 +71,8 @@ build_flags =
|
||||
; -D WLED_DISABLE_MOBILE_UI
|
||||
; -D WLED_DISABLE_OTA
|
||||
; -D WLED_DISABLE_ALEXA
|
||||
; -D WLED_DISABLE_BLYNK
|
||||
; -D WLED_DISABLE_CRONIXIE
|
||||
-D WLED_DISABLE_BLYNK
|
||||
-D WLED_DISABLE_CRONIXIE
|
||||
; -D WLED_DISABLE_HUESYNC
|
||||
-D WLED_DISABLE_INFRARED
|
||||
|
||||
@@ -83,8 +84,8 @@ build_flags =
|
||||
; -D WLED_DISABLE_MOBILE_UI
|
||||
-D WLED_DISABLE_OTA
|
||||
; -D WLED_DISABLE_ALEXA
|
||||
; -D WLED_DISABLE_BLYNK
|
||||
; -D WLED_DISABLE_CRONIXIE
|
||||
-D WLED_DISABLE_BLYNK
|
||||
-D WLED_DISABLE_CRONIXIE
|
||||
; -D WLED_DISABLE_HUESYNC
|
||||
-D WLED_DISABLE_INFRARED
|
||||
|
||||
@@ -159,5 +160,4 @@ build_flags =
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
lib_ignore =
|
||||
IRremoteESP8266
|
||||
|
||||
IRremoteESP8266
|
52
readme.md
52
readme.md
@@ -7,36 +7,36 @@
|
||||
|
||||
## Welcome to my project WLED!
|
||||
|
||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
|
||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
|
||||
|
||||
### Features:
|
||||
- WS2812FX library integrated for 80 special effects
|
||||
- FastLED noise effects and palettes
|
||||
- Customizable Mobile and desktop UI with color and effect controls
|
||||
- Settings page - configuration over network
|
||||
- Access Point and station mode - automatic failsafe AP
|
||||
- Support for RGBW strips
|
||||
- 25 user presets to save and load colors/effects easily, supports cycling through them.
|
||||
- Macro functions to automatically execute API calls
|
||||
- Nightlight function (gradually dims down)
|
||||
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
||||
- Configurable analog clock + support for the Cronixie kit by Diamex
|
||||
- Configurable Auto Brightness limit for safer operation
|
||||
- WS2812FX library integrated for 80 special effects
|
||||
- FastLED noise effects and palettes
|
||||
- Customizable Mobile and desktop UI with color and effect controls
|
||||
- Settings page - configuration over network
|
||||
- Access Point and station mode - automatic failsafe AP
|
||||
- Support for RGBW strips
|
||||
- 25 user presets to save and load colors/effects easily, supports cycling through them.
|
||||
- Macro functions to automatically execute API calls
|
||||
- Nightlight function (gradually dims down)
|
||||
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
||||
- Configurable analog clock + support for the Cronixie kit by Diamex
|
||||
- Configurable Auto Brightness limit for safer operation
|
||||
|
||||
### Supported light control interfaces:
|
||||
- WLED Android app
|
||||
- HTTP and JSON request APIs
|
||||
- Blynk IoT
|
||||
- MQTT
|
||||
- E1.31
|
||||
- Hyperion
|
||||
- UDP realtime
|
||||
- Alexa voice control (including dimming and color)
|
||||
- Sync to Philips hue lights
|
||||
- Adalight (PC ambilight via serial)
|
||||
- Sync color of multiple WLED devices (UDP notifier)
|
||||
- Infrared remotes (24-key RGB, receiver required)
|
||||
- Simple timers/schedules (time from NTP, timezones/DST supported)
|
||||
- WLED app for Android and iOS
|
||||
- JSON and HTTP request APIs
|
||||
- MQTT
|
||||
- Blynk IoT
|
||||
- E1.31
|
||||
- Hyperion
|
||||
- UDP realtime
|
||||
- Alexa voice control (including dimming and color)
|
||||
- Sync to Philips hue lights
|
||||
- Adalight (PC ambilight via serial)
|
||||
- Sync color of multiple WLED devices (UDP notifier)
|
||||
- Infrared remotes (24-key RGB, receiver required)
|
||||
- Simple timers/schedules (time from NTP, timezones/DST supported)
|
||||
|
||||
### Quick start guide and documentation:
|
||||
|
||||
|
25
wled00.sln
Normal file
25
wled00.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28010.2046
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wled00", "wled00\wled00.vcxproj", "{C5F80730-F44F-4478-BDAE-6634EFC2CA88}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9A679C2B-61D3-400B-B96F-06E604E9CED2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
wled00/.vs/wled00/v15/.suo
Normal file
BIN
wled00/.vs/wled00/v15/.suo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -40,14 +40,21 @@
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
/* Not used in all effects yet */
|
||||
#define WLED_FPS 42
|
||||
#define FRAMETIME 1000/WLED_FPS
|
||||
|
||||
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#define MAX_NUM_SEGMENTS 1
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define MAX_NUM_SEGMENTS 10
|
||||
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define SEGMENT _segments[_segment_index]
|
||||
#define SEGMENT_RUNTIME _segment_runtimes[_segment_index]
|
||||
#define SEGMENT_LENGTH (SEGMENT.stop - SEGMENT.start)
|
||||
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGMENT_LENGTH
|
||||
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
|
||||
#define SEGENV _segment_runtimes[_segment_index]
|
||||
#define SEGLEN SEGMENT.length()
|
||||
#define SEGACT SEGMENT.stop
|
||||
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
|
||||
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
||||
|
||||
// some common colors
|
||||
@@ -77,7 +84,7 @@
|
||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
||||
|
||||
#define MODE_COUNT 80
|
||||
#define MODE_COUNT 83
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
@@ -160,6 +167,9 @@
|
||||
#define FX_MODE_METEOR_SMOOTH 77
|
||||
#define FX_MODE_RAILWAY 78
|
||||
#define FX_MODE_RIPPLE 79
|
||||
#define FX_MODE_TWINKLEFOX 80
|
||||
#define FX_MODE_TWINKLECAT 81
|
||||
#define FX_MODE_HALLOWEEN_EYES 82
|
||||
|
||||
|
||||
class WS2812FX {
|
||||
@@ -176,11 +186,6 @@ class WS2812FX {
|
||||
uint8_t mode;
|
||||
uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected
|
||||
uint32_t colors[NUM_COLORS];
|
||||
//member functions
|
||||
uint32_t color(uint8_t n)
|
||||
{
|
||||
return colors[n];
|
||||
}
|
||||
void setOption(uint8_t n, bool val)
|
||||
{
|
||||
if (val) {
|
||||
@@ -194,19 +199,32 @@ class WS2812FX {
|
||||
{
|
||||
return ((options >> n) & 0x01);
|
||||
}
|
||||
bool isSelected()
|
||||
{
|
||||
return getOption(0);
|
||||
}
|
||||
bool isActive()
|
||||
{
|
||||
return stop > start;
|
||||
}
|
||||
uint16_t length()
|
||||
{
|
||||
return stop - start;
|
||||
}
|
||||
} segment;
|
||||
|
||||
// segment runtime parameters
|
||||
typedef struct Segment_runtime { // 16 bytes
|
||||
unsigned long next_time;
|
||||
uint32_t counter_mode_step;
|
||||
uint32_t counter_mode_call;
|
||||
uint16_t aux_param;
|
||||
uint16_t aux_param2;
|
||||
void reset(){next_time = 0; counter_mode_step = 0; counter_mode_call = 0; aux_param = 0; aux_param2 = 0;};
|
||||
uint32_t step;
|
||||
uint32_t call;
|
||||
uint16_t aux0;
|
||||
uint16_t aux1;
|
||||
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;};
|
||||
} segment_runtime;
|
||||
|
||||
WS2812FX() {
|
||||
//assign each member of the _mode[] array to its respective function reference
|
||||
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
|
||||
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
|
||||
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
|
||||
@@ -287,43 +305,35 @@ class WS2812FX {
|
||||
_mode[FX_MODE_METEOR_SMOOTH] = &WS2812FX::mode_meteor_smooth;
|
||||
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
|
||||
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
|
||||
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
||||
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
|
||||
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
|
||||
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
_num_segments = 1;
|
||||
_segments[0].mode = DEFAULT_MODE;
|
||||
_segments[0].colors[0] = DEFAULT_COLOR;
|
||||
_segments[0].start = 0;
|
||||
_segments[0].speed = DEFAULT_SPEED;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
targetPalette = CloudColors_p;
|
||||
_reverseMode = false;
|
||||
_skipFirstMode = false;
|
||||
colorOrder = 0;
|
||||
paletteFade = 0;
|
||||
paletteBlend = 0;
|
||||
ablMilliampsMax = 850;
|
||||
currentMilliamps = 0;
|
||||
timebase = 0;
|
||||
_locked = nullptr;
|
||||
_modeUsesLock = false;
|
||||
bus = new NeoPixelWrapper();
|
||||
RESET_RUNTIME;
|
||||
resetSegments();
|
||||
}
|
||||
|
||||
void
|
||||
init(bool supportWhite, uint16_t countPixels, bool skipFirst),
|
||||
init(bool supportWhite, uint16_t countPixels, bool skipFirs),
|
||||
service(void),
|
||||
blur(uint8_t),
|
||||
fade_out(uint8_t r),
|
||||
setMode(uint8_t m),
|
||||
setMode(uint8_t segid, uint8_t m),
|
||||
setSpeed(uint8_t s),
|
||||
setIntensity(uint8_t i),
|
||||
setPalette(uint8_t p),
|
||||
setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setColor(uint32_t c),
|
||||
setSecondaryColor(uint32_t c),
|
||||
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setColor(uint8_t slot, uint32_t c),
|
||||
setBrightness(uint8_t b),
|
||||
setReverseMode(bool b),
|
||||
driverModeCronixie(bool b),
|
||||
setCronixieDigits(byte* d),
|
||||
setCronixieBacklight(bool b),
|
||||
@@ -343,25 +353,37 @@ class WS2812FX {
|
||||
show(void);
|
||||
|
||||
bool
|
||||
reverseMode = false,
|
||||
gammaCorrectBri = false,
|
||||
gammaCorrectCol = true,
|
||||
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
|
||||
|
||||
uint8_t
|
||||
paletteFade,
|
||||
paletteBlend,
|
||||
colorOrder,
|
||||
returnedSegment = 0,
|
||||
paletteFade = 0,
|
||||
paletteBlend = 0,
|
||||
colorOrder = 0,
|
||||
getBrightness(void),
|
||||
getMode(void),
|
||||
getSpeed(void),
|
||||
getNumSegments(void),
|
||||
getModeCount(void),
|
||||
getPaletteCount(void),
|
||||
getMaxSegments(void),
|
||||
getFirstSelectedSegment(void),
|
||||
getReturnedSegmentId(void),
|
||||
gamma8(uint8_t),
|
||||
get_random_wheel_index(uint8_t);
|
||||
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps;
|
||||
|
||||
uint32_t
|
||||
timebase,
|
||||
color_wheel(uint8_t),
|
||||
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
|
||||
color_blend(uint32_t,uint32_t,uint8_t),
|
||||
gamma32(uint32_t),
|
||||
getPixelColor(uint16_t),
|
||||
getColor(void);
|
||||
|
||||
@@ -374,21 +396,6 @@ class WS2812FX {
|
||||
WS2812FX::Segment*
|
||||
getSegments(void);
|
||||
|
||||
// mode helper functions
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps,
|
||||
blink(uint32_t, uint32_t, bool strobe, bool),
|
||||
color_wipe(uint32_t, uint32_t, bool , bool),
|
||||
scan(bool),
|
||||
theater_chase(uint32_t, uint32_t, bool),
|
||||
running_base(bool),
|
||||
dissolve(uint32_t),
|
||||
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||
gradient_base(bool),
|
||||
running(uint32_t, uint32_t),
|
||||
tricolor_chase(uint32_t, uint32_t);
|
||||
|
||||
// builtin modes
|
||||
uint16_t
|
||||
mode_static(void),
|
||||
@@ -471,15 +478,20 @@ class WS2812FX {
|
||||
mode_meteor(void),
|
||||
mode_meteor_smooth(void),
|
||||
mode_railway(void),
|
||||
mode_ripple(void);
|
||||
mode_ripple(void),
|
||||
mode_twinklefox(void),
|
||||
mode_twinklecat(void),
|
||||
mode_halloween_eyes(void);
|
||||
|
||||
private:
|
||||
NeoPixelWrapper *bus;
|
||||
|
||||
CRGB fastled_from_col(uint32_t);
|
||||
uint32_t crgb_to_col(CRGB fastled);
|
||||
CRGB col_to_crgb(uint32_t);
|
||||
CRGBPalette16 currentPalette;
|
||||
CRGBPalette16 targetPalette;
|
||||
|
||||
|
||||
uint32_t now;
|
||||
uint16_t _length;
|
||||
uint16_t _rand16seed;
|
||||
uint8_t _brightness;
|
||||
@@ -487,11 +499,11 @@ class WS2812FX {
|
||||
void handle_palette(void);
|
||||
void fill(uint32_t);
|
||||
bool modeUsesLock(uint8_t);
|
||||
void twinklefox_base(bool);
|
||||
|
||||
bool
|
||||
_modeUsesLock,
|
||||
_rgbwMode,
|
||||
_reverseMode,
|
||||
_cronixieMode,
|
||||
_cronixieBacklightEnabled,
|
||||
_skipFirstMode,
|
||||
@@ -502,13 +514,26 @@ class WS2812FX {
|
||||
|
||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
|
||||
// mode helper functions
|
||||
uint16_t
|
||||
blink(uint32_t, uint32_t, bool strobe, bool),
|
||||
color_wipe(bool, bool),
|
||||
scan(bool),
|
||||
theater_chase(uint32_t, uint32_t, bool),
|
||||
running_base(bool),
|
||||
dissolve(uint32_t),
|
||||
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||
gradient_base(bool),
|
||||
running(uint32_t, uint32_t),
|
||||
tricolor_chase(uint32_t, uint32_t);
|
||||
|
||||
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
||||
|
||||
uint32_t _lastPaletteChange = 0;
|
||||
uint32_t _lastShow = 0;
|
||||
|
||||
uint8_t _segment_index = 0;
|
||||
uint8_t _segment_index_palette_last = 99;
|
||||
uint8_t _num_segments = 1;
|
||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 21 bytes per element
|
||||
// start, stop, speed, intensity, palette, mode, options, color[]
|
||||
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, {DEFAULT_COLOR}}
|
||||
@@ -525,8 +550,9 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
||||
"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","In Out","In In",
|
||||
"Out Out","Out In","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","Noise 1",
|
||||
"Noise 2","Noise 3","Noise 4","Colortwinkle","Lake","Meteor","Smooth Meteor","Railway","Ripple"
|
||||
"Dual Scanner","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",
|
||||
"Twinklefox","Twinklecat","Halloween Eyes"
|
||||
])=====";
|
||||
|
||||
|
||||
@@ -535,7 +561,7 @@ const char JSON_palette_names[] PROGMEM = R"=====([
|
||||
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
|
||||
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
||||
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
||||
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night"
|
||||
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura"
|
||||
])=====";
|
||||
|
||||
#endif
|
@@ -24,7 +24,7 @@
|
||||
Modified heavily for WLED
|
||||
*/
|
||||
|
||||
#include "WS2812FX.h"
|
||||
#include "FX.h"
|
||||
#include "palettes.h"
|
||||
|
||||
#define LED_SKIP_AMOUNT 1
|
||||
@@ -55,19 +55,22 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
||||
}
|
||||
|
||||
void WS2812FX::service() {
|
||||
unsigned long now = millis(); // Be aware, millis() rolls over every 49 days
|
||||
now = millis() + timebase; // Be aware, millis() rolls over every 49 days
|
||||
if (now - _lastShow < MIN_SHOW_DELAY) return;
|
||||
bool doShow = false;
|
||||
for(uint8_t i=0; i < _num_segments; i++)
|
||||
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
_segment_index = i;
|
||||
if(now > SEGMENT_RUNTIME.next_time || _triggered)
|
||||
if (SEGMENT.isActive())
|
||||
{
|
||||
doShow = true;
|
||||
handle_palette();
|
||||
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
||||
SEGMENT_RUNTIME.next_time = now + max(delay, MIN_SHOW_DELAY);
|
||||
SEGMENT_RUNTIME.counter_mode_call++;
|
||||
if(now > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
|
||||
{
|
||||
doShow = true;
|
||||
handle_palette();
|
||||
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
||||
SEGENV.next_time = now + delay;
|
||||
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(doShow) {
|
||||
@@ -82,7 +85,7 @@ 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) return true;
|
||||
m == FX_MODE_RIPPLE || m == FX_MODE_DYNAMIC ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -97,7 +100,6 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
if (_locked[i] && !_modeUsesLock) return;
|
||||
if (_reverseMode) i = _length -1 -i;
|
||||
if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment
|
||||
byte tmpg = g;
|
||||
switch (colorOrder) //0 = Grb, default
|
||||
@@ -109,6 +111,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
}
|
||||
if (!_cronixieMode)
|
||||
{
|
||||
if (reverseMode) i = _length -1 -i;
|
||||
if (_skipFirstMode)
|
||||
{
|
||||
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
|
||||
@@ -153,11 +156,6 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setReverseMode(bool b)
|
||||
{
|
||||
_reverseMode = b;
|
||||
}
|
||||
|
||||
void WS2812FX::driverModeCronixie(bool b)
|
||||
{
|
||||
_cronixieMode = b;
|
||||
@@ -254,14 +252,24 @@ void WS2812FX::trigger() {
|
||||
_triggered = true;
|
||||
}
|
||||
|
||||
void WS2812FX::setMode(uint8_t m) {
|
||||
RESET_RUNTIME;
|
||||
bool ua = modeUsesLock(_segments[0].mode) && !modeUsesLock(m);
|
||||
if (m > MODE_COUNT - 1) m = MODE_COUNT - 1;
|
||||
_segments[0].mode = m;
|
||||
if (ua) unlockAll();
|
||||
_modeUsesLock = modeUsesLock(_segments[0].mode);
|
||||
setBrightness(_brightness);
|
||||
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
||||
if (segid >= MAX_NUM_SEGMENTS) return;
|
||||
|
||||
bool anyUsedLock = _modeUsesLock, anyUseLock = false;
|
||||
if (m >= MODE_COUNT) m = MODE_COUNT - 1;
|
||||
|
||||
if (_segments[segid].mode != m)
|
||||
{
|
||||
_segment_runtimes[segid].reset();
|
||||
_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()
|
||||
@@ -276,77 +284,117 @@ uint8_t WS2812FX::getPaletteCount()
|
||||
|
||||
//TODO transitions
|
||||
|
||||
void WS2812FX::setMode(uint8_t m) {
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected()) setMode(i, m);
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setSpeed(uint8_t s) {
|
||||
_segments[0].speed = s;
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected()) _segments[i].speed = s;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setIntensity(uint8_t in) {
|
||||
_segments[0].intensity = in;
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected()) _segments[i].intensity = in;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setPalette(uint8_t p) {
|
||||
_segments[0].palette = p;
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected()) _segments[i].palette = p;
|
||||
}
|
||||
}
|
||||
|
||||
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p) {
|
||||
bool changed = false;
|
||||
m = constrain(m, 0, MODE_COUNT - 1);
|
||||
if (m != _segments[0].mode) { setMode(m); changed = true; }
|
||||
if (s != _segments[0].speed) { setSpeed(s); changed = true; }
|
||||
if (i != _segments[0].intensity) { setIntensity(i); changed = true; }
|
||||
if (p != _segments[0].palette) { setPalette(p); changed = true; }
|
||||
return changed;
|
||||
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
||||
uint8_t retSeg = getReturnedSegmentId();
|
||||
Segment& seg = _segments[retSeg];
|
||||
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
||||
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected())
|
||||
{
|
||||
_segments[i].speed = s;
|
||||
_segments[i].intensity = in;
|
||||
_segments[i].palette = p;
|
||||
setMode(i, m);
|
||||
}
|
||||
}
|
||||
|
||||
if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
setColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
setColor(slot, ((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
void WS2812FX::setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
setSecondaryColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint32_t c) {
|
||||
_segments[0].colors[0] = c;
|
||||
}
|
||||
|
||||
void WS2812FX::setSecondaryColor(uint32_t c) {
|
||||
_segments[0].colors[1] = c;
|
||||
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
|
||||
if (slot >= NUM_COLORS) return;
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setBrightness(uint8_t b) {
|
||||
if (_brightness == b) return;
|
||||
_brightness = b;
|
||||
if (SEGMENT_RUNTIME.next_time > millis() + 20) show(); //apply brightness change immeadiately if no refresh soon
|
||||
_brightness = (gammaCorrectBri) ? gamma8(b) : b;
|
||||
_segment_index = 0;
|
||||
if (SEGENV.next_time > millis() + 22) show();//apply brightness change immediately if no refresh soon
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getMode(void) {
|
||||
return _segments[0].mode;
|
||||
return _segments[getReturnedSegmentId()].mode;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getSpeed(void) {
|
||||
return _segments[0].speed;
|
||||
return _segments[getReturnedSegmentId()].speed;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getBrightness(void) {
|
||||
return _brightness;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getNumSegments(void) {
|
||||
return _num_segments;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getMaxSegments(void) {
|
||||
return MAX_NUM_SEGMENTS;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getFirstSelectedSegment(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isActive() && _segments[i].isSelected()) return i;
|
||||
}
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //if none selected, get first active
|
||||
{
|
||||
if (_segments[i].isActive()) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getReturnedSegmentId(void) {
|
||||
if (returnedSegment >= MAX_NUM_SEGMENTS || !_segments[returnedSegment].isActive())
|
||||
{
|
||||
return getFirstSelectedSegment();
|
||||
}
|
||||
return returnedSegment;
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getColor(void) {
|
||||
return _segments[0].colors[0];
|
||||
return _segments[getReturnedSegmentId()].colors[0];
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||
{
|
||||
if (_reverseMode) i = _length- 1 -i;
|
||||
if (reverseMode) i = _length- 1 -i;
|
||||
if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment
|
||||
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
||||
if (_cronixieMode)
|
||||
@@ -386,7 +434,7 @@ WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
|
||||
}
|
||||
|
||||
WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) {
|
||||
return SEGMENT_RUNTIME;
|
||||
return SEGENV;
|
||||
}
|
||||
|
||||
WS2812FX::Segment* WS2812FX::getSegments(void) {
|
||||
@@ -397,6 +445,16 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
|
||||
if (n >= MAX_NUM_SEGMENTS) return;
|
||||
Segment& seg = _segments[n];
|
||||
if (seg.start == i1 && seg.stop == i2) return;
|
||||
if (seg.isActive() && modeUsesLock(seg.mode))
|
||||
{
|
||||
_modeUsesLock = false;
|
||||
unlockRange(seg.start, seg.stop);
|
||||
_modeUsesLock = true;
|
||||
}
|
||||
if (i2 <= i1) //disable segment
|
||||
{
|
||||
seg.stop = 0; return;
|
||||
}
|
||||
if (i1 < _length) seg.start = i1;
|
||||
seg.stop = i2;
|
||||
if (i2 > _length) seg.stop = _length;
|
||||
@@ -407,12 +465,12 @@ void WS2812FX::resetSegments() {
|
||||
memset(_segments, 0, sizeof(_segments));
|
||||
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
|
||||
_segment_index = 0;
|
||||
_num_segments = 1;
|
||||
_segments[0].mode = DEFAULT_MODE;
|
||||
_segments[0].colors[0] = DEFAULT_COLOR;
|
||||
_segments[0].start = 0;
|
||||
_segments[0].speed = DEFAULT_SPEED;
|
||||
_segments[0].stop = _length;
|
||||
_segments[0].setOption(0, 1); //select
|
||||
}
|
||||
|
||||
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
|
||||
@@ -439,31 +497,31 @@ void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
|
||||
|
||||
void WS2812FX::lock(uint16_t i)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
if (i >= 0 && i < _length) _locked[i] = true;
|
||||
if (_modeUsesLock) return;
|
||||
if (i < _length) _locked[i] = true;
|
||||
}
|
||||
|
||||
void WS2812FX::lockRange(uint16_t i, uint16_t i2)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
for (uint16_t x = i; x <= i2; x++)
|
||||
if (_modeUsesLock) return;
|
||||
for (uint16_t x = i; x < i2; x++)
|
||||
{
|
||||
if (i >= 0 && i < _length) _locked[i] = true;
|
||||
if (x < _length) _locked[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::unlock(uint16_t i)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
if (i >= 0 && i < _length) _locked[i] = false;
|
||||
if (_modeUsesLock) return;
|
||||
if (i < _length) _locked[i] = false;
|
||||
}
|
||||
|
||||
void WS2812FX::unlockRange(uint16_t i, uint16_t i2)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
if (_modeUsesLock) return;
|
||||
for (uint16_t x = i; x < i2; x++)
|
||||
{
|
||||
if (x >= 0 && x < _length) _locked[x] = false;
|
||||
if (x < _length) _locked[x] = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,10 +532,11 @@ void WS2812FX::unlockAll()
|
||||
|
||||
void WS2812FX::setTransitionMode(bool t)
|
||||
{
|
||||
_segment_index = 0;
|
||||
SEGMENT.setOption(7,t);
|
||||
if (!t) return;
|
||||
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
|
||||
if (SEGMENT.mode == FX_MODE_STATIC && SEGMENT_RUNTIME.next_time > waitMax) SEGMENT_RUNTIME.next_time = waitMax;
|
||||
if (SEGMENT.mode == FX_MODE_STATIC && SEGENV.next_time > waitMax) SEGENV.next_time = waitMax;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -487,15 +546,15 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend)
|
||||
if(blend == 0) return color1;
|
||||
if(blend == 255) return color2;
|
||||
|
||||
int w1 = (color1 >> 24) & 0xff;
|
||||
int r1 = (color1 >> 16) & 0xff;
|
||||
int g1 = (color1 >> 8) & 0xff;
|
||||
int b1 = color1 & 0xff;
|
||||
uint32_t w1 = (color1 >> 24) & 0xff;
|
||||
uint32_t r1 = (color1 >> 16) & 0xff;
|
||||
uint32_t g1 = (color1 >> 8) & 0xff;
|
||||
uint32_t b1 = color1 & 0xff;
|
||||
|
||||
int w2 = (color2 >> 24) & 0xff;
|
||||
int r2 = (color2 >> 16) & 0xff;
|
||||
int g2 = (color2 >> 8) & 0xff;
|
||||
int b2 = color2 & 0xff;
|
||||
uint32_t w2 = (color2 >> 24) & 0xff;
|
||||
uint32_t r2 = (color2 >> 16) & 0xff;
|
||||
uint32_t g2 = (color2 >> 8) & 0xff;
|
||||
uint32_t b2 = color2 & 0xff;
|
||||
|
||||
uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8;
|
||||
uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8;
|
||||
@@ -521,7 +580,7 @@ void WS2812FX::fade_out(uint8_t rate) {
|
||||
rate = (255-rate) >> 1;
|
||||
float mappedRate = float(rate) +1.1;
|
||||
|
||||
uint32_t color = SEGMENT.colors[1]; // target color
|
||||
uint32_t color = SEGCOLOR(1); // target color
|
||||
int w2 = (color >> 24) & 0xff;
|
||||
int r2 = (color >> 16) & 0xff;
|
||||
int g2 = (color >> 8) & 0xff;
|
||||
@@ -559,7 +618,7 @@ void WS2812FX::blur(uint8_t blur_amount)
|
||||
CRGB carryover = CRGB::Black;
|
||||
for(uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
|
||||
{
|
||||
CRGB cur = fastled_from_col(getPixelColor(i));
|
||||
CRGB cur = col_to_crgb(getPixelColor(i));
|
||||
CRGB part = cur;
|
||||
part.nscale8(seep);
|
||||
cur.nscale8(keep);
|
||||
@@ -611,7 +670,13 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
|
||||
}
|
||||
|
||||
|
||||
CRGB WS2812FX::fastled_from_col(uint32_t color)
|
||||
uint32_t WS2812FX::crgb_to_col(CRGB fastled)
|
||||
{
|
||||
return (((uint32_t)fastled.red << 16) | ((uint32_t)fastled.green << 8) | fastled.blue);
|
||||
}
|
||||
|
||||
|
||||
CRGB WS2812FX::col_to_crgb(uint32_t color)
|
||||
{
|
||||
CRGB fastled_col;
|
||||
fastled_col.red = (color >> 16 & 0xFF);
|
||||
@@ -663,11 +728,11 @@ void WS2812FX::handle_palette(void)
|
||||
_lastPaletteChange = millis();
|
||||
} break;}
|
||||
case 2: {//primary color only
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||
targetPalette = CRGBPalette16(prim); break;}
|
||||
case 3: {//based on primary
|
||||
//considering performance implications
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||
CHSV prim_hsv = rgb2hsv_approximate(prim);
|
||||
targetPalette = CRGBPalette16(
|
||||
CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself
|
||||
@@ -676,12 +741,12 @@ void WS2812FX::handle_palette(void)
|
||||
CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v)); //color itself
|
||||
break;}
|
||||
case 4: {//primary + secondary
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CRGB sec = fastled_from_col(SEGMENT.colors[1]);
|
||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||
targetPalette = CRGBPalette16(sec,prim); break;}
|
||||
case 5: {//based on primary + secondary
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CRGB sec = fastled_from_col(SEGMENT.colors[1]);
|
||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||
targetPalette = CRGBPalette16(sec,prim,CRGB::White); break;}
|
||||
case 6: //Party colors
|
||||
targetPalette = PartyColors_p; break;
|
||||
@@ -712,7 +777,7 @@ void WS2812FX::handle_palette(void)
|
||||
|
||||
uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||
{
|
||||
if (SEGMENT.palette == 0 && mcol < 3) return SEGMENT.colors[mcol]; //WS2812FX default
|
||||
if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default
|
||||
uint8_t paletteIndex = i;
|
||||
if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop-1,0,255);
|
||||
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||
@@ -720,3 +785,41 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8
|
||||
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);
|
||||
return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b;
|
||||
}
|
||||
|
||||
//gamma 2.4 lookup table used for color correction
|
||||
const byte gammaT[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
||||
uint8_t WS2812FX::gamma8(uint8_t b)
|
||||
{
|
||||
return gammaT[b];
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::gamma32(uint32_t color)
|
||||
{
|
||||
if (!gammaCorrectCol) return color;
|
||||
uint8_t w = (color >> 24) & 0xFF;
|
||||
uint8_t r = (color >> 16) & 0xFF;
|
||||
uint8_t g = (color >> 8) & 0xFF;
|
||||
uint8_t b = color & 0xFF;
|
||||
w = gammaT[w];
|
||||
r = gammaT[r];
|
||||
g = gammaT[g];
|
||||
b = gammaT[b];
|
||||
return ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||
}
|
@@ -4,20 +4,35 @@
|
||||
|
||||
//PIN CONFIGURATION
|
||||
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
||||
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
||||
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
||||
#define IR_PIN 4 //infrared pin (-1 to disable)
|
||||
#define IR_PIN 4 //infrared pin (-1 to disable)
|
||||
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
|
||||
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
|
||||
|
||||
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
||||
|
||||
#ifdef USE_APA102
|
||||
#define CLKPIN 0
|
||||
#define DATAPIN 2
|
||||
#if BTNPIN == CLKPIN || BTNPIN == DATAPIN
|
||||
#undef BTNPIN // Deactivate button pin if it conflicts with one of the APA102 pins.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//automatically uses the right driver method for each platform
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#define PIXELMETHOD NeoWs2813Method
|
||||
#ifdef USE_APA102
|
||||
#define PIXELMETHOD DotStarMethod
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod
|
||||
#endif
|
||||
#else //esp8266
|
||||
//autoselect the right method depending on strip pin
|
||||
#if LEDPIN == 2
|
||||
#ifdef USE_APA102
|
||||
#define PIXELMETHOD DotStarMethod
|
||||
#elif LEDPIN == 2
|
||||
#define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus
|
||||
#elif LEDPIN == 3
|
||||
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
|
||||
@@ -29,8 +44,13 @@
|
||||
|
||||
|
||||
//you can now change the color order in the web settings
|
||||
#define PIXELFEATURE3 NeoGrbFeature
|
||||
#define PIXELFEATURE4 NeoGrbwFeature
|
||||
#ifdef USE_APA102
|
||||
#define PIXELFEATURE3 DotStarBgrFeature
|
||||
#define PIXELFEATURE4 DotStarLbgrFeature
|
||||
#else
|
||||
#define PIXELFEATURE3 NeoGrbFeature
|
||||
#define PIXELFEATURE4 NeoGrbwFeature
|
||||
#endif
|
||||
|
||||
|
||||
#include <NeoPixelBrightnessBus.h>
|
||||
@@ -68,12 +88,20 @@ public:
|
||||
switch (_type)
|
||||
{
|
||||
case NeoPixelType_Grb:
|
||||
#ifdef USE_APA102
|
||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
|
||||
#else
|
||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
|
||||
#endif
|
||||
_pGrb->Begin();
|
||||
break;
|
||||
|
||||
case NeoPixelType_Grbw:
|
||||
#ifdef USE_APA102
|
||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
|
||||
#else
|
||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
|
||||
#endif
|
||||
_pGrbw->Begin();
|
||||
break;
|
||||
}
|
||||
|
129
wled00/__vm/.wled00.vsarduino.h
Normal file
129
wled00/__vm/.wled00.vsarduino.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Editor: https://www.visualmicro.com/
|
||||
This file is for intellisense purpose only.
|
||||
Visual micro (and the arduino ide) ignore this code during compilation. This code is automatically maintained by visualmicro, manual changes to this file will be overwritten
|
||||
The contents of the _vm sub folder can be deleted prior to publishing a project
|
||||
All non-arduino files created by visual micro and all visual studio project or solution files can be freely deleted and are not required to compile a sketch (do not delete your own code!).
|
||||
Note: debugger breakpoints are stored in '.sln' or '.asln' files, knowledge of last uploaded breakpoints is stored in the upload.vmps.xml file. Both files are required to continue a previous debug session without needing to compile and upload again
|
||||
|
||||
Hardware: ESP32 Dev Module, Platform=esp32, Package=esp32
|
||||
*/
|
||||
|
||||
#if defined(_VMICRO_INTELLISENSE)
|
||||
|
||||
#ifndef _VSARDUINO_H_
|
||||
#define _VSARDUINO_H_
|
||||
#define __ESP32_esp32__
|
||||
#define __ESP32_ESP32__
|
||||
#define ESP_PLATFORM
|
||||
#define HAVE_CONFIG_H
|
||||
#define F_CPU 240000000L
|
||||
#define ARDUINO 10807
|
||||
#define ARDUINO_ESP32_DEV
|
||||
#define ARDUINO_ARCH_ESP32
|
||||
#define ESP32
|
||||
#define CORE_DEBUG_LEVEL 0
|
||||
#define __cplusplus 201103L
|
||||
|
||||
#define _Pragma(x)
|
||||
#undef __cplusplus
|
||||
#define __cplusplus 201103L
|
||||
|
||||
#define __STDC__
|
||||
#define __ARM__
|
||||
#define __arm__
|
||||
#define __inline__
|
||||
#define __asm__(...)
|
||||
#define __extension__
|
||||
#define __ATTR_PURE__
|
||||
#define __ATTR_CONST__
|
||||
#define __volatile__
|
||||
|
||||
#define __ASM
|
||||
#define __INLINE
|
||||
#define __attribute__(noinline)
|
||||
|
||||
//#define _STD_BEGIN
|
||||
//#define EMIT
|
||||
#define WARNING
|
||||
#define _Lockit
|
||||
#define __CLR_OR_THIS_CALL
|
||||
#define C4005
|
||||
#define _NEW
|
||||
|
||||
typedef bool _Bool;
|
||||
typedef int _read;
|
||||
typedef int _seek;
|
||||
typedef int _write;
|
||||
typedef int _close;
|
||||
typedef int __cleanup;
|
||||
|
||||
//#define inline
|
||||
|
||||
#define __builtin_clz
|
||||
#define __builtin_clzl
|
||||
#define __builtin_clzll
|
||||
#define __builtin_labs
|
||||
#define __builtin_va_list
|
||||
typedef int __gnuc_va_list;
|
||||
|
||||
#define __ATOMIC_ACQ_REL
|
||||
|
||||
#define __CHAR_BIT__
|
||||
#define _EXFUN()
|
||||
|
||||
typedef unsigned char byte;
|
||||
extern "C" void __cxa_pure_virtual() {;}
|
||||
|
||||
typedef long __INTPTR_TYPE__ ;
|
||||
typedef long __UINTPTR_TYPE__ ;
|
||||
typedef long __SIZE_TYPE__ ;
|
||||
typedef long __PTRDIFF_TYPE__;
|
||||
|
||||
typedef long pthread_t;
|
||||
typedef long pthread_key_t;
|
||||
typedef long pthread_once_t;
|
||||
typedef long pthread_mutex_t;
|
||||
typedef long pthread_mutex_t;
|
||||
typedef long pthread_cond_t;
|
||||
|
||||
|
||||
|
||||
#include "arduino.h"
|
||||
#include <pins_arduino.h>
|
||||
|
||||
//#include "..\generic\Common.h"
|
||||
//#include "..\generic\pins_arduino.h"
|
||||
|
||||
//#undef F
|
||||
//#define F(string_literal) ((const PROGMEM char *)(string_literal))
|
||||
//#undef PSTR
|
||||
//#define PSTR(string_literal) ((const PROGMEM char *)(string_literal))
|
||||
//current vc++ does not understand this syntax so use older arduino example for intellisense
|
||||
//todo:move to the new clang/gcc project types.
|
||||
#define interrupts() sei()
|
||||
#define noInterrupts() cli()
|
||||
|
||||
#include "wled00.ino"
|
||||
#include "wled01_eeprom.ino"
|
||||
#include "wled02_xml.ino"
|
||||
#include "wled03_set.ino"
|
||||
#include "wled04_file.ino"
|
||||
#include "wled05_init.ino"
|
||||
#include "wled06_usermod.ino"
|
||||
#include "wled07_notify.ino"
|
||||
#include "wled08_led.ino"
|
||||
#include "wled09_button.ino"
|
||||
#include "wled10_ntp.ino"
|
||||
#include "wled11_ol.ino"
|
||||
#include "wled12_alexa.ino"
|
||||
#include "wled13_cronixie.ino"
|
||||
#include "wled14_colors.ino"
|
||||
#include "wled15_hue.ino"
|
||||
#include "wled16_blynk.ino"
|
||||
#include "wled17_mqtt.ino"
|
||||
#include "wled18_server.ino"
|
||||
#include "wled19_json.ino"
|
||||
#include "wled20_ir.ino"
|
||||
#endif
|
||||
#endif
|
12
wled00/__vm/Compile.vmps.xml
Normal file
12
wled00/__vm/Compile.vmps.xml
Normal file
File diff suppressed because one or more lines are too long
9
wled00/__vm/Configuration.Release.vmps.xml
Normal file
9
wled00/__vm/Configuration.Release.vmps.xml
Normal file
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head><meta charset="utf-8"><meta name="theme-color" content="#fff">
|
||||
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
|
||||
<title>WLED 0.8.4</title>
|
||||
<title>WLED 0.8.6</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var w=window.getComputedStyle(d.querySelector("html"));
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<meta name="theme-color" content="#333333">
|
||||
<meta content="yes" name="apple-mobile-web-app-capable">
|
||||
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
|
||||
<title>WLED 0.8.4</title>
|
||||
<title>WLED 0.8.6</title>
|
||||
<script>function feedback(){}</script>
|
||||
<style>
|
||||
*{transition-duration: 0.5s;}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta content='width=device-width' name='viewport'><title>WLED Message</title><script>function B(){window.history.back()}</script>
|
||||
<style>:root{--aCol:#D9B310;--bCol:#0B3C5D;--cCol:#1D2731;--dCol:#328CC1;--sCol:#000;--tCol:#328CC1;--cFn:Verdana;}.bt{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%}</style></head>
|
||||
<body><h2>WLED Software Update</h2>Installed version: 0.8.4-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.8.5-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>
|
@@ -1,27 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content='width=device-width' name='viewport'>
|
||||
<meta name="theme-color" content="#333333">
|
||||
<title>WLED Setup</title>
|
||||
<style>
|
||||
:root {
|
||||
--aCol: #D9B310;
|
||||
--bCol: #0B3C5D;
|
||||
--cCol: #1D2731;
|
||||
--dCol: #328CC1;
|
||||
--sCol: #000;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
background: linear-gradient(var(--bCol),black);
|
||||
background-color: #333;
|
||||
margin: 0;
|
||||
background-attachment: fixed;
|
||||
color: var(--dCol);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
button {
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
margin: 10px;
|
||||
width: 230px;
|
||||
text-transform: uppercase;
|
||||
font-family: helvetica;
|
||||
font-size: 19px;
|
||||
background-color: #222;
|
||||
color: white;
|
||||
border: 0px solid white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: var(--dCol);
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -34,10 +43,12 @@
|
||||
<svg><use xlink:href="#lnr-smile"></use></svg>
|
||||
<h1>Welcome to WLED!</h1>
|
||||
<h3>Thank you for installing my application!</h3>
|
||||
Take a quick look at the <a href="https://github.com/Aircoookie/WLED/wiki" target="_blank">wiki</a>!<br>
|
||||
If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br>
|
||||
<b>Next steps:</b><br><br>
|
||||
Connect the module to your local WiFi <a href="/settings/wifi">here</a>!<br><br>
|
||||
<i>Just trying this out in AP mode?</i> <a href="/sliders">Here are the controls.</a><br>
|
||||
Connect the module to your local WiFi here!<br>
|
||||
<button onclick="window.location.href='/settings/wifi'">WiFi settings</button><br>
|
||||
<i>Just trying this out in AP mode?</i><br>
|
||||
<button onclick="window.location.href='/sliders'">To the controls!</button>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -20,30 +20,14 @@ const char PAGE_msg[] 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>
|
||||
%CSS%.bt{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%%}</style></head>
|
||||
<body><h2>WLED Software Update</h2>Installed version: 0.8.4<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.8.6<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
|
||||
#ifndef WLED_DISABLE_MOBILE_UI
|
||||
const char PAGE_welcome[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta content='width=device-width' name='viewport'><title>WLED Welcome!</title>
|
||||
%CSS%body{font-family:var(--cFn),sans-serif;text-align:center;background:linear-gradient(var(--bCol),black);margin:0;background-attachment: fixed;color: var(--tCol);}svg {fill: var(--dCol);}
|
||||
</style></head>
|
||||
<body>
|
||||
<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<symbol id="lnr-smile" viewBox="0 0 1024 1024"><path d="M486.4 1024c-129.922 0-252.067-50.594-343.936-142.464s-142.464-214.014-142.464-343.936c0-129.923 50.595-252.067 142.464-343.936s214.013-142.464 343.936-142.464c129.922 0 252.067 50.595 343.936 142.464s142.464 214.014 142.464 343.936-50.594 252.067-142.464 343.936c-91.869 91.87-214.014 142.464-343.936 142.464zM486.4 102.4c-239.97 0-435.2 195.23-435.2 435.2s195.23 435.2 435.2 435.2 435.2-195.23 435.2-435.2-195.23-435.2-435.2-435.2z"></path><path d="M332.8 409.6c-42.347 0-76.8-34.453-76.8-76.8s34.453-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.453 76.8-76.8 76.8zM332.8 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M640 409.6c-42.349 0-76.8-34.453-76.8-76.8s34.451-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.451 76.8-76.8 76.8zM640 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M486.4 870.4c-183.506 0-332.8-149.294-332.8-332.8 0-14.139 11.462-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 155.275 126.325 281.6 281.6 281.6s281.6-126.325 281.6-281.6c0-14.139 11.461-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 183.506-149.294 332.8-332.8 332.8z"></path></symbol>
|
||||
</defs></svg>
|
||||
<br><br>
|
||||
<svg><use xlink:href="#lnr-smile"></use></svg>
|
||||
<h1>Welcome to WLED!</h1>
|
||||
<h3>Thank you for installing my application!</h3>
|
||||
Take a quick look at the <a href="https://github.com/Aircoookie/WLED/wiki" target="_blank">wiki</a>!<br>
|
||||
If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br>
|
||||
<b>Next steps:</b><br><br>
|
||||
Connect the module to your local WiFi <a href="/settings/wifi">here</a>!<br><br>
|
||||
<i>Just trying this out in AP mode?</i> <a href="/sliders">Here are the controls.</a><br>
|
||||
</body></html>)=====";
|
||||
const char PAGE_welcome[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset=utf-8><meta content='width=device-width' name=viewport><meta name=theme-color content=#333333><title>WLED Setup</title> <style>body{font-family:Verdana,Helvetica,sans-serif;text-align:center;background-color:#333;margin:0;color:#fff}button{outline:0;cursor:pointer}.btn{padding:8px;margin:10px;width:230px;text-transform:uppercase;font-family:helvetica;font-size:19px;background-color:#222;color:white;border:0 solid white;border-radius:5px}svg{fill:#fff}</style></head>
|
||||
<body> <svg style=position:absolute;width:0;height:0;overflow:hidden version=1.1 xmlns=http://www.w3.org/2000/svg> <defs> <symbol id=lnr-smile viewBox="0 0 1024 1024"><path d="M486.4 1024c-129.922 0-252.067-50.594-343.936-142.464s-142.464-214.014-142.464-343.936c0-129.923 50.595-252.067 142.464-343.936s214.013-142.464 343.936-142.464c129.922 0 252.067 50.595 343.936 142.464s142.464 214.014 142.464 343.936-50.594 252.067-142.464 343.936c-91.869 91.87-214.014 142.464-343.936 142.464zM486.4 102.4c-239.97 0-435.2 195.23-435.2 435.2s195.23 435.2 435.2 435.2 435.2-195.23 435.2-435.2-195.23-435.2-435.2-435.2z"></path><path d="M332.8 409.6c-42.347 0-76.8-34.453-76.8-76.8s34.453-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.453 76.8-76.8 76.8zM332.8 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M640 409.6c-42.349 0-76.8-34.453-76.8-76.8s34.451-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.451 76.8-76.8 76.8zM640 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M486.4 870.4c-183.506 0-332.8-149.294-332.8-332.8 0-14.139 11.462-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 155.275 126.325 281.6 281.6 281.6s281.6-126.325 281.6-281.6c0-14.139 11.461-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 183.506-149.294 332.8-332.8 332.8z"></path></symbol> </defs></svg> <br><br>
|
||||
<svg><use xlink:href=#lnr-smile></use></svg><h1>Welcome to WLED!</h1><h3>Thank you for installing my application!</h3> If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br> <b>Next steps:</b><br><br> Connect the module to your local WiFi here!<br> <button class=btn onclick="window.location.href='/settings/wifi'">WiFi settings</button><br> <i>Just trying this out in AP mode?</i><br> <button class=btn onclick="window.location.href='/sliders'">To the controls!</button></body></html>)=====";
|
||||
#else
|
||||
const char PAGE_welcome[] PROGMEM = "";
|
||||
#endif
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Settings html
|
||||
*/
|
||||
|
||||
|
||||
//common CSS of settings pages
|
||||
const char PAGE_settingsCss[] PROGMEM = R"=====(body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:4em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}td{padding:2px;}</style>)=====";
|
||||
|
||||
@@ -28,7 +28,7 @@ const char PAGE_settings_wifi[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
%CSS%%SCSS%</head><body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
|
||||
<h2>WiFi setup</h2>
|
||||
<h3>Connect to existing network</h3>
|
||||
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
|
||||
@@ -50,15 +50,20 @@ Static subnet mask:<br>
|
||||
<input name="S3" type="number" min="0" max="255" required><br>
|
||||
mDNS address (leave empty for no mDNS):<br/>
|
||||
http:// <input name="CM" maxlength="32"> .local<br>
|
||||
Try connecting before opening AP for: <input name="AT" type="number" min="0" max="255" required> s <br>
|
||||
Client IP: <span class="sip"> Not connected </span><br>
|
||||
<h3>Configure Access Point</h3>
|
||||
AP SSID (leave empty for no AP):<br><input name="AS" maxlength="32"><br>
|
||||
Hide AP name: <input type="checkbox" name="AH"><br>
|
||||
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63"><br>
|
||||
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
|
||||
AP opens:
|
||||
<select name="AB">
|
||||
<option value="0">No connection after boot</option>
|
||||
<option value="1">Disconnected</option>
|
||||
<option value="2">Always</option>
|
||||
<option value="3">Never (not recommended)</option></select><br>
|
||||
AP IP: <span class="sip"> Not active </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 & Connect</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>)=====";
|
||||
@@ -80,7 +85,7 @@ el.innerHTML=x;el.selectedIndex=pl?p:f;}).catch(function(){el.innerHTML=e;})}fun
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>LED setup</h2>
|
||||
LED count: <input name="LC" type="number" min="1" max="1200" oninput=UI() required><br>
|
||||
LED count: <input name="LC" type="number" min="1" max="1500" oninput=UI() required><br>
|
||||
<i>Recommended power supply for brightest white:</i><br>
|
||||
<b><span id="psu">?</span></b><br><br>
|
||||
Maximum Current: <input name="MA" type="number" min="250" max="65000" required> mA<br>
|
||||
@@ -252,7 +257,13 @@ For best results, only use one of these services at a time.<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>
|
||||
<h3>MQTT</h3>
|
||||
Broker: <input name="MS" maxlength="32"><br>
|
||||
Broker: <input name="MS" maxlength="32">
|
||||
Port: <input name="MQPORT" type="number" min="1" max="65535" required><br>
|
||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||
Never use the MQTT password for another service!</b><br>
|
||||
Username: <input name="MQUSER" maxlength="40"><br>
|
||||
Password: <input type="password" input name="MQPASS" maxlength="40"><br>
|
||||
Client ID: <input name="MQCID" maxlength="40"><br>
|
||||
Device Topic: <input name="MD" maxlength="32"><br>
|
||||
Group Topic: <input name="MG" maxlength="32"><br>
|
||||
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
||||
@@ -289,7 +300,7 @@ function Wd(){a=[0,0,0,0,0,0,0,0];for(i=0;i<8;i++){m=1;for(j=0;j<8;j++){a[i]+=gI
|
||||
<h2>Time setup</h2>
|
||||
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
||||
Use 24h format: <input type="checkbox" name="CF"><br>
|
||||
Time zone:
|
||||
Time zone:
|
||||
<select name="TZ">
|
||||
<option value="0" selected>GMT(UTC)</option>
|
||||
<option value="1">GMT/BST</option>
|
||||
@@ -384,9 +395,6 @@ The password should be changed when OTA is enabled.<br>
|
||||
<b>Disable OTA when not in use, otherwise an attacker can reflash device software!</b><br>
|
||||
<i>Settings on this page are only changable if OTA lock is disabled!</i><br>
|
||||
Deny access to WiFi settings if locked: <input type="checkbox" name="OW"><br><br>
|
||||
Disable recovery AP: <input type="checkbox" name="NA"><br>
|
||||
In case of an error there will be no wireless recovery possible!<br>
|
||||
Completely disables all Access Point functions.<br><br>
|
||||
Factory reset: <input type="checkbox" name="RS"><br>
|
||||
All EEPROM content (settings) will be erased.<br><br>
|
||||
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
|
||||
@@ -394,7 +402,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
|
||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||
<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.8.6<br><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>
|
||||
(c) 2016-2019 Christian Schwinne <br>
|
||||
|
@@ -529,12 +529,41 @@ DEFINE_GRADIENT_PALETTE( April_Night_gp ) {
|
||||
127, 249,150, 5, //yellow
|
||||
143, 1, 5, 45,
|
||||
162, 1, 5, 45,
|
||||
178, 255,92, 0, //pastel orange
|
||||
178, 255, 92, 0, //pastel orange
|
||||
193, 1, 5, 45,
|
||||
214, 1, 5, 45,
|
||||
229, 223, 45, 72, //pink
|
||||
244, 1, 5, 45,
|
||||
255, 1, 5, 45};
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Orangery_gp ) {
|
||||
0, 255, 95, 23,
|
||||
30, 255, 82, 0,
|
||||
60, 223, 13, 8,
|
||||
90, 144, 44, 2,
|
||||
120, 255,110, 17,
|
||||
150, 255, 69, 0,
|
||||
180, 158, 13, 11,
|
||||
210, 241, 82, 17,
|
||||
255, 213, 37, 4};
|
||||
|
||||
//inspired by Mark Kriegsman https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
|
||||
DEFINE_GRADIENT_PALETTE( C9_gp ) {
|
||||
0, 184, 4, 0, //red
|
||||
60, 184, 4, 0,
|
||||
65, 144, 44, 2, //amber
|
||||
125, 144, 44, 2,
|
||||
130, 4, 96, 2, //green
|
||||
190, 4, 96, 2,
|
||||
195, 7, 7, 88, //blue
|
||||
255, 7, 7, 88};
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Sakura_gp ) {
|
||||
0, 196, 19, 10,
|
||||
65, 255, 69, 45,
|
||||
130, 223, 45, 72,
|
||||
195, 255, 82,103,
|
||||
255, 223, 13, 17};
|
||||
|
||||
|
||||
// Single array of defined cpt-city color palettes.
|
||||
@@ -581,7 +610,10 @@ const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
|
||||
Blue_Cyan_Yellow_gp, //43-30 Yelblu
|
||||
Orange_Teal_gp, //44-31 Orange & Teal
|
||||
Tiamat_gp, //45-32 Tiamat
|
||||
April_Night_gp //46-33 April Night
|
||||
April_Night_gp, //46-33 April Night
|
||||
Orangery_gp, //47-34 Orangery
|
||||
C9_gp, //48-35 C9
|
||||
Sakura_gp, //49-36 Sakura
|
||||
};
|
||||
|
||||
|
||||
|
@@ -38,6 +38,7 @@ AsyncMqttClient::AsyncMqttClient()
|
||||
|
||||
#ifdef ESP32
|
||||
sprintf(_generatedClientId, "esp32%06x", ESP.getEfuseMac());
|
||||
_xSemaphore = xSemaphoreCreateMutex();
|
||||
#elif defined(ESP8266)
|
||||
sprintf(_generatedClientId, "esp8266%06x", ESP.getChipId());
|
||||
#endif
|
||||
@@ -49,6 +50,9 @@ AsyncMqttClient::AsyncMqttClient()
|
||||
AsyncMqttClient::~AsyncMqttClient() {
|
||||
delete _currentParsedPacket;
|
||||
delete[] _parsingInformation.topicBuffer;
|
||||
#ifdef ESP32
|
||||
vSemaphoreDelete(_xSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setKeepAlive(uint16_t keepAlive) {
|
||||
@@ -298,9 +302,11 @@ void AsyncMqttClient::_onConnect(AsyncClient* client) {
|
||||
neededSpace += passwordLength;
|
||||
}
|
||||
|
||||
SEMAPHORE_TAKE();
|
||||
if (_client.space() < neededSpace) {
|
||||
_connectPacketNotEnoughSpace = true;
|
||||
_client.close(true);
|
||||
SEMAPHORE_GIVE();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -329,26 +335,24 @@ void AsyncMqttClient::_onConnect(AsyncClient* client) {
|
||||
}
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
SEMAPHORE_GIVE();
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onDisconnect(AsyncClient* client) {
|
||||
(void)client;
|
||||
AsyncMqttClientDisconnectReason reason;
|
||||
if (!_disconnectFlagged) {
|
||||
AsyncMqttClientDisconnectReason reason;
|
||||
|
||||
if (_connectPacketNotEnoughSpace) {
|
||||
reason = AsyncMqttClientDisconnectReason::ESP8266_NOT_ENOUGH_SPACE;
|
||||
} else if (_tlsBadFingerprint) {
|
||||
reason = AsyncMqttClientDisconnectReason::TLS_BAD_FINGERPRINT;
|
||||
} else {
|
||||
reason = AsyncMqttClientDisconnectReason::TCP_DISCONNECTED;
|
||||
if (_connectPacketNotEnoughSpace) {
|
||||
reason = AsyncMqttClientDisconnectReason::ESP8266_NOT_ENOUGH_SPACE;
|
||||
} else if (_tlsBadFingerprint) {
|
||||
reason = AsyncMqttClientDisconnectReason::TLS_BAD_FINGERPRINT;
|
||||
} else {
|
||||
reason = AsyncMqttClientDisconnectReason::TCP_DISCONNECTED;
|
||||
}
|
||||
for (auto callback : _onDisconnectUserCallbacks) callback(reason);
|
||||
}
|
||||
|
||||
_clear();
|
||||
|
||||
for (auto callback : _onDisconnectUserCallbacks) callback(reason);
|
||||
|
||||
_connectPacketNotEnoughSpace = false;
|
||||
_tlsBadFingerprint = false;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onError(AsyncClient* client, int8_t error) {
|
||||
@@ -481,8 +485,8 @@ void AsyncMqttClient::_onConnAck(bool sessionPresent, uint8_t connectReturnCode)
|
||||
_connected = true;
|
||||
for (auto callback : _onConnectUserCallbacks) callback(sessionPresent);
|
||||
} else {
|
||||
_clear();
|
||||
for (auto callback : _onDisconnectUserCallbacks) callback(static_cast<AsyncMqttClientDisconnectReason>(connectReturnCode));
|
||||
_disconnectFlagged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,19 +610,22 @@ bool AsyncMqttClient::_sendPing() {
|
||||
|
||||
size_t neededSpace = 2;
|
||||
|
||||
if (_client.space() < neededSpace) return false;
|
||||
SEMAPHORE_TAKE(false);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return false; }
|
||||
|
||||
_client.add(fixedHeader, 2);
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
_lastPingRequestTime = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return true;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_sendAcks() {
|
||||
uint8_t neededAckSpace = 2 + 2;
|
||||
|
||||
SEMAPHORE_TAKE();
|
||||
for (size_t i = 0; i < _toSendAcks.size(); i++) {
|
||||
if (_client.space() < neededAckSpace) break;
|
||||
|
||||
@@ -643,12 +650,17 @@ void AsyncMqttClient::_sendAcks() {
|
||||
|
||||
_lastClientActivity = millis();
|
||||
}
|
||||
SEMAPHORE_GIVE();
|
||||
}
|
||||
|
||||
bool AsyncMqttClient::_sendDisconnect() {
|
||||
if (!_connected) return true;
|
||||
|
||||
const uint8_t neededSpace = 2;
|
||||
|
||||
if (_client.space() < neededSpace) return false;
|
||||
SEMAPHORE_TAKE(false);
|
||||
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return false; }
|
||||
|
||||
char fixedHeader[2];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.DISCONNECT;
|
||||
@@ -662,6 +674,7 @@ bool AsyncMqttClient::_sendDisconnect() {
|
||||
|
||||
_disconnectFlagged = false;
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -704,7 +717,6 @@ void AsyncMqttClient::disconnect(bool force) {
|
||||
} else {
|
||||
_disconnectFlagged = true;
|
||||
_sendDisconnect();
|
||||
_client.send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,7 +744,9 @@ uint16_t AsyncMqttClient::subscribe(const char* topic, uint8_t qos) {
|
||||
neededSpace += 2;
|
||||
neededSpace += topicLength;
|
||||
neededSpace += 1;
|
||||
if (_client.space() < neededSpace) return 0;
|
||||
|
||||
SEMAPHORE_TAKE(0);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return 0; }
|
||||
|
||||
uint16_t packetId = _getNextPacketId();
|
||||
char packetIdBytes[2];
|
||||
@@ -747,6 +761,7 @@ uint16_t AsyncMqttClient::subscribe(const char* topic, uint8_t qos) {
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return packetId;
|
||||
}
|
||||
|
||||
@@ -770,7 +785,9 @@ uint16_t AsyncMqttClient::unsubscribe(const char* topic) {
|
||||
neededSpace += 2;
|
||||
neededSpace += 2;
|
||||
neededSpace += topicLength;
|
||||
if (_client.space() < neededSpace) return 0;
|
||||
|
||||
SEMAPHORE_TAKE(0);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return 0; }
|
||||
|
||||
uint16_t packetId = _getNextPacketId();
|
||||
char packetIdBytes[2];
|
||||
@@ -784,6 +801,7 @@ uint16_t AsyncMqttClient::unsubscribe(const char* topic) {
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return packetId;
|
||||
}
|
||||
|
||||
@@ -825,7 +843,9 @@ uint16_t AsyncMqttClient::publish(const char* topic, uint8_t qos, bool retain, c
|
||||
neededSpace += topicLength;
|
||||
if (qos != 0) neededSpace += 2;
|
||||
if (payload != nullptr) neededSpace += payloadLength;
|
||||
if (_client.space() < neededSpace) return 0;
|
||||
|
||||
SEMAPHORE_TAKE(0);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return 0; }
|
||||
|
||||
uint16_t packetId = 0;
|
||||
char packetIdBytes[2];
|
||||
@@ -848,6 +868,7 @@ uint16_t AsyncMqttClient::publish(const char* topic, uint8_t qos, bool retain, c
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
if (qos != 0) {
|
||||
return packetId;
|
||||
} else {
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#ifdef ESP32
|
||||
#include <AsyncTCP.h>
|
||||
#include <freertos/semphr.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <ESPAsyncTCP.h>
|
||||
#else
|
||||
@@ -37,6 +38,14 @@
|
||||
#include "AsyncMqttClient/Packets/PubRecPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PubCompPacket.hpp"
|
||||
|
||||
#if ESP32
|
||||
#define SEMAPHORE_TAKE(X) if (xSemaphoreTake(_xSemaphore, 1000 / portTICK_PERIOD_MS) != pdTRUE) { return X; } // Waits max 1000ms
|
||||
#define SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore);
|
||||
#elif defined(ESP8266)
|
||||
#define SEMAPHORE_TAKE(X) void()
|
||||
#define SEMAPHORE_GIVE() void()
|
||||
#endif
|
||||
|
||||
class AsyncMqttClient {
|
||||
public:
|
||||
AsyncMqttClient();
|
||||
@@ -121,6 +130,10 @@ class AsyncMqttClient {
|
||||
|
||||
std::vector<AsyncMqttClientInternals::PendingAck> _toSendAcks;
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t _xSemaphore = nullptr;
|
||||
#endif
|
||||
|
||||
void _clear();
|
||||
void _freeCurrentParsedPacket();
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
/*
|
||||
* @title Espalexa library
|
||||
* @version 2.4.0
|
||||
* @version 2.4.3
|
||||
* @author Christian Schwinne
|
||||
* @license MIT
|
||||
* @contributors d-999
|
||||
@@ -49,7 +49,7 @@
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
#ifdef ESPALEXA_DEBUG
|
||||
#pragma message "Espalexa 2.4.0 debug mode"
|
||||
#pragma message "Espalexa 2.4.3 debug mode"
|
||||
#define EA_DEBUG(x) Serial.print (x)
|
||||
#define EA_DEBUGLN(x) Serial.println (x)
|
||||
#else
|
||||
@@ -118,14 +118,28 @@ private:
|
||||
case EspalexaDeviceType::color: return "LST001";
|
||||
case EspalexaDeviceType::extendedcolor: return "LCT015";
|
||||
}
|
||||
return "Plug 01";
|
||||
return "Plug";
|
||||
}
|
||||
|
||||
//Workaround functions courtesy of Sonoff-Tasmota
|
||||
uint32_t encodeLightId(uint8_t idx)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
uint32_t id = (mac[3] << 20) | (mac[4] << 12) | (mac[5] << 4) | (idx & 0xF);
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t decodeLightId(uint32_t id) {
|
||||
return id & 0xF;
|
||||
}
|
||||
|
||||
//device JSON string: color+temperature device emulates LCT015, dimmable device LWB010, (TODO: on/off Plug 01, color temperature device LWT010, color device LST001)
|
||||
String deviceJsonString(uint8_t deviceId)
|
||||
{
|
||||
if (deviceId < 1 || deviceId > currentDeviceCount) return "{}"; //error
|
||||
EspalexaDevice* dev = devices[deviceId-1];
|
||||
deviceId--;
|
||||
if (deviceId >= currentDeviceCount) return "{}"; //error
|
||||
EspalexaDevice* dev = devices[deviceId];
|
||||
|
||||
String json = "{\"state\":{\"on\":";
|
||||
json += boolString(dev->getValue());
|
||||
@@ -148,9 +162,9 @@ private:
|
||||
json += "\"type\":\"" + typeString(dev->getType());
|
||||
json += "\",\"name\":\"" + dev->getName();
|
||||
json += "\",\"modelid\":\"" + modelidString(dev->getType());
|
||||
json += "\",\"manufacturername\":\"Espalexa\",\"productname\":\"E" + String(static_cast<uint8_t>(dev->getType()));
|
||||
json += "\",\"uniqueid\":\""+ WiFi.macAddress() +"-"+ (deviceId+1);
|
||||
json += "\",\"swversion\":\"2.4.0\"}";
|
||||
json += "\",\"manufacturername\":\"Philips\",\"productname\":\"E" + String(static_cast<uint8_t>(dev->getType()));
|
||||
json += "\",\"uniqueid\":\"" + String(encodeLightId(deviceId+1));
|
||||
json += "\",\"swversion\":\"espalexa-2.4.3\"}";
|
||||
|
||||
return json;
|
||||
}
|
||||
@@ -174,7 +188,7 @@ private:
|
||||
}
|
||||
res += "\r\nFree Heap: " + (String)ESP.getFreeHeap();
|
||||
res += "\r\nUptime: " + (String)millis();
|
||||
res += "\r\n\r\nEspalexa library v2.4.0 by Christian Schwinne 2019";
|
||||
res += "\r\n\r\nEspalexa library v2.4.3 by Christian Schwinne 2019";
|
||||
server->send(200, "text/plain", res);
|
||||
}
|
||||
#endif
|
||||
@@ -219,15 +233,6 @@ private:
|
||||
"<serialNumber>"+ escapedMac +"</serialNumber>"
|
||||
"<UDN>uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"</UDN>"
|
||||
"<presentationURL>index.html</presentationURL>"
|
||||
"<iconList>"
|
||||
" <icon>"
|
||||
" <mimetype>image/png</mimetype>"
|
||||
" <height>48</height>"
|
||||
" <width>48</width>"
|
||||
" <depth>24</depth>"
|
||||
" <url>hue_logo_0.png</url>"
|
||||
" </icon>"
|
||||
"</iconList>"
|
||||
"</device>"
|
||||
"</root>";
|
||||
|
||||
@@ -386,7 +391,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
//deprecated brightness-only callback
|
||||
//brightness-only callback
|
||||
bool addDevice(String deviceName, BrightnessCallbackFunction callback, uint8_t initialValue = 0)
|
||||
{
|
||||
EA_DEBUG("Constructing device ");
|
||||
@@ -395,6 +400,17 @@ public:
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
|
||||
return addDevice(d);
|
||||
}
|
||||
|
||||
//brightness-only callback
|
||||
bool addDevice(String deviceName, ColorCallbackFunction callback, uint8_t initialValue = 0)
|
||||
{
|
||||
EA_DEBUG("Constructing device ");
|
||||
EA_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
|
||||
return addDevice(d);
|
||||
}
|
||||
|
||||
|
||||
bool addDevice(String deviceName, DeviceCallbackFunction callback, EspalexaDeviceType t = EspalexaDeviceType::dimmable, uint8_t initialValue = 0)
|
||||
{
|
||||
@@ -439,22 +455,27 @@ public:
|
||||
{
|
||||
server->send(200, "application/json", "[{\"success\":true}]"); //short valid response
|
||||
|
||||
int devId = req.substring(req.indexOf("lights")+7).toInt();
|
||||
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
|
||||
EA_DEBUG("ls"); EA_DEBUGLN(devId);
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::none);
|
||||
devId = decodeLightId(devId);
|
||||
EA_DEBUGLN(devId);
|
||||
devId--; //zero-based for devices array
|
||||
if (devId >= currentDeviceCount) return true; //return if invalid ID
|
||||
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::none);
|
||||
|
||||
if (body.indexOf("false")>0) //OFF command
|
||||
{
|
||||
devices[devId-1]->setValue(0);
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::off);
|
||||
devices[devId-1]->doCallback();
|
||||
devices[devId]->setValue(0);
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::off);
|
||||
devices[devId]->doCallback();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (body.indexOf("true") >0) //ON command
|
||||
{
|
||||
devices[devId-1]->setValue(devices[devId-1]->getLastValue());
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::on);
|
||||
devices[devId]->setValue(devices[devId]->getLastValue());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::on);
|
||||
}
|
||||
|
||||
if (body.indexOf("bri") >0) //BRIGHTNESS command
|
||||
@@ -462,35 +483,35 @@ public:
|
||||
uint8_t briL = body.substring(body.indexOf("bri") +5).toInt();
|
||||
if (briL == 255)
|
||||
{
|
||||
devices[devId-1]->setValue(255);
|
||||
devices[devId]->setValue(255);
|
||||
} else {
|
||||
devices[devId-1]->setValue(briL+1);
|
||||
devices[devId]->setValue(briL+1);
|
||||
}
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::bri);
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::bri);
|
||||
}
|
||||
|
||||
if (body.indexOf("xy") >0) //COLOR command (XY mode)
|
||||
{
|
||||
devices[devId-1]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::xy);
|
||||
devices[devId]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::xy);
|
||||
}
|
||||
|
||||
if (body.indexOf("hue") >0) //COLOR command (HS mode)
|
||||
{
|
||||
devices[devId-1]->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::hs);
|
||||
devices[devId]->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::hs);
|
||||
}
|
||||
|
||||
if (body.indexOf("ct") >0) //COLOR TEMP command (white spectrum)
|
||||
{
|
||||
devices[devId-1]->setColor(body.substring(body.indexOf("ct") +4).toInt());
|
||||
devices[devId-1]->setPropertyChanged(EspalexaDeviceProperty::ct);
|
||||
devices[devId]->setColor(body.substring(body.indexOf("ct") +4).toInt());
|
||||
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::ct);
|
||||
}
|
||||
|
||||
devices[devId-1]->doCallback();
|
||||
devices[devId]->doCallback();
|
||||
|
||||
#ifdef ESPALEXA_DEBUG
|
||||
if (devices[devId-1]->getLastChangedProperty() == EspalexaDeviceProperty::none)
|
||||
if (devices[devId]->getLastChangedProperty() == EspalexaDeviceProperty::none)
|
||||
EA_DEBUGLN("STATE REQ WITHOUT BODY (likely Content-Type issue #6)");
|
||||
#endif
|
||||
return true;
|
||||
@@ -508,7 +529,7 @@ public:
|
||||
String jsonTemp = "{";
|
||||
for (int i = 0; i<currentDeviceCount; i++)
|
||||
{
|
||||
jsonTemp += "\"" + String(i+1) + "\":";
|
||||
jsonTemp += "\"" + String(encodeLightId(i+1)) + "\":";
|
||||
jsonTemp += deviceJsonString(i+1);
|
||||
if (i < currentDeviceCount-1) jsonTemp += ",";
|
||||
}
|
||||
@@ -516,7 +537,14 @@ public:
|
||||
server->send(200, "application/json", jsonTemp);
|
||||
} else //client wants one light (devId)
|
||||
{
|
||||
server->send(200, "application/json", deviceJsonString(devId));
|
||||
devId = decodeLightId(devId);
|
||||
EA_DEBUGLN(devId);
|
||||
if (devId > currentDeviceCount)
|
||||
{
|
||||
server->send(200, "application/json", "{}");
|
||||
} else {
|
||||
server->send(200, "application/json", deviceJsonString(devId));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -546,6 +574,13 @@ public:
|
||||
return escapedMac;
|
||||
}
|
||||
|
||||
//convert brightness (0-255) to percentage
|
||||
uint8_t toPercent(uint8_t bri)
|
||||
{
|
||||
uint16_t perc = bri * 100;
|
||||
return perc / 255;
|
||||
}
|
||||
|
||||
~Espalexa(){delete devices;} //note: Espalexa is NOT meant to be destructed
|
||||
};
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
EspalexaDevice::EspalexaDevice(){}
|
||||
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, BrightnessCallbackFunction gnCallback, uint8_t initialValue) { //constructor
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, BrightnessCallbackFunction gnCallback, uint8_t initialValue) { //constructor for dimmable device
|
||||
|
||||
_deviceName = deviceName;
|
||||
_callback = gnCallback;
|
||||
@@ -13,12 +13,21 @@ EspalexaDevice::EspalexaDevice(String deviceName, BrightnessCallbackFunction gnC
|
||||
_type = EspalexaDeviceType::dimmable;
|
||||
}
|
||||
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, DeviceCallbackFunction gnCallback, EspalexaDeviceType t, uint8_t initialValue) { //constructor for color device
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, ColorCallbackFunction gnCallback, uint8_t initialValue) { //constructor for color device
|
||||
|
||||
_deviceName = deviceName;
|
||||
_callbackCol = gnCallback;
|
||||
_val = initialValue;
|
||||
_val_last = _val;
|
||||
_type = EspalexaDeviceType::extendedcolor;
|
||||
}
|
||||
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, DeviceCallbackFunction gnCallback, EspalexaDeviceType t, uint8_t initialValue) { //constructor for general device
|
||||
|
||||
_deviceName = deviceName;
|
||||
_callbackDev = gnCallback;
|
||||
_callback = nullptr;
|
||||
_type = t;
|
||||
if (t == EspalexaDeviceType::onoff) _type = EspalexaDeviceType::dimmable; //on/off is broken, so make dimmable device instead
|
||||
_val = initialValue;
|
||||
_val_last = _val;
|
||||
}
|
||||
@@ -305,5 +314,7 @@ void EspalexaDevice::setColor(uint8_t r, uint8_t g, uint8_t b)
|
||||
|
||||
void EspalexaDevice::doCallback()
|
||||
{
|
||||
(_callback != nullptr) ? _callback(_val) : _callbackDev(this);
|
||||
if (_callback != nullptr) {_callback(_val); return;}
|
||||
if (_callbackDev != nullptr) {_callbackDev(this); return;}
|
||||
if (_callbackCol != nullptr) _callbackCol(_val, getRGB());
|
||||
}
|
@@ -7,6 +7,7 @@ typedef class EspalexaDevice;
|
||||
|
||||
typedef void (*BrightnessCallbackFunction) (uint8_t b);
|
||||
typedef void (*DeviceCallbackFunction) (EspalexaDevice* d);
|
||||
typedef void (*ColorCallbackFunction) (uint8_t br, uint32_t col);
|
||||
|
||||
enum class EspalexaColorMode : uint8_t { none = 0, ct = 1, hs = 2, xy = 3 };
|
||||
enum class EspalexaDeviceType : uint8_t { onoff = 0, dimmable = 1, whitespectrum = 2, color = 3, extendedcolor = 4 };
|
||||
@@ -15,22 +16,24 @@ enum class EspalexaDeviceProperty : uint8_t { none = 0, on = 1, off = 2, bri = 3
|
||||
class EspalexaDevice {
|
||||
private:
|
||||
String _deviceName;
|
||||
BrightnessCallbackFunction _callback;
|
||||
DeviceCallbackFunction _callbackDev;
|
||||
BrightnessCallbackFunction _callback = nullptr;
|
||||
DeviceCallbackFunction _callbackDev = nullptr;
|
||||
ColorCallbackFunction _callbackCol = nullptr;
|
||||
uint8_t _val, _val_last, _sat = 0;
|
||||
uint16_t _hue = 0, _ct = 0;
|
||||
float _x = 0, _y = 0;
|
||||
float _x = 0.5, _y = 0.5;
|
||||
uint32_t _rgb = 0;
|
||||
uint8_t _id = 0;
|
||||
EspalexaDeviceType _type;
|
||||
EspalexaDeviceProperty _changed = EspalexaDeviceProperty::none;
|
||||
EspalexaColorMode _mode;
|
||||
EspalexaColorMode _mode = EspalexaColorMode::xy;
|
||||
|
||||
public:
|
||||
EspalexaDevice();
|
||||
~EspalexaDevice();
|
||||
EspalexaDevice(String deviceName, BrightnessCallbackFunction bcb, uint8_t initialValue =0);
|
||||
EspalexaDevice(String deviceName, DeviceCallbackFunction dcb, EspalexaDeviceType t =EspalexaDeviceType::dimmable, uint8_t initialValue =0);
|
||||
EspalexaDevice(String deviceName, ColorCallbackFunction ccb, uint8_t initialValue =0);
|
||||
|
||||
String getName();
|
||||
uint8_t getId();
|
||||
|
File diff suppressed because it is too large
Load Diff
5663
wled00/src/dependencies/json/ArduinoJson-v6.h
Normal file
5663
wled00/src/dependencies/json/ArduinoJson-v6.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
// AsyncJson.h
|
||||
// AsyncJson-v6.h
|
||||
/*
|
||||
Original file at: https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/src/AsyncJson.h
|
||||
Original file at: https://github.com/baggior/ESPAsyncWebServer/blob/master/src/AsyncJson.h
|
||||
Only changes are ArduinoJson lib path and removed content-type check
|
||||
|
||||
Async Response to use with ArduinoJson and AsyncWebServer
|
||||
@@ -12,9 +12,12 @@
|
||||
*/
|
||||
#ifndef ASYNC_JSON_H_
|
||||
#define ASYNC_JSON_H_
|
||||
#include "ArduinoJson-v5.h"
|
||||
#include "ArduinoJson-v6.h"
|
||||
#include <Print.h>
|
||||
|
||||
constexpr char* JSON_MIMETYPE = "application/json";
|
||||
#define DYNAMYC_JSON_DOCUMENT_SIZE 4096
|
||||
|
||||
constexpr const char* JSON_MIMETYPE = "application/json";
|
||||
|
||||
/*
|
||||
* Json Response
|
||||
@@ -41,27 +44,38 @@ class ChunkPrint : public Print {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
size_t write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
return this->Print::write(buffer, size);
|
||||
}
|
||||
};
|
||||
|
||||
class AsyncJsonResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
DynamicJsonBuffer _jsonBuffer;
|
||||
|
||||
DynamicJsonDocument _jsonBuffer;
|
||||
|
||||
JsonVariant _root;
|
||||
bool _isValid;
|
||||
public:
|
||||
AsyncJsonResponse(bool isArray=false): _isValid{false} {
|
||||
|
||||
public:
|
||||
|
||||
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMYC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
||||
_code = 200;
|
||||
_contentType = JSON_MIMETYPE;
|
||||
if(isArray)
|
||||
_root = _jsonBuffer.createArray();
|
||||
_root = _jsonBuffer.createNestedArray();
|
||||
else
|
||||
_root = _jsonBuffer.createObject();
|
||||
_root = _jsonBuffer.createNestedObject();
|
||||
}
|
||||
|
||||
~AsyncJsonResponse() {}
|
||||
JsonVariant & getRoot() { return _root; }
|
||||
bool _sourceValid() const { return _isValid; }
|
||||
size_t setLength() {
|
||||
_contentLength = _root.measureLength();
|
||||
|
||||
_contentLength = measureJson(_root);
|
||||
|
||||
if (_contentLength) { _isValid = true; }
|
||||
return _contentLength;
|
||||
}
|
||||
@@ -70,12 +84,13 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
||||
|
||||
size_t _fillBuffer(uint8_t *data, size_t len){
|
||||
ChunkPrint dest(data, _sentLength, len);
|
||||
_root.printTo( dest ) ;
|
||||
|
||||
serializeJson(_root, dest);
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest *request, JsonVariant &json)> ArJsonRequestHandlerFunction;
|
||||
typedef std::function<void(AsyncWebServerRequest *request, JsonObject json)> ArJsonRequestHandlerFunction;
|
||||
|
||||
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
||||
private:
|
||||
@@ -84,9 +99,13 @@ protected:
|
||||
WebRequestMethodComposite _method;
|
||||
ArJsonRequestHandlerFunction _onRequest;
|
||||
int _contentLength;
|
||||
const size_t maxJsonBufferSize;
|
||||
int _maxContentLength;
|
||||
public:
|
||||
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {}
|
||||
|
||||
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMYC_JSON_DOCUMENT_SIZE)
|
||||
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
|
||||
|
||||
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
||||
void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; }
|
||||
void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; }
|
||||
@@ -108,14 +127,17 @@ public:
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||
if(_onRequest) {
|
||||
if (request->_tempObject != NULL) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject));
|
||||
if (json.success()) {
|
||||
|
||||
DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize);
|
||||
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, "{\"error\":\"Empty body\"}");
|
||||
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
||||
} else {
|
||||
request->send(500);
|
||||
}
|
@@ -3,12 +3,12 @@
|
||||
*/
|
||||
/*
|
||||
* @title WLED project sketch
|
||||
* @version 0.8.4
|
||||
* @version 0.8.6
|
||||
* @author Christian Schwinne
|
||||
*/
|
||||
|
||||
|
||||
//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
|
||||
//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS).
|
||||
|
||||
//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS).
|
||||
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
|
||||
@@ -35,15 +35,16 @@
|
||||
|
||||
//library inclusions
|
||||
#include <Arduino.h>
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include "SPIFFS.h"
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <ESPAsyncTCP.h>
|
||||
#else
|
||||
#include <WiFi.h>
|
||||
#include "esp_wifi.h"
|
||||
#include <ESPmDNS.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include "SPIFFS.h"
|
||||
#endif
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
@@ -61,6 +62,7 @@
|
||||
#define ESPALEXA_ASYNC
|
||||
#define ESPALEXA_NO_SUBPAGE
|
||||
#define ESPALEXA_MAXDEVICES 1
|
||||
//#define ESPALEXA_DEBUG
|
||||
#include "src/dependencies/espalexa/Espalexa.h"
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
@@ -68,13 +70,13 @@
|
||||
#endif
|
||||
#include "src/dependencies/e131/E131.h"
|
||||
#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h"
|
||||
#include "src/dependencies/json/AsyncJson.h"
|
||||
#include "src/dependencies/json/ArduinoJson-v5.h"
|
||||
#include "src/dependencies/json/AsyncJson-v6.h"
|
||||
#include "src/dependencies/json/ArduinoJson-v6.h"
|
||||
#include "html_classic.h"
|
||||
#include "html_mobile.h"
|
||||
#include "html_settings.h"
|
||||
#include "html_other.h"
|
||||
#include "WS2812FX.h"
|
||||
#include "FX.h"
|
||||
#include "ir_codes.h"
|
||||
|
||||
|
||||
@@ -98,8 +100,8 @@
|
||||
|
||||
|
||||
//version code in format yymmddb (b = daily build)
|
||||
#define VERSION 1903252
|
||||
char versionString[] = "0.8.4";
|
||||
#define VERSION 1910255
|
||||
char versionString[] = "0.8.6";
|
||||
|
||||
|
||||
//AP and OTA default passwords (for maximum change them!)
|
||||
@@ -122,47 +124,45 @@ char cmDNS[33] = "x"; //mDNS address (placeholder, will
|
||||
char apSSID[33] = ""; //AP off by default (unless setup)
|
||||
byte apChannel = 1; //2.4GHz WiFi AP channel (1-13)
|
||||
byte apHide = 0; //hidden AP SSID
|
||||
byte apWaitTimeSecs = 32; //time to wait for connection before opening AP
|
||||
bool recoveryAPDisabled = false; //never open AP (not recommended)
|
||||
//byte apWaitTimeSecs = 32; //time to wait for connection before opening AP
|
||||
byte apBehavior = 0; //0: Open AP when no connection after boot 1: Open when no connection 2: Always open 3: Only when button pressed for 6 sec
|
||||
//bool recoveryAPDisabled = false; //never open AP (not recommended)
|
||||
IPAddress staticIP(0, 0, 0, 0); //static IP of ESP
|
||||
IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP
|
||||
IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks
|
||||
|
||||
//LED CONFIG
|
||||
uint16_t ledCount = 30; //overcurrent prevented by ABL
|
||||
uint16_t ledCount = 30; //overcurrent prevented by ABL
|
||||
bool useRGBW = false; //SK6812 strips can contain an extra White channel
|
||||
bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB
|
||||
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
|
||||
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
|
||||
bool turnOnAtBoot = true; //turn on LEDs at power-up
|
||||
byte bootPreset = 0; //save preset to load after power-up
|
||||
|
||||
byte colS[]{255, 159, 0, 0}; //default RGB(W) color
|
||||
byte colSecS[]{0, 0, 0, 0}; //default RGB(W) secondary color
|
||||
byte briS = 127; //default brightness
|
||||
byte effectDefault = 0;
|
||||
byte effectDefault = 0;
|
||||
byte effectSpeedDefault = 75;
|
||||
byte effectIntensityDefault = 128; //intensity is supported on some effects as an additional parameter (e.g. for blink you can change the duty cycle)
|
||||
byte effectPaletteDefault = 0; //palette is supported on the FastLED effects, otherwise it has no effect
|
||||
|
||||
bool useGammaCorrectionBri = false; //gamma correct brightness (not recommended)
|
||||
bool useGammaCorrectionRGB = true; //gamma correct colors (strongly recommended)
|
||||
|
||||
byte nightlightTargetBri = 0; //brightness after nightlight is over
|
||||
byte nightlightDelayMins = 60;
|
||||
bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over
|
||||
bool fadeTransition = true; //enable crossfading color transition
|
||||
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 reverseMode = false; //flip entire LED strip (reverses all effect directions)
|
||||
//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)
|
||||
byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)
|
||||
|
||||
|
||||
//User Interface CONFIG
|
||||
char serverDescription[33] = "WLED Light"; //Name of module
|
||||
char serverDescription[33] = "WLED"; //Name of module
|
||||
byte currentTheme = 7; //UI theme index for settings and classic UI
|
||||
byte uiConfiguration = 0; //0: automatic (depends on user-agent) 1: classic UI 2: mobile UI
|
||||
byte uiConfiguration = 2; //0: automatic (depends on user-agent) 1: classic UI 2: mobile UI
|
||||
bool useHSB = true; //classic UI: use HSB sliders instead of RGB by default
|
||||
char cssFont[33] = "Verdana"; //font to use in classic UI
|
||||
|
||||
@@ -204,6 +204,10 @@ bool e131Multicast = false;
|
||||
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 mqttServer[33] = ""; //both domains and IPs should work (no SSL)
|
||||
char mqttUser[41] = ""; //optional: username for MQTT auth
|
||||
char mqttPass[41] = ""; //optional: password for MQTT auth
|
||||
char mqttClientID[41] = ""; //override the client ID
|
||||
uint16_t mqttPort = 1883;
|
||||
|
||||
bool huePollingEnabled = false; //poll hue bridge for light state
|
||||
uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response
|
||||
@@ -239,7 +243,7 @@ byte countdownMin = 0, countdownSec = 0;
|
||||
|
||||
byte macroBoot = 0; //macro loaded after startup
|
||||
byte macroNl = 0; //after nightlight delay over
|
||||
byte macroCountdown = 0;
|
||||
byte macroCountdown = 0;
|
||||
byte macroAlexaOn = 0, macroAlexaOff = 0;
|
||||
byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0;
|
||||
|
||||
@@ -254,6 +258,13 @@ uint16_t userVar0 = 0, userVar1 = 0;
|
||||
|
||||
|
||||
//internal global variable declarations
|
||||
//wifi
|
||||
bool apActive = false;
|
||||
bool forceReconnect = false;
|
||||
uint32_t lastReconnectAttempt = 0;
|
||||
bool interfacesInited = false;
|
||||
bool wasConnected = false;
|
||||
|
||||
//color
|
||||
byte col[]{255, 159, 0, 0}; //target RGB(W) color
|
||||
byte colOld[]{0, 0, 0, 0}; //color before transition
|
||||
@@ -292,6 +303,7 @@ byte briLast = 127; //brightness before turned off. Us
|
||||
|
||||
//button
|
||||
bool buttonPressedBefore = false;
|
||||
bool buttonLongPressed = false;
|
||||
unsigned long buttonPressedTime = 0;
|
||||
unsigned long buttonWaitTime = 0;
|
||||
|
||||
@@ -309,7 +321,6 @@ byte effectIntensity = effectIntensityDefault;
|
||||
byte effectPalette = effectPaletteDefault;
|
||||
|
||||
//network
|
||||
bool onlyAP = false; //only Access Point active, no connection to home network
|
||||
bool udpConnected = false, udpRgbConnected = false;
|
||||
|
||||
//ui style
|
||||
@@ -326,8 +337,6 @@ unsigned long hueLastRequestSent = 0;
|
||||
bool hueAuthRequired = false;
|
||||
bool hueReceived = false;
|
||||
bool hueStoreAllowed = false, hueNewKey = false;
|
||||
//unsigned long huePollIntervalMsTemp = huePollIntervalMs;
|
||||
//bool hueAttempt = false;
|
||||
|
||||
//overlays
|
||||
byte overlayCurrent = overlayDefault;
|
||||
@@ -373,10 +382,9 @@ IPAddress realtimeIP = (0,0,0,0);
|
||||
unsigned long realtimeTimeout = 0;
|
||||
|
||||
//mqtt
|
||||
long lastMQTTReconnectAttempt = 0;
|
||||
long lastMqttReconnectAttempt = 0;
|
||||
long lastInterfaceUpdate = 0;
|
||||
byte interfaceUpdateCallMode = 0;
|
||||
uint32_t mqttFailedConAttempts = 0;
|
||||
|
||||
#if AUXPIN >= 0
|
||||
//auxiliary debug pin
|
||||
@@ -394,7 +402,6 @@ EspalexaDevice* espalexaDevice;
|
||||
|
||||
//dns server
|
||||
DNSServer dnsServer;
|
||||
bool dnsActive = false;
|
||||
|
||||
//network time
|
||||
bool ntpConnected = false;
|
||||
@@ -405,6 +412,9 @@ IPAddress ntpServerIP;
|
||||
unsigned int ntpLocalPort = 2390;
|
||||
#define NTP_PACKET_SIZE 48
|
||||
|
||||
#define MAX_LEDS 1500
|
||||
#define MAX_LEDS_DMA 500
|
||||
|
||||
//string temp buffer (now stored in stack locally)
|
||||
#define OMAX 2048
|
||||
char* obuf;
|
||||
@@ -414,6 +424,8 @@ String messageHead, messageSub;
|
||||
byte optionType;
|
||||
|
||||
bool doReboot = false; //flag to initiate reboot from async handlers
|
||||
bool doPublishMqtt = false;
|
||||
bool doSendHADiscovery = true;
|
||||
|
||||
//server library objects
|
||||
AsyncWebServer server(80);
|
||||
@@ -428,6 +440,9 @@ E131* e131;
|
||||
//led fx library object
|
||||
WS2812FX strip = WS2812FX();
|
||||
|
||||
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
|
||||
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,"Your_Network") != 0)
|
||||
|
||||
//debug macros
|
||||
#ifdef WLED_DEBUG
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
@@ -436,6 +451,7 @@ WS2812FX strip = WS2812FX();
|
||||
unsigned long debugTime = 0;
|
||||
int lastWifiState = 3;
|
||||
unsigned long wifiStateChangedTime = 0;
|
||||
int loops = 0;
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
@@ -451,24 +467,6 @@ WS2812FX strip = WS2812FX();
|
||||
#include "SPIFFSEditor.h"
|
||||
#endif
|
||||
|
||||
//gamma 2.4 lookup table used for color correction
|
||||
const byte gamma8[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
||||
//function prototypes
|
||||
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);
|
||||
@@ -503,7 +501,7 @@ bool oappend(char* txt)
|
||||
//append new number to temp buffer efficiently
|
||||
bool oappendi(int i)
|
||||
{
|
||||
char s[11];
|
||||
char s[11];
|
||||
sprintf(s,"%ld", i);
|
||||
return oappend(s);
|
||||
}
|
||||
@@ -517,38 +515,41 @@ void setup() {
|
||||
|
||||
//main program loop
|
||||
void loop() {
|
||||
handleConnection();
|
||||
handleSerial();
|
||||
handleNotifications();
|
||||
handleTransitions();
|
||||
userLoop();
|
||||
|
||||
|
||||
yield();
|
||||
handleIO();
|
||||
handleIR();
|
||||
handleNetworkTime();
|
||||
if (!onlyAP) handleAlexa();
|
||||
|
||||
handleOverlays();
|
||||
handleAlexa();
|
||||
|
||||
handleOverlays();
|
||||
if (doSendHADiscovery) sendHADiscoveryMQTT();
|
||||
yield();
|
||||
if (doReboot) reset();
|
||||
|
||||
|
||||
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
|
||||
{
|
||||
if (dnsActive) dnsServer.processNextRequest();
|
||||
if (apActive) dnsServer.processNextRequest();
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
if (aOtaEnabled) ArduinoOTA.handle();
|
||||
if (WLED_CONNECTED && aOtaEnabled) ArduinoOTA.handle();
|
||||
#endif
|
||||
handleNightlight();
|
||||
yield();
|
||||
if (!onlyAP) {
|
||||
handleHue();
|
||||
handleBlynk();
|
||||
}
|
||||
|
||||
handleHue();
|
||||
handleBlynk();
|
||||
|
||||
yield();
|
||||
if (!offMode) strip.service();
|
||||
}
|
||||
|
||||
yield();
|
||||
if (millis() - lastMqttReconnectAttempt > 30000) initMqtt();
|
||||
|
||||
//DEBUG serial logging
|
||||
#ifdef WLED_DEBUG
|
||||
if (millis() - debugTime > 9999)
|
||||
@@ -566,7 +567,10 @@ void loop() {
|
||||
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
|
||||
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
|
||||
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
|
||||
debugTime = millis();
|
||||
DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops/10);
|
||||
loops = 0;
|
||||
debugTime = millis();
|
||||
}
|
||||
loops++;
|
||||
#endif
|
||||
}
|
||||
|
367
wled00/wled00.vcxproj
Normal file
367
wled00/wled00.vcxproj
Normal file
File diff suppressed because one or more lines are too long
272
wled00/wled00.vcxproj.filters
Normal file
272
wled00/wled00.vcxproj.filters
Normal file
@@ -0,0 +1,272 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="wled00.ino" />
|
||||
<None Include="wled01_eeprom.ino" />
|
||||
<None Include="wled02_xml.ino" />
|
||||
<None Include="wled03_set.ino" />
|
||||
<None Include="wled04_file.ino" />
|
||||
<None Include="wled05_init.ino" />
|
||||
<None Include="wled06_usermod.ino" />
|
||||
<None Include="wled07_notify.ino" />
|
||||
<None Include="wled08_led.ino" />
|
||||
<None Include="wled09_button.ino" />
|
||||
<None Include="wled10_ntp.ino" />
|
||||
<None Include="wled11_ol.ino" />
|
||||
<None Include="wled12_alexa.ino" />
|
||||
<None Include="wled13_cronixie.ino" />
|
||||
<None Include="wled14_colors.ino" />
|
||||
<None Include="wled15_hue.ino" />
|
||||
<None Include="wled16_blynk.ino" />
|
||||
<None Include="wled17_mqtt.ino" />
|
||||
<None Include="wled18_server.ino" />
|
||||
<None Include="wled19_json.ino" />
|
||||
<None Include="wled20_ir.ino" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="__vm\.wled00.vsarduino.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="html_classic.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="html_mobile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="html_other.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="html_settings.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ir_codes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NpbWrapper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="palettes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WS2812FX.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Callbacks.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\DisconnectReasons.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Flags.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Helpers.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\MessageProperties.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\ParsingInformation.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Storage.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\ConnAckPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\Packet.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PingRespPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubAckPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubCompPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PublishPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubRecPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubRelPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\SubAckPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\UnsubAckPacket.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\BlynkSimpleEsp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkApi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkApiArduino.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkArduinoClient.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkConfig.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkDateTime.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkDebug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkDetectDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkEveryN.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkFifo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkHandlers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkParam.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkProtocol.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkProtocolDefs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkTemplates.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkTimer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkUtility.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkWidgetBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkWiFiCommon.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\e131\E131.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\espalexa\Espalexa.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\espalexa\EspalexaDevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\json\ArduinoJson-v6.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\json\AsyncJson-v6.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\time\Time.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\time\TimeLib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\dependencies\timezone\Timezone.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="WS2812FX.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WS2812FX_fcn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\ConnAckPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PingRespPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubAckPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubCompPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PublishPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubRecPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\PubRelPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\SubAckPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient\Packets\UnsubAckPacket.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\blynk\Blynk\BlynkDebug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\blynk\Blynk\BlynkHandlers.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\blynk\Blynk\BlynkTimer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\blynk\Blynk\utility.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\e131\E131.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\espalexa\EspalexaDevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\time\DateStrings.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\time\Time.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dependencies\timezone\Timezone.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
4
wled00/wled00.vcxproj.user
Normal file
4
wled00/wled00.vcxproj.user
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
@@ -6,7 +6,7 @@
|
||||
#define EEPSIZE 2560
|
||||
|
||||
//eeprom Version code, enables default settings instead of 0 init on update
|
||||
#define EEPVER 10
|
||||
#define EEPVER 11
|
||||
//0 -> old version, default
|
||||
//1 -> 0.4p 1711272 and up
|
||||
//2 -> 0.4p 1711302 and up
|
||||
@@ -18,6 +18,7 @@
|
||||
//8 -> 0.8.0-a and up
|
||||
//9 -> 0.8.0
|
||||
//10-> 0.8.2
|
||||
//11-> 0.8.5-dev #mqttauth @TimothyBrown
|
||||
|
||||
|
||||
/*
|
||||
@@ -64,7 +65,7 @@ void saveSettingsToEEPROM()
|
||||
clearEEPROM();
|
||||
EEPROM.write(233, 233);
|
||||
}
|
||||
|
||||
|
||||
writeStringToEEPROM( 0, clientSSID, 32);
|
||||
writeStringToEEPROM( 32, clientPass, 64);
|
||||
writeStringToEEPROM( 96, cmDNS, 32);
|
||||
@@ -81,50 +82,50 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(231, notifyTwice);
|
||||
EEPROM.write(232, buttonEnabled);
|
||||
//233 reserved for first boot flag
|
||||
|
||||
|
||||
for (int i = 0; i<4; i++) //ip addresses
|
||||
{
|
||||
EEPROM.write(234+i, staticIP[i]);
|
||||
EEPROM.write(238+i, staticGateway[i]);
|
||||
EEPROM.write(242+i, staticSubnet[i]);
|
||||
}
|
||||
|
||||
|
||||
EEPROM.write(246, colS[0]);
|
||||
EEPROM.write(247, colS[1]);
|
||||
EEPROM.write(248, colS[2]);
|
||||
EEPROM.write(249, briS);
|
||||
|
||||
|
||||
EEPROM.write(250, receiveNotificationBrightness);
|
||||
EEPROM.write(251, fadeTransition);
|
||||
EEPROM.write(252, reverseMode);
|
||||
EEPROM.write(252, strip.reverseMode);
|
||||
EEPROM.write(253, transitionDelayDefault & 0xFF);
|
||||
EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF);
|
||||
EEPROM.write(255, briMultiplier);
|
||||
|
||||
|
||||
//255,250,231,230,226 notifier bytes
|
||||
writeStringToEEPROM(256, otaPass, 32);
|
||||
|
||||
|
||||
EEPROM.write(288, nightlightTargetBri);
|
||||
EEPROM.write(289, otaLock);
|
||||
EEPROM.write(290, udpPort & 0xFF);
|
||||
EEPROM.write(291, (udpPort >> 8) & 0xFF);
|
||||
writeStringToEEPROM(292, serverDescription, 32);
|
||||
|
||||
|
||||
EEPROM.write(324, effectDefault);
|
||||
EEPROM.write(325, effectSpeedDefault);
|
||||
EEPROM.write(326, effectIntensityDefault);
|
||||
|
||||
|
||||
EEPROM.write(327, ntpEnabled);
|
||||
EEPROM.write(328, currentTimezone);
|
||||
EEPROM.write(329, useAMPM);
|
||||
EEPROM.write(330, useGammaCorrectionBri);
|
||||
EEPROM.write(331, useGammaCorrectionRGB);
|
||||
EEPROM.write(330, strip.gammaCorrectBri);
|
||||
EEPROM.write(331, strip.gammaCorrectCol);
|
||||
EEPROM.write(332, overlayDefault);
|
||||
|
||||
|
||||
EEPROM.write(333, alexaEnabled);
|
||||
writeStringToEEPROM(334, alexaInvocationName, 32);
|
||||
EEPROM.write(366, notifyAlexa);
|
||||
|
||||
|
||||
EEPROM.write(367, (arlsOffset>=0));
|
||||
EEPROM.write(368, abs(arlsOffset));
|
||||
EEPROM.write(369, turnOnAtBoot);
|
||||
@@ -133,11 +134,11 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(372, useRGBW);
|
||||
EEPROM.write(373, effectPaletteDefault);
|
||||
EEPROM.write(374, strip.paletteFade);
|
||||
EEPROM.write(375, apWaitTimeSecs);
|
||||
EEPROM.write(376, recoveryAPDisabled);
|
||||
|
||||
//EEPROM.write(375, apWaitTimeSecs);
|
||||
EEPROM.write(376, apBehavior);
|
||||
|
||||
EEPROM.write(377, EEPVER); //eeprom was updated to latest
|
||||
|
||||
|
||||
EEPROM.write(378, colSecS[0]);
|
||||
EEPROM.write(379, colSecS[1]);
|
||||
EEPROM.write(380, colSecS[2]);
|
||||
@@ -154,7 +155,7 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(391, receiveNotificationColor);
|
||||
EEPROM.write(392, receiveNotificationEffects);
|
||||
EEPROM.write(393, wifiLock);
|
||||
|
||||
|
||||
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
|
||||
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
||||
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
||||
@@ -193,7 +194,7 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(2152, analogClock12pixel);
|
||||
EEPROM.write(2153, analogClock5MinuteMarks);
|
||||
EEPROM.write(2154, analogClockSecondsTrail);
|
||||
|
||||
|
||||
EEPROM.write(2155, countdownMode);
|
||||
EEPROM.write(2156, countdownYear);
|
||||
EEPROM.write(2157, countdownMonth);
|
||||
@@ -206,7 +207,7 @@ void saveSettingsToEEPROM()
|
||||
writeStringToEEPROM(2165, cronixieDisplay, 6);
|
||||
EEPROM.write(2171, cronixieBacklight);
|
||||
setCronixie();
|
||||
|
||||
|
||||
EEPROM.write(2175, macroBoot);
|
||||
EEPROM.write(2176, macroAlexaOn);
|
||||
EEPROM.write(2177, macroAlexaOff);
|
||||
@@ -253,10 +254,15 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(2290 + i, timerMacro[i] );
|
||||
}
|
||||
|
||||
writeStringToEEPROM(2300, mqttServer, 32);
|
||||
writeStringToEEPROM(2300, mqttServer, 32);
|
||||
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
|
||||
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
||||
|
||||
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
||||
writeStringToEEPROM(2399, mqttUser, 40);
|
||||
writeStringToEEPROM(2440, mqttPass, 40);
|
||||
writeStringToEEPROM(2481, mqttClientID, 40);
|
||||
EEPROM.write(2522, mqttPort & 0xFF);
|
||||
EEPROM.write(2523, (mqttPort >> 8) & 0xFF);
|
||||
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
@@ -274,7 +280,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
return;
|
||||
}
|
||||
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
|
||||
|
||||
|
||||
|
||||
readStringFromEEPROM( 0, clientSSID, 32);
|
||||
readStringFromEEPROM( 32, clientPass, 64);
|
||||
@@ -287,17 +293,17 @@ void loadSettingsFromEEPROM(bool first)
|
||||
nightlightFade = EEPROM.read(225);
|
||||
notifyDirectDefault = EEPROM.read(226);
|
||||
notifyDirect = notifyDirectDefault;
|
||||
|
||||
|
||||
apChannel = EEPROM.read(227);
|
||||
if (apChannel > 13 || apChannel < 1) apChannel = 1;
|
||||
apHide = EEPROM.read(228);
|
||||
if (apHide > 1) apHide = 1;
|
||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 30;
|
||||
|
||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30;
|
||||
|
||||
notifyButton = EEPROM.read(230);
|
||||
notifyTwice = EEPROM.read(231);
|
||||
buttonEnabled = EEPROM.read(232);
|
||||
|
||||
|
||||
staticIP[0] = EEPROM.read(234);
|
||||
staticIP[1] = EEPROM.read(235);
|
||||
staticIP[2] = EEPROM.read(236);
|
||||
@@ -310,7 +316,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
staticSubnet[1] = EEPROM.read(243);
|
||||
staticSubnet[2] = EEPROM.read(244);
|
||||
staticSubnet[3] = EEPROM.read(245);
|
||||
|
||||
|
||||
colS[0] = EEPROM.read(246); col[0] = colS[0];
|
||||
colS[1] = EEPROM.read(247); col[1] = colS[1];
|
||||
colS[2] = EEPROM.read(248); col[2] = colS[2];
|
||||
@@ -321,33 +327,33 @@ void loadSettingsFromEEPROM(bool first)
|
||||
}
|
||||
receiveNotificationBrightness = EEPROM.read(250);
|
||||
fadeTransition = EEPROM.read(251);
|
||||
reverseMode = EEPROM.read(252);
|
||||
strip.reverseMode = EEPROM.read(252);
|
||||
transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00);
|
||||
transitionDelay = transitionDelayDefault;
|
||||
briMultiplier = EEPROM.read(255);
|
||||
|
||||
readStringFromEEPROM(256, otaPass, 32);
|
||||
|
||||
|
||||
nightlightTargetBri = EEPROM.read(288);
|
||||
otaLock = EEPROM.read(289);
|
||||
udpPort = EEPROM.read(290) + ((EEPROM.read(291) << 8) & 0xFF00);
|
||||
|
||||
readStringFromEEPROM(292, serverDescription, 32);
|
||||
|
||||
|
||||
effectDefault = EEPROM.read(324); effectCurrent = effectDefault;
|
||||
effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault;
|
||||
ntpEnabled = EEPROM.read(327);
|
||||
currentTimezone = EEPROM.read(328);
|
||||
useAMPM = EEPROM.read(329);
|
||||
useGammaCorrectionBri = EEPROM.read(330);
|
||||
useGammaCorrectionRGB = EEPROM.read(331);
|
||||
strip.gammaCorrectBri = EEPROM.read(330);
|
||||
strip.gammaCorrectCol = EEPROM.read(331);
|
||||
overlayDefault = EEPROM.read(332);
|
||||
if (lastEEPROMversion < 8 && overlayDefault > 0) overlayDefault--; //overlay mode 1 (solid) was removed
|
||||
|
||||
|
||||
alexaEnabled = EEPROM.read(333);
|
||||
|
||||
readStringFromEEPROM(334, alexaInvocationName, 32);
|
||||
|
||||
|
||||
notifyAlexa = EEPROM.read(366);
|
||||
arlsOffset = EEPROM.read(368);
|
||||
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
|
||||
@@ -358,9 +364,9 @@ void loadSettingsFromEEPROM(bool first)
|
||||
effectPaletteDefault = EEPROM.read(373); effectPalette = effectPaletteDefault;
|
||||
//374 - strip.paletteFade
|
||||
|
||||
if (lastEEPROMversion > 0) {
|
||||
apWaitTimeSecs = EEPROM.read(375);
|
||||
recoveryAPDisabled = EEPROM.read(376);
|
||||
if (lastEEPROMversion > 0) {
|
||||
//apWaitTimeSecs = EEPROM.read(375);
|
||||
apBehavior = EEPROM.read(376);
|
||||
}
|
||||
//377 = lastEEPROMversion
|
||||
if (lastEEPROMversion > 1) {
|
||||
@@ -370,7 +376,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
}
|
||||
}
|
||||
if (lastEEPROMversion > 3) {
|
||||
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
|
||||
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
|
||||
aOtaEnabled = EEPROM.read(390);
|
||||
receiveNotificationColor = EEPROM.read(391);
|
||||
receiveNotificationEffects = EEPROM.read(392);
|
||||
@@ -391,7 +397,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
}
|
||||
|
||||
readStringFromEEPROM(2054, hueApiKey, 46);
|
||||
|
||||
|
||||
huePollIntervalMs = EEPROM.read(2100) + ((EEPROM.read(2101) << 8) & 0xFF00);
|
||||
notifyHue = EEPROM.read(2102);
|
||||
hueApplyOnOff = EEPROM.read(2103);
|
||||
@@ -416,7 +422,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
|
||||
readStringFromEEPROM(2165, cronixieDisplay, 6);
|
||||
cronixieBacklight = EEPROM.read(2171);
|
||||
|
||||
|
||||
macroBoot = EEPROM.read(2175);
|
||||
macroAlexaOn = EEPROM.read(2176);
|
||||
macroAlexaOff = EEPROM.read(2177);
|
||||
@@ -454,9 +460,9 @@ void loadSettingsFromEEPROM(bool first)
|
||||
|
||||
if (lastEEPROMversion > 8)
|
||||
{
|
||||
readStringFromEEPROM(2300, mqttServer, 32);
|
||||
readStringFromEEPROM(2300, mqttServer, 32);
|
||||
readStringFromEEPROM(2333, mqttDeviceTopic, 32);
|
||||
readStringFromEEPROM(2366, mqttGroupTopic, 32);
|
||||
readStringFromEEPROM(2366, mqttGroupTopic, 32);
|
||||
}
|
||||
|
||||
if (lastEEPROMversion > 9)
|
||||
@@ -470,16 +476,24 @@ void loadSettingsFromEEPROM(bool first)
|
||||
} else {
|
||||
strip.ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
if (lastEEPROMversion > 10)
|
||||
{
|
||||
readStringFromEEPROM(2399, mqttUser, 40);
|
||||
readStringFromEEPROM(2440, mqttPass, 40);
|
||||
readStringFromEEPROM(2481, mqttClientID, 40);
|
||||
mqttPort = EEPROM.read(2522) + ((EEPROM.read(2523) << 8) & 0xFF00);
|
||||
}
|
||||
|
||||
receiveDirect = !EEPROM.read(2200);
|
||||
notifyMacro = EEPROM.read(2201);
|
||||
uiConfiguration = EEPROM.read(2202);
|
||||
|
||||
|
||||
#ifdef WLED_DISABLE_MOBILE_UI
|
||||
uiConfiguration = 1;
|
||||
//force default UI since mobile is unavailable
|
||||
#endif
|
||||
|
||||
|
||||
autoRGBtoRGBW = EEPROM.read(2203);
|
||||
skipFirstLed = EEPROM.read(2204);
|
||||
|
||||
@@ -493,7 +507,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
presetApplyCol = EEPROM.read(2211);
|
||||
presetApplyFx = EEPROM.read(2212);
|
||||
}
|
||||
|
||||
|
||||
bootPreset = EEPROM.read(389);
|
||||
wifiLock = EEPROM.read(393);
|
||||
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
|
||||
@@ -513,10 +527,10 @@ void loadSettingsFromEEPROM(bool first)
|
||||
//1024-2047 reserved
|
||||
|
||||
readStringFromEEPROM(2220, blynkApiKey, 35);
|
||||
|
||||
|
||||
//user MOD memory
|
||||
//2944 - 3071 reserved
|
||||
|
||||
|
||||
useHSB = useHSBDefault;
|
||||
|
||||
overlayCurrent = overlayDefault;
|
||||
@@ -570,7 +584,7 @@ void savePreset(byte index)
|
||||
}
|
||||
EEPROM.write(i+10, effectCurrent);
|
||||
EEPROM.write(i+11, effectSpeed);
|
||||
|
||||
|
||||
EEPROM.write(i+16, effectIntensity);
|
||||
EEPROM.write(i+17, effectPalette);
|
||||
EEPROM.commit();
|
||||
@@ -597,7 +611,7 @@ void applyMacro(byte index)
|
||||
if (!notifyMacro) mc += "&NN";
|
||||
String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop
|
||||
/*
|
||||
* NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again.
|
||||
* NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again.
|
||||
* To prevent that, but also disable calling macros within macros, comment the next line out.
|
||||
*/
|
||||
forbidden = forbidden + index;
|
||||
|
@@ -7,12 +7,12 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
|
||||
{
|
||||
char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed
|
||||
obuf = (dest == nullptr)? sbuf:dest;
|
||||
|
||||
|
||||
olen = 0;
|
||||
oappend("<?xml version=\"1.0\" ?><vs><ac>");
|
||||
oappendi((nightlightActive && nightlightFade) ? briT : bri);
|
||||
oappend("</ac>");
|
||||
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
oappend("<cl>");
|
||||
@@ -77,7 +77,7 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
|
||||
} else {
|
||||
oappend(serverDescription);
|
||||
}
|
||||
|
||||
|
||||
oappend("</ds>");
|
||||
if (includeTheme)
|
||||
{
|
||||
@@ -107,7 +107,7 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
|
||||
void sappend(char stype, char* key, int val)
|
||||
{
|
||||
char ds[] = "d.Sf.";
|
||||
|
||||
|
||||
switch(stype)
|
||||
{
|
||||
case 'c': //checkbox
|
||||
@@ -165,7 +165,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
DEBUG_PRINTLN(subPage);
|
||||
obuf = dest;
|
||||
olen = 0;
|
||||
|
||||
|
||||
if (subPage <1 || subPage >6) return;
|
||||
|
||||
if (subPage == 1) {
|
||||
@@ -174,7 +174,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
byte l = strlen(clientPass);
|
||||
char fpass[l+1]; //fill password field with ***
|
||||
fpass[l] = 0;
|
||||
memset(fpass,'*',l);
|
||||
memset(fpass,'*',l);
|
||||
sappends('s',"CP",fpass);
|
||||
|
||||
char k[3]; k[2] = 0; //IP addresses
|
||||
@@ -187,16 +187,16 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
}
|
||||
|
||||
sappends('s',"CM",cmDNS);
|
||||
sappend('v',"AT",apWaitTimeSecs);
|
||||
sappend('i',"AB",apBehavior);
|
||||
sappends('s',"AS",apSSID);
|
||||
sappend('c',"AH",apHide);
|
||||
|
||||
|
||||
l = strlen(apPass);
|
||||
char fapass[l+1]; //fill password field with ***
|
||||
fapass[l] = 0;
|
||||
memset(fapass,'*',l);
|
||||
memset(fapass,'*',l);
|
||||
sappends('s',"AP",fapass);
|
||||
|
||||
|
||||
sappend('v',"AC",apChannel);
|
||||
|
||||
if (WiFi.localIP()[0] != 0) //is connected
|
||||
@@ -209,7 +209,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
{
|
||||
sappends('m',"(\"sip\")[0]","Not connected");
|
||||
}
|
||||
|
||||
|
||||
if (WiFi.softAPIP()[0] != 0) //is active
|
||||
{
|
||||
char s[16];
|
||||
@@ -221,7 +221,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappends('m',"(\"sip\")[1]","Not active");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (subPage == 2) {
|
||||
sappend('v',"LC",ledCount);
|
||||
sappend('v',"MA",strip.ablMilliampsMax);
|
||||
@@ -253,8 +253,8 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
oappend(";");
|
||||
sappend('v',"SX",effectSpeedDefault);
|
||||
sappend('v',"IX",effectIntensityDefault);
|
||||
sappend('c',"GB",useGammaCorrectionBri);
|
||||
sappend('c',"GC",useGammaCorrectionRGB);
|
||||
sappend('c',"GB",strip.gammaCorrectBri);
|
||||
sappend('c',"GC",strip.gammaCorrectCol);
|
||||
sappend('c',"TF",fadeTransition);
|
||||
sappend('v',"TD",transitionDelay);
|
||||
sappend('c',"PF",strip.paletteFade);
|
||||
@@ -264,12 +264,12 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('v',"TL",nightlightDelayMinsDefault);
|
||||
sappend('c',"TW",nightlightFade);
|
||||
sappend('i',"PB",strip.paletteBlend);
|
||||
sappend('c',"RV",reverseMode);
|
||||
sappend('c',"RV",strip.reverseMode);
|
||||
sappend('c',"SL",skipFirstLed);
|
||||
}
|
||||
|
||||
if (subPage == 3)
|
||||
{
|
||||
{
|
||||
sappend('i',"UI",uiConfiguration);
|
||||
sappends('s',"DS",serverDescription);
|
||||
sappend('c',"MD",useHSBDefault);
|
||||
@@ -308,6 +308,15 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',"SA",notifyAlexa);
|
||||
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
|
||||
sappends('s',"MS",mqttServer);
|
||||
sappend('v',"MQPORT",mqttPort);
|
||||
sappends('s',"MQUSER",mqttUser);
|
||||
sappends('s',"MQPASS",mqttPass);
|
||||
byte l = strlen(mqttPass);
|
||||
char fpass[l+1]; //fill password field with ***
|
||||
fpass[l] = 0;
|
||||
memset(fpass,'*',l);
|
||||
sappends('s',"MQPASS",fpass);
|
||||
sappends('s',"MQCID",mqttClientID);
|
||||
sappends('s',"MD",mqttDeviceTopic);
|
||||
sappends('s',"MG",mqttGroupTopic);
|
||||
sappend('v',"H0",hueIP[0]);
|
||||
@@ -330,7 +339,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('i',"TZ",currentTimezone);
|
||||
sappend('v',"UO",utcOffsetSecs);
|
||||
char tm[32];
|
||||
getTimeString(tm);
|
||||
getTimeString(tm);
|
||||
sappends('m',"(\"times\")[0]",tm);
|
||||
sappend('i',"OL",overlayCurrent);
|
||||
sappend('v',"O1",overlayMin);
|
||||
@@ -355,7 +364,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sprintf(k+1,"%i",i);
|
||||
sappends('s',k,m);
|
||||
}
|
||||
|
||||
|
||||
sappend('v',"MB",macroBoot);
|
||||
sappend('v',"A0",macroAlexaOn);
|
||||
sappend('v',"A1",macroAlexaOff);
|
||||
@@ -381,7 +390,6 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',"NO",otaLock);
|
||||
sappend('c',"OW",wifiLock);
|
||||
sappend('c',"AO",aOtaEnabled);
|
||||
sappend('c',"NA",recoveryAPDisabled);
|
||||
sappends('m',"(\"msg\")[0]","WLED ");
|
||||
olen -= 2; //delete ";
|
||||
oappend(versionString);
|
||||
@@ -398,7 +406,7 @@ void getThemeColors(char o[][9])
|
||||
{
|
||||
switch (currentTheme)
|
||||
{
|
||||
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
|
||||
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
|
||||
default: strcpy(o[0], "D9B310"); strcpy(o[1], "0B3C5D"); strcpy(o[2], "1D2731"); strcpy(o[3], "328CC1"); strcpy(o[4], "000"); strcpy(o[5], "328CC1"); break; //night
|
||||
case 1: strcpy(o[0], "eee"); strcpy(o[1], "ddd"); strcpy(o[2], "b9b9b9"); strcpy(o[3], "049"); strcpy(o[4], "777"); strcpy(o[5], "049"); break; //modern
|
||||
case 2: strcpy(o[0], "abb"); strcpy(o[1], "fff"); strcpy(o[2], "ddd"); strcpy(o[3], "000"); strcpy(o[4], "0004"); strcpy(o[5], "000"); break; //bright
|
||||
|
@@ -19,7 +19,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
{
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
|
||||
if (subPage <1 || subPage >6) return;
|
||||
|
||||
|
||||
//WIFI SETTINGS
|
||||
if (subPage == 1)
|
||||
{
|
||||
@@ -27,24 +27,25 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
if (request->arg("CP").charAt(0) != '*') strcpy(clientPass, request->arg("CP").c_str());
|
||||
|
||||
strcpy(cmDNS, request->arg("CM").c_str());
|
||||
|
||||
int t = request->arg("AT").toInt(); if (t > 9 && t <= 255) apWaitTimeSecs = t;
|
||||
|
||||
apBehavior = request->arg("AB").toInt();
|
||||
strcpy(apSSID, request->arg("AS").c_str());
|
||||
apHide = request->hasArg("AH");
|
||||
if (request->arg("AP").charAt(0) != '*') strcpy(apPass, request->arg("AP").c_str());
|
||||
t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
||||
|
||||
int passlen = request->arg("AP").length();
|
||||
if (passlen == 0 || (passlen > 7 && request->arg("AP").charAt(0) != '*')) strcpy(apPass, request->arg("AP").c_str());
|
||||
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
||||
|
||||
char k[3]; k[2] = 0;
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
k[1] = i+48;//ascii 0,1,2,3
|
||||
|
||||
|
||||
k[0] = 'I'; //static IP
|
||||
staticIP[i] = request->arg(k).toInt();
|
||||
|
||||
|
||||
k[0] = 'G'; //gateway
|
||||
staticGateway[i] = request->arg(k).toInt();
|
||||
|
||||
|
||||
k[0] = 'S'; //subnet
|
||||
staticSubnet[i] = request->arg(k).toInt();
|
||||
}
|
||||
@@ -54,15 +55,15 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
if (subPage == 2)
|
||||
{
|
||||
int t = request->arg("LC").toInt();
|
||||
if (t > 0 && t <= 1200) ledCount = t;
|
||||
if (t > 0 && t <= MAX_LEDS) ledCount = t;
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
#if LEDPIN == 3
|
||||
if (ledCount > 300) ledCount = 300; //DMA method uses too much ram
|
||||
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
||||
#endif
|
||||
#endif
|
||||
strip.ablMilliampsMax = request->arg("MA").toInt();
|
||||
useRGBW = request->hasArg("EW");
|
||||
strip.colorOrder = request->arg("CO").toInt();
|
||||
strip.colorOrder = request->arg("CO").toInt();
|
||||
autoRGBtoRGBW = request->hasArg("AW");
|
||||
|
||||
//ignore settings and save current brightness, colors and fx as default
|
||||
@@ -97,25 +98,25 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
turnOnAtBoot = request->hasArg("BO");
|
||||
t = request->arg("BP").toInt();
|
||||
if (t <= 25) bootPreset = t;
|
||||
useGammaCorrectionBri = request->hasArg("GB");
|
||||
useGammaCorrectionRGB = request->hasArg("GC");
|
||||
|
||||
strip.gammaCorrectBri = request->hasArg("GB");
|
||||
strip.gammaCorrectCol = request->hasArg("GC");
|
||||
|
||||
fadeTransition = request->hasArg("TF");
|
||||
t = request->arg("TD").toInt();
|
||||
if (t > 0) transitionDelay = t;
|
||||
transitionDelayDefault = t;
|
||||
strip.paletteFade = request->hasArg("PF");
|
||||
enableSecTransition = request->hasArg("T2");
|
||||
|
||||
|
||||
nightlightTargetBri = request->arg("TB").toInt();
|
||||
t = request->arg("TL").toInt();
|
||||
if (t > 0) nightlightDelayMinsDefault = t;
|
||||
nightlightDelayMins = nightlightDelayMinsDefault;
|
||||
nightlightFade = request->hasArg("TW");
|
||||
|
||||
|
||||
t = request->arg("PB").toInt();
|
||||
if (t >= 0 && t < 4) strip.paletteBlend = t;
|
||||
reverseMode = request->hasArg("RV");
|
||||
strip.setReverseMode(reverseMode);
|
||||
strip.reverseMode = request->hasArg("RV");
|
||||
skipFirstLed = request->hasArg("SL");
|
||||
t = request->arg("BF").toInt();
|
||||
if (t > 0) briMultiplier = t;
|
||||
@@ -157,7 +158,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
notifyHue = request->hasArg("SH");
|
||||
notifyMacro = request->hasArg("SM");
|
||||
notifyTwice = request->hasArg("S2");
|
||||
|
||||
|
||||
receiveDirect = request->hasArg("RD");
|
||||
e131Multicast = request->hasArg("EM");
|
||||
t = request->arg("EU").toInt();
|
||||
@@ -168,18 +169,23 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
arlsDisableGammaCorrection = request->hasArg("RG");
|
||||
t = request->arg("WO").toInt();
|
||||
if (t >= -255 && t <= 255) arlsOffset = t;
|
||||
|
||||
|
||||
alexaEnabled = request->hasArg("AL");
|
||||
strcpy(alexaInvocationName, request->arg("AI").c_str());
|
||||
|
||||
|
||||
if (request->hasArg("BK") && !request->arg("BK").equals("Hidden")) {
|
||||
strcpy(blynkApiKey,request->arg("BK").c_str()); initBlynk(blynkApiKey);
|
||||
}
|
||||
|
||||
strcpy(mqttServer, request->arg("MS").c_str());
|
||||
t = request->arg("MQPORT").toInt();
|
||||
if (t > 0) mqttPort = t;
|
||||
strcpy(mqttUser, request->arg("MQUSER").c_str());
|
||||
if (request->arg("MQPASS").charAt(0) != '*') strcpy(mqttPass, request->arg("MQPASS").c_str());
|
||||
strcpy(mqttClientID, request->arg("MQCID").c_str());
|
||||
strcpy(mqttDeviceTopic, request->arg("MD").c_str());
|
||||
strcpy(mqttGroupTopic, request->arg("MG").c_str());
|
||||
|
||||
|
||||
for (int i=0;i<4;i++){
|
||||
String a = "H"+String(i);
|
||||
hueIP[i] = request->arg(a).toInt();
|
||||
@@ -208,20 +214,20 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
utcOffsetSecs = request->arg("UO").toInt();
|
||||
|
||||
//start ntp if not already connected
|
||||
if (ntpEnabled && WiFi.status() == WL_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||
|
||||
if (ntpEnabled && WLED_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||
|
||||
if (request->hasArg("OL")){
|
||||
overlayDefault = request->arg("OL").toInt();
|
||||
if (overlayCurrent != overlayDefault) strip.unlockAll();
|
||||
overlayCurrent = overlayDefault;
|
||||
}
|
||||
|
||||
|
||||
overlayMin = request->arg("O1").toInt();
|
||||
overlayMax = request->arg("O2").toInt();
|
||||
analogClock12pixel = request->arg("OM").toInt();
|
||||
analogClock5MinuteMarks = request->hasArg("O5");
|
||||
analogClockSecondsTrail = request->hasArg("OS");
|
||||
|
||||
|
||||
strcpy(cronixieDisplay,request->arg("CX").c_str());
|
||||
bool cbOld = cronixieBacklight;
|
||||
cronixieBacklight = request->hasArg("CB");
|
||||
@@ -236,13 +242,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
countdownHour = request->arg("CH").toInt();
|
||||
countdownMin = request->arg("CM").toInt();
|
||||
countdownSec = request->arg("CS").toInt();
|
||||
|
||||
|
||||
for (int i=1;i<17;i++)
|
||||
{
|
||||
String a = "M"+String(i);
|
||||
if (request->hasArg(a.c_str())) saveMacro(i,request->arg(a),false);
|
||||
}
|
||||
|
||||
|
||||
macroBoot = request->arg("MB").toInt();
|
||||
macroAlexaOn = request->arg("A0").toInt();
|
||||
macroAlexaOff = request->arg("A1").toInt();
|
||||
@@ -256,13 +262,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
for (int i = 0; i<8; i++)
|
||||
{
|
||||
k[1] = i+48;//ascii 0,1,2,3
|
||||
|
||||
|
||||
k[0] = 'H'; //timer hours
|
||||
timerHours[i] = request->arg(k).toInt();
|
||||
|
||||
|
||||
k[0] = 'N'; //minutes
|
||||
timerMinutes[i] = request->arg(k).toInt();
|
||||
|
||||
|
||||
k[0] = 'T'; //macros
|
||||
timerMacro[i] = request->arg(k).toInt();
|
||||
|
||||
@@ -293,12 +299,11 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
strcpy(otaPass,request->arg("OP").c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pwdCorrect) //allow changes if correct pwd or no ota active
|
||||
{
|
||||
otaLock = request->hasArg("NO");
|
||||
wifiLock = request->hasArg("OW");
|
||||
recoveryAPDisabled = request->hasArg("NA");
|
||||
aOtaEnabled = request->hasArg("AO");
|
||||
}
|
||||
}
|
||||
@@ -321,7 +326,7 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte
|
||||
{
|
||||
int pos = req->indexOf(key);
|
||||
if (pos < 1) return false;
|
||||
|
||||
|
||||
if (req->charAt(pos+3) == '~') {
|
||||
int out = getNumVal(req, pos+1);
|
||||
if (out == 0)
|
||||
@@ -354,25 +359,25 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
int pos = 0;
|
||||
DEBUG_PRINT("API req: ");
|
||||
DEBUG_PRINTLN(req);
|
||||
|
||||
|
||||
//save macro, requires &MS=<slot>(<macro>) format
|
||||
pos = req.indexOf("&MS=");
|
||||
if (pos > 0) {
|
||||
int i = req.substring(pos + 4).toInt();
|
||||
pos = req.indexOf('(') +1;
|
||||
if (pos > 0) {
|
||||
if (pos > 0) {
|
||||
int en = req.indexOf(')');
|
||||
String mc = req.substring(pos);
|
||||
if (en > 0) mc = req.substring(pos, en);
|
||||
saveMacro(i, mc);
|
||||
saveMacro(i, mc);
|
||||
}
|
||||
|
||||
|
||||
pos = req.indexOf("IN");
|
||||
if (pos < 1) XML_response(request, false);
|
||||
return true;
|
||||
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
|
||||
}
|
||||
|
||||
|
||||
//set brightness
|
||||
updateVal(&req, "&A=", &bri);
|
||||
|
||||
@@ -397,7 +402,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
}
|
||||
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
|
||||
}
|
||||
|
||||
|
||||
//set color from HEX or 32bit DEC
|
||||
pos = req.indexOf("CL=");
|
||||
if (pos > 0) {
|
||||
@@ -407,7 +412,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
if (pos > 0) {
|
||||
colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str());
|
||||
}
|
||||
|
||||
|
||||
//set 2nd to white
|
||||
pos = req.indexOf("SW");
|
||||
if (pos > 0) {
|
||||
@@ -422,7 +427,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
colSec[2] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//set 2nd to black
|
||||
pos = req.indexOf("SB");
|
||||
if (pos > 0) {
|
||||
@@ -431,13 +436,13 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
colSec[1] = 0;
|
||||
colSec[2] = 0;
|
||||
}
|
||||
|
||||
|
||||
//set to random hue SR=0->1st SR=1->2nd
|
||||
pos = req.indexOf("SR");
|
||||
if (pos > 0) {
|
||||
_setRandomColor(getNumVal(&req, pos));
|
||||
}
|
||||
|
||||
|
||||
//set 2nd to 1st
|
||||
pos = req.indexOf("SP");
|
||||
if (pos > 0) {
|
||||
@@ -446,7 +451,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
colSec[2] = col[2];
|
||||
colSec[3] = col[3];
|
||||
}
|
||||
|
||||
|
||||
//swap 2nd & 1st
|
||||
pos = req.indexOf("SC");
|
||||
if (pos > 0) {
|
||||
@@ -458,7 +463,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
colSec[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//set effect parameters
|
||||
if (updateVal(&req, "FX=", &effectCurrent, 0, strip.getModeCount()-1)) presetCyclingEnabled = false;
|
||||
updateVal(&req, "SX=", &effectSpeed);
|
||||
@@ -479,27 +484,27 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//set default control mode (0 - RGB, 1 - HSB)
|
||||
pos = req.indexOf("MD=");
|
||||
if (pos > 0) {
|
||||
useHSB = getNumVal(&req, pos);
|
||||
}
|
||||
|
||||
|
||||
//set advanced overlay
|
||||
pos = req.indexOf("OL=");
|
||||
if (pos > 0) {
|
||||
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){
|
||||
if (pos > 0) {
|
||||
uint16_t index2 = getNumVal(&req, pos);
|
||||
if (unlock) {
|
||||
strip.unlockRange(index, index2);
|
||||
@@ -520,11 +525,11 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
if (pos > 0) {
|
||||
applyMacro(getNumVal(&req, pos));
|
||||
}
|
||||
|
||||
|
||||
//toggle send UDP direct notifications
|
||||
pos = req.indexOf("SN=");
|
||||
if (pos > 0) notifyDirect = (req.charAt(pos+3) != '0');
|
||||
|
||||
|
||||
//toggle receive UDP direct notifications
|
||||
pos = req.indexOf("RN=");
|
||||
if (pos > 0) receiveNotifications = (req.charAt(pos+3) != '0');
|
||||
@@ -532,7 +537,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
//receive live data via UDP/Hyperion
|
||||
pos = req.indexOf("RD=");
|
||||
if (pos > 0) receiveDirect = (req.charAt(pos+3) != '0');
|
||||
|
||||
|
||||
//toggle nightlight mode
|
||||
bool aNlDef = false;
|
||||
if (req.indexOf("&ND") > 0) aNlDef = true;
|
||||
@@ -553,14 +558,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
nightlightActive = true;
|
||||
nightlightStartTime = millis();
|
||||
}
|
||||
|
||||
|
||||
//set nightlight target brightness
|
||||
pos = req.indexOf("NT=");
|
||||
if (pos > 0) {
|
||||
nightlightTargetBri = getNumVal(&req, pos);
|
||||
nightlightActiveOld = false; //re-init
|
||||
}
|
||||
|
||||
|
||||
//toggle nightlight fade
|
||||
pos = req.indexOf("NF=");
|
||||
if (pos > 0)
|
||||
@@ -578,7 +583,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
if (auxTime == 0) auxActive = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
pos = req.indexOf("TT=");
|
||||
if (pos > 0) transitionDelay = getNumVal(&req, pos);
|
||||
|
||||
@@ -597,7 +602,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
//Segment reverse
|
||||
pos = req.indexOf("RV=");
|
||||
if (pos > 0) strip.getSegment(0).setOption(1, req.charAt(pos+3) != '0');
|
||||
|
||||
|
||||
//deactivate nightlight if target brightness is reached
|
||||
if (bri == nightlightTargetBri) nightlightActive = false;
|
||||
//set time (unix timestamp)
|
||||
@@ -605,18 +610,18 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
if (pos > 0) {
|
||||
setTime(getNumVal(&req, pos));
|
||||
}
|
||||
|
||||
|
||||
//set countdown goal (unix timestamp)
|
||||
pos = req.indexOf("CT=");
|
||||
if (pos > 0) {
|
||||
countdownTime = getNumVal(&req, pos);
|
||||
if (countdownTime - now() > 0) countdownOverTriggered = false;
|
||||
}
|
||||
|
||||
|
||||
//set presets
|
||||
pos = req.indexOf("P1="); //sets first preset for cycle
|
||||
if (pos > 0) presetCycleMin = getNumVal(&req, pos);
|
||||
|
||||
|
||||
pos = req.indexOf("P2="); //sets last preset for cycle
|
||||
if (pos > 0) presetCycleMax = getNumVal(&req, pos);
|
||||
|
||||
@@ -627,7 +632,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
presetCyclingEnabled = (req.charAt(pos+3) != '0');
|
||||
presetCycCurr = presetCycleMin;
|
||||
}
|
||||
|
||||
|
||||
pos = req.indexOf("PT="); //sets cycle time in ms
|
||||
if (pos > 0) {
|
||||
int v = getNumVal(&req, pos);
|
||||
@@ -638,11 +643,11 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
if (pos > 0) presetApplyBri = (req.charAt(pos+3) != '0');
|
||||
|
||||
pos = req.indexOf("PC="); //apply color from preset
|
||||
if (pos > 0) presetApplyCol = (req.charAt(pos+3) != '0');
|
||||
if (pos > 0) presetApplyCol = (req.charAt(pos+3) != '0');
|
||||
|
||||
pos = req.indexOf("PX="); //apply effects from preset
|
||||
if (pos > 0) presetApplyFx = (req.charAt(pos+3) != '0');
|
||||
|
||||
|
||||
pos = req.indexOf("PS="); //saves current in preset
|
||||
if (pos > 0) savePreset(getNumVal(&req, pos));
|
||||
|
||||
@@ -650,7 +655,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
if (updateVal(&req, "PL=", &presetCycCurr, presetCycleMin, presetCycleMax)) {
|
||||
applyPreset(presetCycCurr, presetApplyBri, presetApplyCol, presetApplyFx);
|
||||
}
|
||||
|
||||
|
||||
//cronixie
|
||||
#ifndef WLED_DISABLE_CRONIXIE
|
||||
pos = req.indexOf("NX="); //sets digits to code
|
||||
@@ -658,7 +663,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
strcpy(cronixieDisplay,req.substring(pos + 3, pos + 9).c_str());
|
||||
setCronixie();
|
||||
}
|
||||
|
||||
|
||||
if (req.indexOf("NB=") > 0) //sets backlight
|
||||
{
|
||||
cronixieBacklight = true;
|
||||
@@ -673,24 +678,24 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
||||
//mode, 1 countdown
|
||||
pos = req.indexOf("NM=");
|
||||
if (pos > 0) countdownMode = (req.charAt(pos+3) != '0');
|
||||
|
||||
|
||||
pos = req.indexOf("U0="); //user var 0
|
||||
if (pos > 0) {
|
||||
userVar0 = getNumVal(&req, pos);
|
||||
}
|
||||
|
||||
|
||||
pos = req.indexOf("U1="); //user var 1
|
||||
if (pos > 0) {
|
||||
userVar1 = getNumVal(&req, pos);
|
||||
}
|
||||
//you can add more if you need
|
||||
|
||||
|
||||
//internal call, does not send XML response
|
||||
pos = req.indexOf("IN");
|
||||
if (pos < 1) XML_response(request, (req.indexOf("&IT") > 0)); //include theme if firstload
|
||||
|
||||
|
||||
pos = req.indexOf("&NN"); //do not send UDP notifications this time
|
||||
colorUpdated((pos > 0) ? 5:1);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -3,13 +3,13 @@
|
||||
*/
|
||||
|
||||
void wledInit()
|
||||
{
|
||||
{
|
||||
EEPROM.begin(EEPSIZE);
|
||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
|
||||
if (ledCount > 1200 || ledCount == 0) ledCount = 30;
|
||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
|
||||
if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30;
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
#if LEDPIN == 3
|
||||
if (ledCount > 300) ledCount = 300; //DMA method uses too much ram
|
||||
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
||||
#endif
|
||||
#endif
|
||||
Serial.begin(115200);
|
||||
@@ -24,7 +24,7 @@ void wledInit()
|
||||
int heapPreAlloc = ESP.getFreeHeap();
|
||||
DEBUG_PRINT("heap ");
|
||||
DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
|
||||
|
||||
strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly
|
||||
|
||||
DEBUG_PRINT("LEDs inited. heap usage ~");
|
||||
@@ -36,125 +36,68 @@ void wledInit()
|
||||
#endif
|
||||
SPIFFS.begin();
|
||||
#endif
|
||||
|
||||
|
||||
DEBUG_PRINTLN("Load EEPROM");
|
||||
loadSettingsFromEEPROM(true);
|
||||
beginStrip();
|
||||
DEBUG_PRINT("CSSID: ");
|
||||
DEBUG_PRINT(clientSSID);
|
||||
userBeginPreConnection();
|
||||
userSetup();
|
||||
if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true;
|
||||
WiFi.persistent(false);
|
||||
initCon();
|
||||
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINT("Connected! IP address: ");
|
||||
DEBUG_PRINTLN(WiFi.localIP());
|
||||
if (macroBoot>0) applyMacro(macroBoot);
|
||||
Serial.println("Ada");
|
||||
|
||||
if (hueIP[0] == 0)
|
||||
{
|
||||
hueIP[0] = WiFi.localIP()[0];
|
||||
hueIP[1] = WiFi.localIP()[1];
|
||||
hueIP[2] = WiFi.localIP()[2];
|
||||
}
|
||||
|
||||
if (udpPort > 0 && udpPort != ntpLocalPort)
|
||||
{
|
||||
udpConnected = notifierUdp.begin(udpPort);
|
||||
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||
}
|
||||
if (ntpEnabled && WiFi.status() == WL_CONNECTED)
|
||||
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||
|
||||
//start captive portal if AP active
|
||||
if (onlyAP || strlen(apSSID) > 0)
|
||||
{
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure);
|
||||
dnsServer.start(53, "wled.me", WiFi.softAPIP());
|
||||
dnsActive = true;
|
||||
}
|
||||
|
||||
prepareIds(); //UUID from MAC (for Alexa and MQTT)
|
||||
//generate module IDs
|
||||
escapedMac = WiFi.macAddress();
|
||||
escapedMac.replace(":", "");
|
||||
escapedMac.toLowerCase();
|
||||
if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default
|
||||
{
|
||||
strcpy(cmDNS, "wled-");
|
||||
strcat(cmDNS, escapedMac.c_str());
|
||||
sprintf(cmDNS+5, "%*s", 6, escapedMac.c_str()+6);
|
||||
}
|
||||
if (mqttDeviceTopic[0] == 0)
|
||||
{
|
||||
strcpy(mqttDeviceTopic, "wled/");
|
||||
strcat(mqttDeviceTopic, escapedMac.c_str());
|
||||
sprintf(mqttDeviceTopic+5, "%*s", 6, escapedMac.c_str()+6);
|
||||
}
|
||||
|
||||
//smartInit, we only init some resources when connected
|
||||
if (!onlyAP && WiFi.status() == WL_CONNECTED)
|
||||
if (mqttClientID[0] == 0)
|
||||
{
|
||||
mqtt = new AsyncMqttClient();
|
||||
initMqtt();
|
||||
strcpy(mqttClientID, "WLED-");
|
||||
sprintf(mqttClientID+5, "%*s", 6, escapedMac.c_str()+6);
|
||||
}
|
||||
|
||||
|
||||
strip.service();
|
||||
|
||||
//HTTP server page init
|
||||
initServer();
|
||||
|
||||
strip.service();
|
||||
//init Alexa hue emulation
|
||||
if (alexaEnabled && !onlyAP) alexaInit();
|
||||
|
||||
server.begin();
|
||||
DEBUG_PRINTLN("HTTP server started");
|
||||
|
||||
//init ArduinoOTA
|
||||
if (!onlyAP) {
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
if (aOtaEnabled)
|
||||
{
|
||||
ArduinoOTA.onStart([]() {
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
#ifdef ESP8266
|
||||
wifi_set_sleep_type(NONE_SLEEP_T);
|
||||
#endif
|
||||
DEBUG_PRINTLN("Start ArduinoOTA");
|
||||
});
|
||||
if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS);
|
||||
ArduinoOTA.begin();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
strip.service();
|
||||
// Set up mDNS responder:
|
||||
if (strlen(cmDNS) > 0 && !onlyAP)
|
||||
{
|
||||
MDNS.begin(cmDNS);
|
||||
DEBUG_PRINTLN("mDNS responder started");
|
||||
// Add service to MDNS
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("wled", "tcp", 80);
|
||||
}
|
||||
strip.service();
|
||||
//HTTP server page init
|
||||
initServer();
|
||||
|
||||
initBlynk(blynkApiKey);
|
||||
initE131();
|
||||
reconnectHue();
|
||||
} else {
|
||||
e131Enabled = false;
|
||||
}
|
||||
strip.service();
|
||||
|
||||
userBegin();
|
||||
|
||||
if (macroBoot>0) applyMacro(macroBoot);
|
||||
Serial.println("Ada");
|
||||
initConnection();
|
||||
}
|
||||
|
||||
|
||||
void beginStrip()
|
||||
{
|
||||
// Initialize NeoPixel Strip and button
|
||||
strip.setReverseMode(reverseMode);
|
||||
strip.setColor(0);
|
||||
strip.setBrightness(255);
|
||||
|
||||
#ifdef BTNPIN
|
||||
pinMode(BTNPIN, INPUT_PULLUP);
|
||||
#endif
|
||||
|
||||
if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
|
||||
colorUpdated(0);
|
||||
@@ -170,19 +113,41 @@ void beginStrip()
|
||||
#endif
|
||||
|
||||
//disable button if it is "pressed" unintentionally
|
||||
#ifdef BTNPIN
|
||||
if(digitalRead(BTNPIN) == LOW) buttonEnabled = false;
|
||||
#else
|
||||
buttonEnabled = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void initAP(){
|
||||
bool set = apSSID[0];
|
||||
if (!set) strcpy(apSSID,"WLED-AP");
|
||||
void initAP(bool resetAP=false){
|
||||
if (apBehavior == 3 && !resetAP) return;
|
||||
|
||||
if (!apSSID[0] || resetAP) strcpy(apSSID, "WLED-AP");
|
||||
if (resetAP) strcpy(apPass,"wled1234");
|
||||
DEBUG_PRINT("Opening access point ");
|
||||
DEBUG_PRINTLN(apSSID);
|
||||
WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0));
|
||||
WiFi.softAP(apSSID, apPass, apChannel, apHide);
|
||||
if (!set) apSSID[0] = 0;
|
||||
|
||||
if (!apActive) //start captive portal if AP active
|
||||
{
|
||||
DEBUG_PRINTLN("Init AP interfaces");
|
||||
server.begin();
|
||||
if (udpPort > 0 && udpPort != ntpLocalPort)
|
||||
{
|
||||
udpConnected = notifierUdp.begin(udpPort);
|
||||
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||
}
|
||||
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||
}
|
||||
apActive = true;
|
||||
}
|
||||
|
||||
|
||||
void initCon()
|
||||
void initConnection()
|
||||
{
|
||||
WiFi.disconnect(); //close old connections
|
||||
|
||||
@@ -194,48 +159,135 @@ void initCon()
|
||||
WiFi.config(0U, 0U, 0U);
|
||||
}
|
||||
|
||||
if (strlen(apSSID)>0)
|
||||
lastReconnectAttempt = millis();
|
||||
|
||||
if (!WLED_WIFI_CONFIGURED)
|
||||
{
|
||||
DEBUG_PRINT(" USING AP");
|
||||
DEBUG_PRINTLN(strlen(apSSID));
|
||||
initAP();
|
||||
} else
|
||||
{
|
||||
DEBUG_PRINTLN(" NO AP");
|
||||
WiFi.softAPdisconnect(true);
|
||||
DEBUG_PRINT("No connection configured. ");
|
||||
if (!apActive) initAP(); //instantly go to ap mode
|
||||
return;
|
||||
} else if (!apActive) {
|
||||
if (apBehavior == 2)
|
||||
{
|
||||
initAP();
|
||||
} else
|
||||
{
|
||||
DEBUG_PRINTLN("Access point disabled.");
|
||||
WiFi.softAPdisconnect(true);
|
||||
}
|
||||
}
|
||||
int fail_count = 0;
|
||||
if (strlen(clientSSID) <1 || strcmp(clientSSID,"Your_Network") == 0)
|
||||
fail_count = apWaitTimeSecs*2; //instantly go to ap mode
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
showWelcomePage = false;
|
||||
|
||||
DEBUG_PRINT("Connecting to ");
|
||||
DEBUG_PRINT(clientSSID);
|
||||
DEBUG_PRINTLN("...");
|
||||
|
||||
#ifdef ESP8266
|
||||
WiFi.hostname(serverDescription);
|
||||
#endif
|
||||
WiFi.begin(clientSSID, clientPass);
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WiFi.setHostname(serverDescription);
|
||||
#endif
|
||||
unsigned long lastTry = 0;
|
||||
bool con = false;
|
||||
while(!con)
|
||||
}
|
||||
|
||||
void initInterfaces() {
|
||||
DEBUG_PRINTLN("Init STA interfaces");
|
||||
|
||||
if (hueIP[0] == 0)
|
||||
{
|
||||
yield();
|
||||
handleTransitions();
|
||||
handleButton();
|
||||
handleOverlays();
|
||||
if (briT) strip.service();
|
||||
if (millis()-lastTry > 499) {
|
||||
con = (WiFi.status() == WL_CONNECTED);
|
||||
lastTry = millis();
|
||||
DEBUG_PRINTLN("C_NC");
|
||||
if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2)
|
||||
{
|
||||
WiFi.disconnect();
|
||||
DEBUG_PRINTLN("Can't connect. Opening AP...");
|
||||
onlyAP = true;
|
||||
initAP();
|
||||
return;
|
||||
}
|
||||
fail_count++;
|
||||
hueIP[0] = WiFi.localIP()[0];
|
||||
hueIP[1] = WiFi.localIP()[1];
|
||||
hueIP[2] = WiFi.localIP()[2];
|
||||
}
|
||||
|
||||
//init Alexa hue emulation
|
||||
if (alexaEnabled) alexaInit();
|
||||
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
if (aOtaEnabled) ArduinoOTA.begin();
|
||||
#endif
|
||||
|
||||
strip.service();
|
||||
// Set up mDNS responder:
|
||||
if (strlen(cmDNS) > 0)
|
||||
{
|
||||
if (!aOtaEnabled) MDNS.begin(cmDNS);
|
||||
|
||||
DEBUG_PRINTLN("mDNS started");
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("wled", "tcp", 80);
|
||||
}
|
||||
server.begin();
|
||||
|
||||
if (udpPort > 0 && udpPort != ntpLocalPort)
|
||||
{
|
||||
udpConnected = notifierUdp.begin(udpPort);
|
||||
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||
}
|
||||
if (ntpEnabled && WLED_CONNECTED)
|
||||
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||
|
||||
initBlynk(blynkApiKey);
|
||||
initE131();
|
||||
reconnectHue();
|
||||
initMqtt();
|
||||
interfacesInited = true;
|
||||
wasConnected = true;
|
||||
}
|
||||
|
||||
byte stacO = 0;
|
||||
|
||||
void handleConnection() {
|
||||
//TODO: reconnect if heap <8000
|
||||
byte stac = 0;
|
||||
#ifdef ESP8266
|
||||
stac = wifi_softap_get_station_num();
|
||||
#else
|
||||
wifi_sta_list_t stationList;
|
||||
esp_wifi_ap_get_sta_list(&stationList);
|
||||
stac = stationList.num;
|
||||
#endif
|
||||
if (stac != stacO)
|
||||
{
|
||||
stacO = stac;
|
||||
DEBUG_PRINT("Connected AP clients: ");
|
||||
DEBUG_PRINTLN(stac);
|
||||
if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected
|
||||
if (stac) WiFi.disconnect(); //disable search so that AP can work
|
||||
else initConnection(); //restart search
|
||||
}
|
||||
}
|
||||
if (forceReconnect) {
|
||||
DEBUG_PRINTLN("Forcing reconnect.");
|
||||
initConnection();
|
||||
interfacesInited = false;
|
||||
forceReconnect = false;
|
||||
wasConnected = false;
|
||||
return;
|
||||
}
|
||||
if (!WLED_CONNECTED) {
|
||||
if (interfacesInited) {
|
||||
DEBUG_PRINTLN("Disconnected!");
|
||||
interfacesInited = false;
|
||||
initConnection();
|
||||
}
|
||||
if (millis() - lastReconnectAttempt > 300000 && WLED_WIFI_CONFIGURED) initConnection();
|
||||
if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == 1)) initAP();
|
||||
} else if (!interfacesInited) { //newly connected
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINT("Connected! IP address: ");
|
||||
DEBUG_PRINTLN(WiFi.localIP());
|
||||
initInterfaces();
|
||||
userConnected();
|
||||
|
||||
//shut down AP
|
||||
if (apBehavior != 2 && apActive)
|
||||
{
|
||||
dnsServer.stop();
|
||||
WiFi.softAPdisconnect(true);
|
||||
apActive = false;
|
||||
DEBUG_PRINTLN("Access point disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,5 +299,6 @@ bool checkClientIsMobile(String useragent)
|
||||
if (useragent.indexOf("Android") >= 0) return true;
|
||||
if (useragent.indexOf("iPhone") >= 0) return true;
|
||||
if (useragent.indexOf("iPod") >= 0) return true;
|
||||
if (useragent.indexOf("iPad") >= 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
@@ -7,16 +7,19 @@
|
||||
|
||||
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
|
||||
|
||||
void userBeginPreConnection()
|
||||
//gets called once at boot. Do all initialization that doesn't depend on network here
|
||||
void userSetup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void userBegin()
|
||||
//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()
|
||||
{
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* UDP notifier
|
||||
*/
|
||||
|
||||
#define WLEDPACKETSIZE 24
|
||||
#define WLEDPACKETSIZE 29
|
||||
#define UDP_IN_MAXSIZE 1472
|
||||
|
||||
|
||||
@@ -34,7 +34,11 @@ void notify(byte callMode, bool followUp=false)
|
||||
udpOut[8] = effectCurrent;
|
||||
udpOut[9] = effectSpeed;
|
||||
udpOut[10] = col[3];
|
||||
udpOut[11] = 5; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
||||
//compatibilityVersionByte:
|
||||
//0: old 1: supports white 2: supports secondary color
|
||||
//3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
||||
//6: supports timebase syncing, 29 byte packet 7: supports tertiary color
|
||||
udpOut[11] = 6;
|
||||
udpOut[12] = colSec[0];
|
||||
udpOut[13] = colSec[1];
|
||||
udpOut[14] = colSec[2];
|
||||
@@ -43,6 +47,16 @@ void notify(byte callMode, bool followUp=false)
|
||||
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
||||
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
||||
udpOut[19] = effectPalette;
|
||||
/*udpOut[20] = colTer[0];
|
||||
udpOut[21] = colTer[1];
|
||||
udpOut[22] = colTer[2];
|
||||
udpOut[23] = colTer[3];*/
|
||||
udpOut[24] = followUp;
|
||||
uint32_t t = millis() + strip.timebase;
|
||||
udpOut[25] = (t >> 24) & 0xFF;
|
||||
udpOut[26] = (t >> 16) & 0xFF;
|
||||
udpOut[27] = (t >> 8) & 0xFF;
|
||||
udpOut[28] = (t >> 0) & 0xFF;
|
||||
|
||||
IPAddress broadcastIp;
|
||||
broadcastIp = ~uint32_t(WiFi.subnetMask()) | uint32_t(WiFi.gatewayIP());
|
||||
@@ -64,17 +78,18 @@ void arlsLock(uint32_t timeoutMs)
|
||||
strip.setPixelColor(i,0,0,0,0);
|
||||
}
|
||||
strip.unlockAll();
|
||||
realtimeActive = true;
|
||||
}
|
||||
realtimeActive = true;
|
||||
realtimeTimeout = millis() + timeoutMs;
|
||||
if (timeoutMs == 255001 || timeoutMs == 65000) realtimeTimeout = UINT32_MAX;
|
||||
if (arlsForceMaxBri) strip.setBrightness(255);
|
||||
}
|
||||
|
||||
|
||||
void initE131(){
|
||||
if (WiFi.status() == WL_CONNECTED && e131Enabled)
|
||||
if (WLED_CONNECTED && e131Enabled)
|
||||
{
|
||||
e131 = new E131();
|
||||
if (e131 == nullptr) e131 = new E131();
|
||||
e131->begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe);
|
||||
} else {
|
||||
e131Enabled = false;
|
||||
@@ -84,7 +99,7 @@ void initE131(){
|
||||
|
||||
void handleE131(){
|
||||
//E1.31 protocol support
|
||||
if(e131Enabled) {
|
||||
if(WLED_CONNECTED && e131Enabled) {
|
||||
uint16_t len = e131->parsePacket();
|
||||
if (!len || e131->universe < e131Universe || e131->universe > e131Universe +4) return;
|
||||
len /= 3; //one LED is 3 DMX channels
|
||||
@@ -159,6 +174,9 @@ void handleNotifications()
|
||||
//wled notifier, block if realtime packets active
|
||||
if (udpIn[0] == 0 && !realtimeActive && receiveNotifications)
|
||||
{
|
||||
//ignore notification if received within a second after sending a notification ourselves
|
||||
if (millis() - notificationSentTime < 1000) return;
|
||||
|
||||
bool someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
//apply colors from notification
|
||||
if (receiveNotificationColor || !someSel)
|
||||
@@ -176,11 +194,25 @@ void handleNotifications()
|
||||
colSec[2] = udpIn[14];
|
||||
colSec[3] = udpIn[15];
|
||||
}
|
||||
if (udpIn[11] > 5)
|
||||
{
|
||||
uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]);
|
||||
t -= 2;
|
||||
t -= millis();
|
||||
strip.timebase = t;
|
||||
}
|
||||
/*if (udpIn[11] > 6)
|
||||
{
|
||||
colTer[0] = udpIn[20];
|
||||
colTer[1] = udpIn[21];
|
||||
colTer[2] = udpIn[22];
|
||||
colSec[3] = udpIn[23];
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
//apply effects from notification
|
||||
if (receiveNotificationEffects || !someSel)
|
||||
if (udpIn[11] < 200 && (receiveNotificationEffects || !someSel))
|
||||
{
|
||||
if (udpIn[8] < strip.getModeCount()) effectCurrent = udpIn[8];
|
||||
effectSpeed = udpIn[9];
|
||||
@@ -206,10 +238,10 @@ void handleNotifications()
|
||||
if (packetSize > 1) {
|
||||
if (udpIn[1] == 0)
|
||||
{
|
||||
realtimeActive = false;
|
||||
realtimeTimeout = 0;
|
||||
return;
|
||||
} else {
|
||||
arlsLock(udpIn[1]*1000);
|
||||
arlsLock(udpIn[1]*1000 +1);
|
||||
}
|
||||
if (udpIn[0] == 1) //warls
|
||||
{
|
||||
@@ -257,9 +289,9 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
uint16_t pix = i + arlsOffset;
|
||||
if (pix < ledCount)
|
||||
{
|
||||
if (!arlsDisableGammaCorrection && useGammaCorrectionRGB)
|
||||
if (!arlsDisableGammaCorrection && strip.gammaCorrectCol)
|
||||
{
|
||||
strip.setPixelColor(pix, gamma8[r], gamma8[g], gamma8[b], gamma8[w]);
|
||||
strip.setPixelColor(pix, strip.gamma8(r), strip.gamma8(g), strip.gamma8(b), strip.gamma8(w));
|
||||
} else {
|
||||
strip.setPixelColor(pix, r, g, b, w);
|
||||
}
|
||||
|
@@ -21,12 +21,7 @@ void setAllLeds() {
|
||||
double d = briT*briMultiplier;
|
||||
int val = d/100;
|
||||
if (val > 255) val = 255;
|
||||
if (useGammaCorrectionBri)
|
||||
{
|
||||
strip.setBrightness(gamma8[val]);
|
||||
} else {
|
||||
strip.setBrightness(val);
|
||||
}
|
||||
strip.setBrightness(val);
|
||||
}
|
||||
if (!enableSecTransition)
|
||||
{
|
||||
@@ -40,14 +35,8 @@ void setAllLeds() {
|
||||
colorRGBtoRGBW(colT);
|
||||
colorRGBtoRGBW(colSecT);
|
||||
}
|
||||
if (useGammaCorrectionRGB)
|
||||
{
|
||||
strip.setColor(gamma8[colT[0]], gamma8[colT[1]], gamma8[colT[2]], gamma8[colT[3]]);
|
||||
strip.setSecondaryColor(gamma8[colSecT[0]], gamma8[colSecT[1]], gamma8[colSecT[2]], gamma8[colSecT[3]]);
|
||||
} else {
|
||||
strip.setColor(colT[0], colT[1], colT[2], colT[3]);
|
||||
strip.setSecondaryColor(colSecT[0], colSecT[1], colSecT[2], colSecT[3]);
|
||||
}
|
||||
strip.setColor(0, colT[0], colT[1], colT[2], colT[3]);
|
||||
strip.setColor(1, colSecT[0], colSecT[1], colSecT[2], colSecT[3]);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,11 +76,16 @@ void colorUpdated(int callMode)
|
||||
{
|
||||
if (nightlightActive && !nightlightActiveOld && callMode != 3 && callMode != 5)
|
||||
{
|
||||
notify(4); return;
|
||||
notify(4); interfaceUpdateCallMode = 4; return;
|
||||
}
|
||||
else if (fxChanged) {
|
||||
notify(6);
|
||||
if (callMode != 8) interfaceUpdateCallMode = 6;
|
||||
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
||||
}
|
||||
else if (fxChanged) notify(6);
|
||||
return; //no change
|
||||
}
|
||||
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
||||
if (callMode != 5 && nightlightActive && nightlightFade)
|
||||
{
|
||||
briNlT = bri;
|
||||
@@ -134,13 +128,8 @@ void colorUpdated(int callMode)
|
||||
}
|
||||
|
||||
if (callMode == 8) return;
|
||||
//only update Blynk and mqtt every 2 seconds to reduce lag
|
||||
if (millis() - lastInterfaceUpdate <= 2000)
|
||||
{
|
||||
interfaceUpdateCallMode = callMode;
|
||||
return;
|
||||
}
|
||||
updateInterfaces(callMode);
|
||||
//set flag to update blynk and mqtt
|
||||
interfaceUpdateCallMode = callMode;
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +142,7 @@ void updateInterfaces(uint8_t callMode)
|
||||
}
|
||||
#endif
|
||||
if (callMode != 9 && callMode != 5) updateBlynk();
|
||||
publishMqtt();
|
||||
doPublishMqtt = true;
|
||||
lastInterfaceUpdate = millis();
|
||||
}
|
||||
|
||||
@@ -166,6 +155,7 @@ void handleTransitions()
|
||||
updateInterfaces(interfaceUpdateCallMode);
|
||||
interfaceUpdateCallMode = 0; //disable
|
||||
}
|
||||
if (doPublishMqtt) publishMqtt();
|
||||
|
||||
if (transitionActive && transitionDelayTemp > 0)
|
||||
{
|
||||
|
@@ -16,12 +16,24 @@ void shortPressAction()
|
||||
|
||||
void handleButton()
|
||||
{
|
||||
#ifdef BTNPIN
|
||||
if (!buttonEnabled) return;
|
||||
|
||||
if (digitalRead(BTNPIN) == LOW && !buttonPressedBefore) //pressed
|
||||
if (digitalRead(BTNPIN) == LOW) //pressed
|
||||
{
|
||||
buttonPressedTime = millis();
|
||||
if (!buttonPressedBefore) buttonPressedTime = millis();
|
||||
buttonPressedBefore = true;
|
||||
|
||||
if (millis() - buttonPressedTime > 600) //long press
|
||||
{
|
||||
if (!buttonLongPressed)
|
||||
{
|
||||
if (macroLongPress) {applyMacro(macroLongPress);}
|
||||
else _setRandomColor(false,true);
|
||||
|
||||
buttonLongPressed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (digitalRead(BTNPIN) == HIGH && buttonPressedBefore) //released
|
||||
{
|
||||
@@ -30,13 +42,11 @@ void handleButton()
|
||||
bool doublePress = buttonWaitTime;
|
||||
buttonWaitTime = 0;
|
||||
|
||||
if (dur > 6000) {initAP();}
|
||||
else if (dur > 600) //long press
|
||||
if (dur > 6000) //long press
|
||||
{
|
||||
if (macroLongPress) {applyMacro(macroLongPress);}
|
||||
else _setRandomColor(false,true);
|
||||
initAP(true);
|
||||
}
|
||||
else { //short press
|
||||
else if (!buttonLongPressed) { //short press
|
||||
if (macroDoublePress)
|
||||
{
|
||||
if (doublePress) applyMacro(macroDoublePress);
|
||||
@@ -44,6 +54,7 @@ void handleButton()
|
||||
} else shortPressAction();
|
||||
}
|
||||
buttonPressedBefore = false;
|
||||
buttonLongPressed = false;
|
||||
}
|
||||
|
||||
if (buttonWaitTime && millis() - buttonWaitTime > 450 && !buttonPressedBefore)
|
||||
@@ -51,6 +62,7 @@ void handleButton()
|
||||
buttonWaitTime = 0;
|
||||
shortPressAction();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleIO()
|
||||
|
@@ -56,7 +56,7 @@ Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern
|
||||
|
||||
void handleNetworkTime()
|
||||
{
|
||||
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WiFi.status() == WL_CONNECTED)
|
||||
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WLED_CONNECTED)
|
||||
{
|
||||
if (millis() - ntpPacketSentTime > 10000)
|
||||
{
|
||||
|
@@ -5,18 +5,13 @@
|
||||
* https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch
|
||||
* https://github.com/probonopd/ESP8266HueEmulator
|
||||
*/
|
||||
void prepareIds() {
|
||||
escapedMac = WiFi.macAddress();
|
||||
escapedMac.replace(":", "");
|
||||
escapedMac.toLowerCase();
|
||||
}
|
||||
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
void onAlexaChange(EspalexaDevice* dev);
|
||||
|
||||
void alexaInit()
|
||||
{
|
||||
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
|
||||
if (alexaEnabled && WLED_CONNECTED)
|
||||
{
|
||||
if (espalexaDevice == nullptr) //only init once
|
||||
{
|
||||
@@ -31,7 +26,7 @@ void alexaInit()
|
||||
|
||||
void handleAlexa()
|
||||
{
|
||||
if (!alexaEnabled || WiFi.status() != WL_CONNECTED) return;
|
||||
if (!alexaEnabled || !WLED_CONNECTED) return;
|
||||
espalexa.loop();
|
||||
}
|
||||
|
||||
|
@@ -4,17 +4,6 @@
|
||||
#ifndef WLED_DISABLE_HUESYNC
|
||||
void handleHue()
|
||||
{
|
||||
if (hueClient != nullptr && millis() - hueLastRequestSent > huePollIntervalMs && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
hueLastRequestSent = millis();
|
||||
if (huePollingEnabled)
|
||||
{
|
||||
reconnectHue();
|
||||
} else {
|
||||
hueClient->close();
|
||||
if (hueError[0] == 'A') strcpy(hueError,"Inactive");
|
||||
}
|
||||
}
|
||||
if (hueReceived)
|
||||
{
|
||||
colorUpdated(7); hueReceived = false;
|
||||
@@ -25,11 +14,22 @@ void handleHue()
|
||||
hueNewKey = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WLED_CONNECTED || hueClient == nullptr || millis() - hueLastRequestSent < huePollIntervalMs) return;
|
||||
|
||||
hueLastRequestSent = millis();
|
||||
if (huePollingEnabled)
|
||||
{
|
||||
reconnectHue();
|
||||
} else {
|
||||
hueClient->close();
|
||||
if (hueError[0] == 'A') strcpy(hueError,"Inactive");
|
||||
}
|
||||
}
|
||||
|
||||
void reconnectHue()
|
||||
{
|
||||
if (WiFi.status() != WL_CONNECTED || !huePollingEnabled) return;
|
||||
if (!WLED_CONNECTED || !huePollingEnabled) return;
|
||||
DEBUG_PRINTLN("Hue reconnect");
|
||||
if (hueClient == nullptr) {
|
||||
hueClient = new AsyncClient();
|
||||
@@ -87,16 +87,16 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len)
|
||||
if (str == nullptr) return;
|
||||
str += 4;
|
||||
|
||||
StaticJsonBuffer<512> jb;
|
||||
StaticJsonDocument<512> root;
|
||||
if (str[0] == '[') //is JSON array
|
||||
{
|
||||
JsonArray& root = jb.parseArray(str);
|
||||
if (!root.success())
|
||||
auto error = deserializeJson(root, str);
|
||||
if (error)
|
||||
{
|
||||
strcpy(hueError,"JSON parsing error"); return;
|
||||
}
|
||||
|
||||
int hueErrorCode = root[0]["error"]["type"];
|
||||
|
||||
if (hueErrorCode)//hue bridge returned error
|
||||
{
|
||||
switch (hueErrorCode)
|
||||
@@ -130,8 +130,8 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len)
|
||||
if (str == nullptr) return;
|
||||
str = strstr(str,"{");
|
||||
|
||||
JsonObject& root = jb.parseObject(str);
|
||||
if (!root.success())
|
||||
auto error = deserializeJson(root, str);
|
||||
if (error)
|
||||
{
|
||||
strcpy(hueError,"JSON parsing error"); return;
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ byte blSat = 255;
|
||||
void initBlynk(const char* auth)
|
||||
{
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
if (WiFi.status() != WL_CONNECTED) return;
|
||||
if (!WLED_CONNECTED) return;
|
||||
blynkEnabled = (auth[0] != 0);
|
||||
if (blynkEnabled) Blynk.config(auth);
|
||||
#endif
|
||||
@@ -17,7 +17,7 @@ void initBlynk(const char* auth)
|
||||
void handleBlynk()
|
||||
{
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
if (WiFi.status() == WL_CONNECTED && blynkEnabled)
|
||||
if (WLED_CONNECTED && blynkEnabled)
|
||||
Blynk.run();
|
||||
#endif
|
||||
}
|
||||
@@ -25,7 +25,7 @@ void handleBlynk()
|
||||
void updateBlynk()
|
||||
{
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
if (onlyAP) return;
|
||||
if (!WLED_CONNECTED) return;
|
||||
Blynk.virtualWrite(V0, bri);
|
||||
//we need a RGB -> HSB convert here
|
||||
Blynk.virtualWrite(V3, bri? 1:0);
|
||||
|
@@ -2,12 +2,10 @@
|
||||
* MQTT communication protocol for home automation
|
||||
*/
|
||||
|
||||
#define WLED_MQTT_PORT 1883
|
||||
|
||||
void parseMQTTBriPayload(char* payload)
|
||||
{
|
||||
if (strcmp(payload, "ON") == 0 || strcmp(payload, "on") == 0) {bri = briLast; colorUpdated(1);}
|
||||
else if (strcmp(payload, "T" ) == 0 || strcmp(payload, "t" ) == 0) {toggleOnOff(); colorUpdated(1);}
|
||||
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
|
||||
else if (strstr(payload, "T" ) || strstr(payload, "t" )) {toggleOnOff(); colorUpdated(1);}
|
||||
else {
|
||||
uint8_t in = strtoul(payload, NULL, 10);
|
||||
if (in == 0 && bri > 0) briLast = bri;
|
||||
@@ -22,7 +20,7 @@ void onMqttConnect(bool sessionPresent)
|
||||
//(re)subscribe to required topics
|
||||
char subuf[38];
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
|
||||
|
||||
if (mqttDeviceTopic[0] != 0)
|
||||
{
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
@@ -45,16 +43,15 @@ void onMqttConnect(bool sessionPresent)
|
||||
mqtt->subscribe(subuf, 0);
|
||||
}
|
||||
|
||||
#ifdef WLED_ENABLE_HOMEASSISTANT_AUTODISCOVERY
|
||||
sendHADiscoveryMQTT();
|
||||
#endif
|
||||
publishMqtt();
|
||||
doSendHADiscovery = true;
|
||||
doPublishMqtt = true;
|
||||
DEBUG_PRINTLN("MQTT ready");
|
||||
}
|
||||
|
||||
|
||||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
|
||||
|
||||
DEBUG_PRINT("MQTT callb rec: ");
|
||||
DEBUG_PRINT("MQTT msg: ");
|
||||
DEBUG_PRINTLN(topic);
|
||||
DEBUG_PRINTLN(payload);
|
||||
|
||||
@@ -75,19 +72,19 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
||||
|
||||
void publishMqtt()
|
||||
{
|
||||
if (mqtt == NULL) return;
|
||||
if (!mqtt->connected()) return;
|
||||
doPublishMqtt = false;
|
||||
if (mqtt == nullptr || !mqtt->connected()) return;
|
||||
DEBUG_PRINTLN("Publish MQTT");
|
||||
|
||||
char s[10];
|
||||
char subuf[38];
|
||||
|
||||
|
||||
sprintf(s, "%ld", bri);
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/g");
|
||||
mqtt->publish(subuf, 0, true, s);
|
||||
|
||||
sprintf(s, "#%X", col[3]*16777216 + col[0]*65536 + col[1]*256 + col[2]);
|
||||
sprintf(s, "#%06X", col[3]*16777216 + col[0]*65536 + col[1]*256 + col[2]);
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/c");
|
||||
mqtt->publish(subuf, 0, true, s);
|
||||
@@ -101,10 +98,15 @@ void publishMqtt()
|
||||
|
||||
const char HA_static_JSON[] PROGMEM = R"=====(,"bri_val_tpl":"{{value}}","rgb_cmd_tpl":"{{'#%02x%02x%02x' | format(red, green, blue)}}","rgb_val_tpl":"{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}","qos":0,"opt":true,"pl_on":"ON","pl_off":"OFF","fx_val_tpl":"{{value}}","fx_list":[)=====";
|
||||
|
||||
void sendHADiscoveryMQTT(){
|
||||
char* buffer;
|
||||
|
||||
void sendHADiscoveryMQTT()
|
||||
{
|
||||
|
||||
#if ARDUINO_ARCH_ESP32 || LWIP_VERSION_MAJOR > 1
|
||||
/*
|
||||
|
||||
YYYY is discovery tipic
|
||||
YYYY is device topic
|
||||
XXXX is device name
|
||||
|
||||
Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
@@ -128,14 +130,19 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
"fx_val_tpl":"{{value}}",
|
||||
"fx_list":[
|
||||
"[FX=00] Solid",
|
||||
"[FX=01] Blink",
|
||||
"[FX=01] Blink",
|
||||
"[FX=02] ...",
|
||||
"[FX=79] Ripple"
|
||||
]
|
||||
}
|
||||
|
||||
*/
|
||||
char bufc[36], bufcol[38], bufg[36], bufapi[38], buffer[2500];
|
||||
doSendHADiscovery = false;
|
||||
if (mqtt == nullptr || !mqtt->connected()) return;
|
||||
buffer = new char[2400];
|
||||
if (!buffer) {delete[] buffer; return;}
|
||||
|
||||
char bufc[36], bufcol[38], bufg[36], bufapi[38];
|
||||
|
||||
strcpy(bufc, mqttDeviceTopic);
|
||||
strcpy(bufcol, mqttDeviceTopic);
|
||||
@@ -147,8 +154,7 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
strcat(bufg, "/g");
|
||||
strcat(bufapi, "/api");
|
||||
|
||||
StaticJsonBuffer<JSON_OBJECT_SIZE(9) +512> jsonBuffer;
|
||||
JsonObject& root = jsonBuffer.createObject();
|
||||
StaticJsonDocument<JSON_OBJECT_SIZE(9) +512> root;
|
||||
root["name"] = serverDescription;
|
||||
root["stat_t"] = bufc;
|
||||
root["cmd_t"] = mqttDeviceTopic;
|
||||
@@ -159,10 +165,9 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
root["fx_cmd_t"] = bufapi;
|
||||
root["fx_stat_t"] = bufapi;
|
||||
|
||||
size_t jlen = root.measureLength();
|
||||
char pubt[21 + sizeof(serverDescription) + 8];
|
||||
DEBUG_PRINTLN(jlen);
|
||||
root.printTo(buffer, jlen);
|
||||
size_t jlen = measureJson(root);
|
||||
//DEBUG_PRINTLN(jlen);
|
||||
serializeJson(root, buffer, jlen);
|
||||
|
||||
//add values which don't change
|
||||
strcpy_P(buffer + jlen -1, HA_static_JSON);
|
||||
@@ -180,11 +185,11 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
{
|
||||
if (pgm_read_byte(JSON_mode_names + j) == '\"' || j == jmnlen -1)
|
||||
{
|
||||
if (isNameStart)
|
||||
if (isNameStart)
|
||||
{
|
||||
nameStart = j +1;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
nameEnd = j;
|
||||
char mdnfx[64], mdn[56];
|
||||
@@ -193,11 +198,11 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
mdn[namelen] = 0;
|
||||
snprintf(mdnfx, 64, "\"[FX=%02d] %s\",", i, mdn);
|
||||
oappend(mdnfx);
|
||||
DEBUG_PRINTLN(mdnfx);
|
||||
//DEBUG_PRINTLN(mdnfx);
|
||||
i++;
|
||||
}
|
||||
isNameStart = !isNameStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
olen--;
|
||||
oappend("]}");
|
||||
@@ -205,28 +210,39 @@ Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
||||
DEBUG_PRINT("HA Discovery Sending >>");
|
||||
DEBUG_PRINTLN(buffer);
|
||||
|
||||
strcpy(pubt, "homeassistant/light/WLED_");
|
||||
strcat(pubt, escapedMac.c_str());
|
||||
char pubt[25 + 12 + 8];
|
||||
strcpy(pubt, "homeassistant/light/");
|
||||
strcat(pubt, mqttClientID);
|
||||
strcat(pubt, "/config");
|
||||
mqtt->publish(pubt, 0, true, buffer);
|
||||
bool success = mqtt->publish(pubt, 0, true, buffer);
|
||||
DEBUG_PRINTLN(success);
|
||||
yield();
|
||||
delete[] buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool initMqtt()
|
||||
{
|
||||
if (WiFi.status() != WL_CONNECTED) return false;
|
||||
if (mqttServer[0] == 0) return false;
|
||||
|
||||
lastMqttReconnectAttempt = millis();
|
||||
if (mqttServer[0] == 0 || !WLED_CONNECTED) return false;
|
||||
|
||||
if (mqtt == nullptr) {
|
||||
mqtt = new AsyncMqttClient();
|
||||
mqtt->onMessage(onMqttMessage);
|
||||
mqtt->onConnect(onMqttConnect);
|
||||
}
|
||||
if (mqtt->connected()) return true;
|
||||
|
||||
DEBUG_PRINTLN("Reconnecting MQTT");
|
||||
IPAddress mqttIP;
|
||||
if (mqttIP.fromString(mqttServer)) //see if server is IP or domain
|
||||
{
|
||||
mqtt->setServer(mqttIP, WLED_MQTT_PORT);
|
||||
mqtt->setServer(mqttIP, mqttPort);
|
||||
} else {
|
||||
mqtt->setServer(mqttServer, WLED_MQTT_PORT);
|
||||
mqtt->setServer(mqttServer, mqttPort);
|
||||
}
|
||||
mqtt->setClientId(escapedMac.c_str());
|
||||
mqtt->onMessage(onMqttMessage);
|
||||
mqtt->onConnect(onMqttConnect);
|
||||
mqtt->setClientId(mqttClientID);
|
||||
if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
|
||||
mqtt->connect();
|
||||
DEBUG_PRINTLN("MQTT ready");
|
||||
return true;
|
||||
}
|
||||
|
@@ -2,6 +2,34 @@
|
||||
* Server page definitions
|
||||
*/
|
||||
|
||||
//Is this an IP?
|
||||
bool isIp(String str) {
|
||||
for (size_t i = 0; i < str.length(); i++) {
|
||||
int c = str.charAt(i);
|
||||
if (c != '.' && (c < '0' || c > '9')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool captivePortal(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (ON_STA_FILTER(request)) return false; //only serve captive in AP mode
|
||||
String hostH;
|
||||
if (!request->hasHeader("Host")) return false;
|
||||
hostH = request->getHeader("Host")->value();
|
||||
|
||||
if (!isIp(hostH) && hostH.indexOf("wled.me") < 0 && hostH.indexOf(cmDNS) < 0) {
|
||||
DEBUG_PRINTLN("Captive portal");
|
||||
AsyncWebServerResponse *response = request->beginResponse(302);
|
||||
response->addHeader("Location", "http://4.3.2.1");
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void initServer()
|
||||
{
|
||||
//CORS compatiblity
|
||||
@@ -36,8 +64,8 @@ void initServer()
|
||||
|
||||
server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
if (!(wifiLock && otaLock)) handleSettingsSet(request, 1);
|
||||
serveMessage(request, 200,"WiFi settings saved.","Rebooting now...",255);
|
||||
doReboot = true;
|
||||
serveMessage(request, 200,"WiFi settings saved.","Reconnecting now...",255);
|
||||
forceReconnect = true;
|
||||
});
|
||||
|
||||
server.on("/settings/leds", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
@@ -70,10 +98,9 @@ void initServer()
|
||||
serveJson(request);
|
||||
});
|
||||
|
||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request, JsonVariant &json) {
|
||||
JsonObject& root = json.as<JsonObject>();
|
||||
if (!root.success()){request->send(500, "application/json", "{\"error\":\"Parsing failed\"}"); return;}
|
||||
deserializeState(root);
|
||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request, JsonObject root) {
|
||||
if (root.isNull()){request->send(500, "application/json", "{\"error\":\"Parsing failed\"}"); return;}
|
||||
if (deserializeState(root)) { serveJson(request); return; } //if JSON contains "v" (verbose response)
|
||||
request->send(200, "application/json", "{\"success\":true}");
|
||||
});
|
||||
server.addHandler(handler);
|
||||
@@ -162,6 +189,7 @@ void initServer()
|
||||
}
|
||||
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (captivePortal(request)) return;
|
||||
serveIndexOrWelcome(request);
|
||||
});
|
||||
|
||||
@@ -169,6 +197,7 @@ void initServer()
|
||||
server.onNotFound([](AsyncWebServerRequest *request){
|
||||
DEBUG_PRINTLN("Not-Found HTTP call:");
|
||||
DEBUG_PRINTLN("URI: " + request->url());
|
||||
if (captivePortal(request)) return;
|
||||
|
||||
//make API CORS compatible
|
||||
if (request->method() == HTTP_OPTIONS)
|
||||
@@ -305,7 +334,7 @@ String settingsProcessor(const String& var)
|
||||
getCSSColors();
|
||||
return String(buf);
|
||||
}
|
||||
if (var == "SCSS") return String(PAGE_settingsCss);
|
||||
if (var == "SCSS") return String(FPSTR(PAGE_settingsCss));
|
||||
return String();
|
||||
}
|
||||
|
||||
@@ -343,7 +372,7 @@ void serveSettings(AsyncWebServerRequest* request)
|
||||
case 4: request->send_P(200, "text/html", PAGE_settings_sync, settingsProcessor); break;
|
||||
case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break;
|
||||
case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break;
|
||||
case 255: request->send_P(200, "text/html", PAGE_welcome , settingsProcessor); break;
|
||||
case 255: request->send_P(200, "text/html", PAGE_welcome); break;
|
||||
default: request->send_P(200, "text/html", PAGE_settings , settingsProcessor);
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,10 @@
|
||||
* JSON API (De)serialization
|
||||
*/
|
||||
|
||||
void deserializeState(JsonObject& root)
|
||||
bool deserializeState(JsonObject root)
|
||||
{
|
||||
bool stateResponse = root["v"] | false;
|
||||
|
||||
bri = root["bri"] | bri;
|
||||
|
||||
bool on = root["on"] | (bri > 0);
|
||||
@@ -21,76 +23,114 @@ void deserializeState(JsonObject& root)
|
||||
int cy = root["pl"] | -1;
|
||||
presetCyclingEnabled = (cy >= 0);
|
||||
|
||||
JsonObject& nl = root["nl"];
|
||||
JsonObject nl = root["nl"];
|
||||
nightlightActive = nl["on"] | nightlightActive;
|
||||
nightlightDelayMins = nl["dur"] | nightlightDelayMins;
|
||||
nightlightFade = nl["fade"] | nightlightFade;
|
||||
nightlightTargetBri = nl["tbri"] | nightlightTargetBri;
|
||||
|
||||
JsonObject& udpn = root["udpn"];
|
||||
JsonObject udpn = root["udpn"];
|
||||
notifyDirect = udpn["send"] | notifyDirect;
|
||||
receiveNotifications = udpn["recv"] | receiveNotifications;
|
||||
bool noNotification = udpn["nn"]; //send no notification just for this request
|
||||
|
||||
int timein = root["time"] | -1;
|
||||
if (timein != -1) setTime(timein);
|
||||
|
||||
int it = 0;
|
||||
JsonArray& segs = root["seg"];
|
||||
for (JsonObject& elem : segs)
|
||||
JsonArray segs = root["seg"];
|
||||
for (JsonObject elem : segs)
|
||||
{
|
||||
byte id = elem["id"] | it;
|
||||
if (id < strip.getMaxSegments())
|
||||
{
|
||||
WS2812FX::Segment& seg = strip.getSegment(id);
|
||||
/*uint16_t start = elem["start"] | seg.start;
|
||||
uint16_t start = elem["start"] | seg.start;
|
||||
int stop = elem["stop"] | -1;
|
||||
|
||||
if (stop < 0) {
|
||||
uint16_t len = elem["len"];
|
||||
stop = (len > 0) ? start + len : seg.stop;
|
||||
}
|
||||
strip.setSegment(id, start, stop);*/
|
||||
strip.setSegment(id, start, stop);
|
||||
|
||||
JsonArray& colarr = elem["col"];
|
||||
if (colarr.success())
|
||||
JsonArray colarr = elem["col"];
|
||||
if (!colarr.isNull())
|
||||
{
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
{
|
||||
JsonArray& colX = colarr[i];
|
||||
if (!colX.success()) break;
|
||||
JsonArray colX = colarr[i];
|
||||
if (colX.isNull()) break;
|
||||
byte sz = colX.size();
|
||||
if (sz > 0 && sz < 5)
|
||||
{
|
||||
int rgbw[] = {0,0,0,0};
|
||||
byte cp = colX.copyTo(rgbw);
|
||||
byte cp = copyArray(colX, rgbw);
|
||||
seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
|
||||
if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0;
|
||||
//temporary
|
||||
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
|
||||
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
|
||||
if (id == 0) //temporary
|
||||
{
|
||||
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
|
||||
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte fx = elem["fx"] | seg.mode;
|
||||
if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(fx);
|
||||
if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
|
||||
seg.speed = elem["sx"] | seg.speed;
|
||||
seg.intensity = elem["ix"] | seg.intensity;
|
||||
byte pal = elem["pal"] | seg.palette;
|
||||
if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
||||
seg.setOption(0, elem["sel"] | seg.getOption(0));
|
||||
seg.setOption(1, elem["rev"] | seg.getOption(1));
|
||||
seg.palette = elem["pal"] | seg.palette;
|
||||
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
||||
seg.setOption(0, elem["sel"] | seg.getOption(0)); //selected
|
||||
seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse
|
||||
//int cln = seg_0["cln"];
|
||||
//temporary
|
||||
effectCurrent = seg.mode;
|
||||
effectSpeed = seg.speed;
|
||||
effectIntensity = seg.intensity;
|
||||
effectPalette = seg.palette;
|
||||
if (id == 0) {
|
||||
effectCurrent = seg.mode;
|
||||
effectSpeed = seg.speed;
|
||||
effectIntensity = seg.intensity;
|
||||
effectPalette = seg.palette;
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
colorUpdated(noNotification ? 5:1);
|
||||
|
||||
return stateResponse;
|
||||
}
|
||||
|
||||
void serializeState(JsonObject& root)
|
||||
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id)
|
||||
{
|
||||
root["id"] = id;
|
||||
root["start"] = seg.start;
|
||||
root["stop"] = seg.stop;
|
||||
root["len"] = seg.stop - seg.start;
|
||||
|
||||
JsonArray colarr = root.createNestedArray("col");
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
{
|
||||
JsonArray colX = colarr.createNestedArray();
|
||||
colX.add((seg.colors[i] >> 16) & 0xFF);
|
||||
colX.add((seg.colors[i] >> 8) & 0xFF);
|
||||
colX.add((seg.colors[i]) & 0xFF);
|
||||
if (useRGBW)
|
||||
colX.add((seg.colors[i] >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
root["fx"] = seg.mode;
|
||||
root["sx"] = seg.speed;
|
||||
root["ix"] = seg.intensity;
|
||||
root["pal"] = seg.palette;
|
||||
root["sel"] = seg.isSelected();
|
||||
root["rev"] = seg.getOption(1);
|
||||
root["cln"] = -1;
|
||||
}
|
||||
|
||||
|
||||
void serializeState(JsonObject root)
|
||||
{
|
||||
root["on"] = (bri > 0);
|
||||
root["bri"] = briLast;
|
||||
@@ -99,66 +139,37 @@ void serializeState(JsonObject& root)
|
||||
root["ps"] = -1; //
|
||||
root["pl"] = (presetCyclingEnabled) ? 0: -1;
|
||||
|
||||
JsonObject& nl = root.createNestedObject("nl");
|
||||
JsonObject nl = root.createNestedObject("nl");
|
||||
nl["on"] = nightlightActive;
|
||||
nl["dur"] = nightlightDelayMins;
|
||||
nl["fade"] = nightlightFade;
|
||||
nl["tbri"] = nightlightTargetBri;
|
||||
|
||||
JsonObject& udpn = root.createNestedObject("udpn");
|
||||
JsonObject udpn = root.createNestedObject("udpn");
|
||||
udpn["send"] = notifyDirect;
|
||||
udpn["recv"] = receiveNotifications;
|
||||
|
||||
JsonArray& seg = root.createNestedArray("seg");
|
||||
JsonObject& seg0 = seg.createNestedObject();
|
||||
serializeSegment(seg0);
|
||||
}
|
||||
|
||||
void serializeSegment(JsonObject& root)
|
||||
{
|
||||
WS2812FX::Segment seg = strip.getSegment(0);
|
||||
|
||||
//root["id"] = i;
|
||||
root["start"] = seg.start;
|
||||
root["stop"] = seg.stop;
|
||||
root["len"] = seg.stop - seg.start;
|
||||
|
||||
JsonArray& colarr = root.createNestedArray("col");
|
||||
|
||||
//temporary
|
||||
JsonArray& c0 = colarr.createNestedArray();
|
||||
c0.add(col[0]); c0.add(col[1]); c0.add(col[2]); if (useRGBW) c0.add(col[3]);
|
||||
JsonArray& c1 = colarr.createNestedArray();
|
||||
c1.add(colSec[0]); c1.add(colSec[1]); c1.add(colSec[2]); if (useRGBW) c1.add(colSec[3]);
|
||||
//set i back to 0 once temporary is removed!
|
||||
for (uint8_t i = 2; i < 3; i++)
|
||||
JsonArray seg = root.createNestedArray("seg");
|
||||
for (byte s = 0; s < strip.getMaxSegments(); s++)
|
||||
{
|
||||
JsonArray& colX = colarr.createNestedArray();
|
||||
colX.add((seg.colors[i] >> 16) & 0xFF);
|
||||
colX.add((seg.colors[i] >> 8) & 0xFF);
|
||||
colX.add((seg.colors[i] ) & 0xFF);
|
||||
if (useRGBW)
|
||||
colX.add((seg.colors[i] >> 24) & 0xFF);
|
||||
WS2812FX::Segment sg = strip.getSegment(s);
|
||||
if (sg.isActive())
|
||||
{
|
||||
JsonObject seg0 = seg.createNestedObject();
|
||||
serializeSegment(seg0, sg, s);
|
||||
}
|
||||
}
|
||||
|
||||
root["fx"] = seg.mode;
|
||||
root["sx"] = seg.speed;
|
||||
root["ix"] = seg.intensity;
|
||||
root["pal"] = seg.palette;
|
||||
root["sel"] = true; //seg.getOption(0);
|
||||
root["rev"] = seg.getOption(1);
|
||||
root["cln"] = -1;
|
||||
}
|
||||
|
||||
void serializeInfo(JsonObject& root)
|
||||
void serializeInfo(JsonObject root)
|
||||
{
|
||||
root["ver"] = versionString;
|
||||
root["vid"] = VERSION;
|
||||
|
||||
JsonObject& leds = root.createNestedObject("leds");
|
||||
JsonObject leds = root.createNestedObject("leds");
|
||||
leds["count"] = ledCount;
|
||||
leds["rgbw"] = useRGBW;
|
||||
JsonArray& leds_pin = leds.createNestedArray("pin");
|
||||
JsonArray leds_pin = leds.createNestedArray("pin");
|
||||
leds_pin.add(LEDPIN);
|
||||
|
||||
leds["pwr"] = strip.currentMilliamps;
|
||||
@@ -235,7 +246,7 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse();
|
||||
JsonObject& doc = response->getRoot();
|
||||
JsonObject doc = response->getRoot();
|
||||
|
||||
switch (subJson)
|
||||
{
|
||||
@@ -244,12 +255,12 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
case 2: //info
|
||||
serializeInfo(doc); break;
|
||||
default: //all
|
||||
JsonObject& state = doc.createNestedObject("state");
|
||||
JsonObject state = doc.createNestedObject("state");
|
||||
serializeState(state);
|
||||
JsonObject& info = doc.createNestedObject("info");
|
||||
JsonObject info = doc.createNestedObject("info");
|
||||
serializeInfo(info);
|
||||
doc["effects"] = RawJson(String(JSON_mode_names));
|
||||
doc["palettes"] = RawJson(String(JSON_palette_names));
|
||||
doc["effects"] = serialized((const __FlashStringHelper*)JSON_mode_names);
|
||||
doc["palettes"] = serialized((const __FlashStringHelper*)JSON_palette_names);
|
||||
}
|
||||
|
||||
response->setLength();
|
||||
|
Reference in New Issue
Block a user