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