mirror of
https://github.com/wled/WLED.git
synced 2025-07-20 17:26:32 +00:00
Merge branch 'master' into sync-seg
This commit is contained in:
commit
e54819e7e5
@ -12,7 +12,7 @@
|
|||||||
; default_envs = travis_esp8266, travis_esp32
|
; default_envs = travis_esp8266, travis_esp32
|
||||||
|
|
||||||
# Release binaries
|
# Release binaries
|
||||||
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth
|
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32s2_saola
|
||||||
|
|
||||||
# Build everything
|
# Build everything
|
||||||
; default_envs = esp32dev, esp8285_4CH_MagicHome, esp8285_4CH_H801, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, travis_esp8266, travis_esp32, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_5CH_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips
|
; default_envs = esp32dev, esp8285_4CH_MagicHome, esp8285_4CH_H801, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, travis_esp8266, travis_esp32, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_5CH_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips
|
||||||
@ -54,13 +54,14 @@ extra_configs =
|
|||||||
arduino_core_2_6_3 = espressif8266@2.3.3
|
arduino_core_2_6_3 = espressif8266@2.3.3
|
||||||
arduino_core_2_7_4 = espressif8266@2.6.2
|
arduino_core_2_7_4 = espressif8266@2.6.2
|
||||||
arduino_core_3_0_0 = espressif8266@3.0.0
|
arduino_core_3_0_0 = espressif8266@3.0.0
|
||||||
|
arduino_core_3_0_2 = espressif8266@3.2.0
|
||||||
|
|
||||||
# Development platforms
|
# Development platforms
|
||||||
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
|
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
|
||||||
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
|
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
|
||||||
|
|
||||||
# Platform to use for ESP8266
|
# Platform to use for ESP8266
|
||||||
platform_wled_default = ${common.arduino_core_2_7_4}
|
platform_wled_default = ${common.arduino_core_3_0_2}
|
||||||
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
|
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
|
||||||
platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
||||||
platformio/toolchain-xtensa @ ~2.40802.200502
|
platformio/toolchain-xtensa @ ~2.40802.200502
|
||||||
@ -105,6 +106,7 @@ build_flags =
|
|||||||
-DBEARSSL_SSL_BASIC
|
-DBEARSSL_SSL_BASIC
|
||||||
-D CORE_DEBUG_LEVEL=0
|
-D CORE_DEBUG_LEVEL=0
|
||||||
-D NDEBUG
|
-D NDEBUG
|
||||||
|
-Dregister=
|
||||||
#build_flags for the IRremoteESP8266 library (enabled decoders have to appear here)
|
#build_flags for the IRremoteESP8266 library (enabled decoders have to appear here)
|
||||||
-D _IR_ENABLE_DEFAULT_=false
|
-D _IR_ENABLE_DEFAULT_=false
|
||||||
-D DECODE_HASH=true
|
-D DECODE_HASH=true
|
||||||
@ -162,8 +164,7 @@ lib_compat_mode = strict
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
fastled/FastLED @ 3.4.0
|
fastled/FastLED @ 3.4.0
|
||||||
IRremoteESP8266 @ 2.7.18
|
IRremoteESP8266 @ 2.7.18
|
||||||
https://github.com/lorol/LITTLEFS.git
|
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.4
|
||||||
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.2
|
|
||||||
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
||||||
#TFT_eSPI
|
#TFT_eSPI
|
||||||
#For use SSD1306 OLED display uncomment following
|
#For use SSD1306 OLED display uncomment following
|
||||||
@ -185,6 +186,7 @@ build_flags =
|
|||||||
-DFP_IN_IROM
|
-DFP_IN_IROM
|
||||||
;-Wno-deprecated-declarations
|
;-Wno-deprecated-declarations
|
||||||
;-Wno-register
|
;-Wno-register
|
||||||
|
-Wno-misleading-indentation
|
||||||
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
|
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
|
||||||
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
|
-DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703
|
||||||
; lwIP 2 - Higher Bandwidth no Features
|
; lwIP 2 - Higher Bandwidth no Features
|
||||||
@ -198,6 +200,7 @@ build_flags =
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
|
https://github.com/lorol/LITTLEFS.git
|
||||||
# ESPAsyncTCP @ 1.2.0
|
# ESPAsyncTCP @ 1.2.0
|
||||||
ESPAsyncUDP
|
ESPAsyncUDP
|
||||||
makuna/NeoPixelBus @ 2.6.7 # 2.6.5/2.6.6 and newer do not compile on ESP core < 3.0.0
|
makuna/NeoPixelBus @ 2.6.7 # 2.6.5/2.6.6 and newer do not compile on ESP core < 3.0.0
|
||||||
@ -212,13 +215,13 @@ default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
|||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
|
https://github.com/lorol/LITTLEFS.git
|
||||||
makuna/NeoPixelBus @ 2.6.7
|
makuna/NeoPixelBus @ 2.6.7
|
||||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||||
|
|
||||||
[esp32s2]
|
[esp32s2]
|
||||||
build_flags = -g
|
build_flags = -g
|
||||||
-DARDUINO_ARCH_ESP32
|
-DARDUINO_ARCH_ESP32
|
||||||
-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
|
||||||
-DARDUINO_ARCH_ESP32S2
|
-DARDUINO_ARCH_ESP32S2
|
||||||
-DCONFIG_IDF_TARGET_ESP32S2
|
-DCONFIG_IDF_TARGET_ESP32S2
|
||||||
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
||||||
@ -314,14 +317,13 @@ lib_deps = ${esp32.lib_deps}
|
|||||||
board_build.partitions = ${esp32.default_partitions}
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
|
||||||
[env:esp32s2_saola]
|
[env:esp32s2_saola]
|
||||||
board = esp32dev
|
board = esp32-s2-saola-1
|
||||||
board_build.mcu = esp32s2
|
platform = https://github.com/tasmota/platform-espressif32/releases/download/v3.4.1/Tasmota-platform-espressif32.zip
|
||||||
platform = espressif32
|
|
||||||
platform_packages =
|
platform_packages =
|
||||||
toolchain-xtensa32s2
|
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.2
|
||||||
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.0-alpha1
|
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||||
|
board_build.flash_mode = qio
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
lib_deps = ${esp32s2.lib_deps}
|
lib_deps = ${esp32s2.lib_deps}
|
||||||
|
@ -111,17 +111,17 @@ class Animated_Staircase : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i >= onIndex && i < offIndex) {
|
if (i >= onIndex && i < offIndex) {
|
||||||
segments->setOption(SEG_OPTION_ON, 1, 1);
|
segments->setOption(SEG_OPTION_ON, 1, i);
|
||||||
|
|
||||||
// We may need to copy mode and colors from segment 0 to make sure
|
// We may need to copy mode and colors from segment 0 to make sure
|
||||||
// changes are propagated even when the config is changed during a wipe
|
// changes are propagated even when the config is changed during a wipe
|
||||||
// segments->mode = mainsegment.mode;
|
// segments->mode = mainsegment.mode;
|
||||||
// segments->colors[0] = mainsegment.colors[0];
|
// segments->colors[0] = mainsegment.colors[0];
|
||||||
} else {
|
} else {
|
||||||
segments->setOption(SEG_OPTION_ON, 0, 1);
|
segments->setOption(SEG_OPTION_ON, 0, i);
|
||||||
}
|
}
|
||||||
// Always mark segments as "transitional", we are animating the staircase
|
// Always mark segments as "transitional", we are animating the staircase
|
||||||
segments->setOption(SEG_OPTION_TRANSITIONAL, 1, 1);
|
segments->setOption(SEG_OPTION_TRANSITIONAL, 1, i);
|
||||||
}
|
}
|
||||||
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
||||||
}
|
}
|
||||||
@ -296,7 +296,7 @@ class Animated_Staircase : public Usermod {
|
|||||||
maxSegmentId = i - 1;
|
maxSegmentId = i - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
segments->setOption(SEG_OPTION_ON, 1, 1);
|
segments->setOption(SEG_OPTION_ON, 1, i);
|
||||||
}
|
}
|
||||||
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
colorUpdated(CALL_MODE_DIRECT_CHANGE);
|
||||||
DEBUG_PRINTLN(F("Animated Staircase disabled."));
|
DEBUG_PRINTLN(F("Animated Staircase disabled."));
|
||||||
|
@ -61,10 +61,10 @@ class QuinLEDAnPentaUsermod : public Usermod
|
|||||||
float shtLastKnownHumidity = 0;
|
float shtLastKnownHumidity = 0;
|
||||||
|
|
||||||
// Pin/IO vars
|
// Pin/IO vars
|
||||||
const int8_t anPentaPins[5] = {14, 13, 12, 4, 2};
|
const int8_t anPentaLEDPins[5] = {14, 13, 12, 4, 2};
|
||||||
int8_t oledSpiClk = 15;
|
int8_t oledSpiClk = 15;
|
||||||
int8_t oledSpiData = 16;
|
int8_t oledSpiData = 16;
|
||||||
int8_t oledSpiCs = 0;
|
int8_t oledSpiCs = 27;
|
||||||
int8_t oledSpiDc = 32;
|
int8_t oledSpiDc = 32;
|
||||||
int8_t oledSpiRst = 33;
|
int8_t oledSpiRst = 33;
|
||||||
int8_t shtSda = 1;
|
int8_t shtSda = 1;
|
||||||
@ -75,7 +75,7 @@ class QuinLEDAnPentaUsermod : public Usermod
|
|||||||
{
|
{
|
||||||
for(int8_t i = 0; i <= 4; i++)
|
for(int8_t i = 0; i <= 4; i++)
|
||||||
{
|
{
|
||||||
if(anPentaPins[i] == pin)
|
if(anPentaLEDPins[i] == pin)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -313,7 +313,7 @@ class QuinLEDAnPentaUsermod : public Usermod
|
|||||||
byte drawnLines = 0;
|
byte drawnLines = 0;
|
||||||
for (int8_t app = 0; app <= 4; app++) {
|
for (int8_t app = 0; app <= 4; app++) {
|
||||||
for (int8_t clp = 0; clp <= 4; clp++) {
|
for (int8_t clp = 0; clp <= 4; clp++) {
|
||||||
if (anPentaPins[app] == currentLedPins[clp]) {
|
if (anPentaLEDPins[app] == currentLedPins[clp]) {
|
||||||
char charCurrentLedcReads[17];
|
char charCurrentLedcReads[17];
|
||||||
sprintf(charCurrentLedcReads, "LED %d:", app+1);
|
sprintf(charCurrentLedcReads, "LED %d:", app+1);
|
||||||
if (oledUseProgressBars) {
|
if (oledUseProgressBars) {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
# QuinLED-An-Penta
|
# QuinLED-An-Penta
|
||||||
The (un)official usermod to get the best out of the QuinLED-An-Penta, like using the OLED and the SHT30 temperature/humidity sensor.
|
The (un)official usermod to get the best out of the QuinLED-An-Penta (https://quinled.info/quinled-an-penta/), like using the OLED and the SHT30 temperature/humidity sensor.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
* "u8gs" by olikraus, v2.28 or higher: https://github.com/olikraus/u8g2
|
* "u8gs" by olikraus, v2.28 or higher: https://github.com/olikraus/u8g2
|
||||||
* "SHT85" by Rob Tillaart, v0.2 or higher: https://github.com/RobTillaart/SHT85
|
* "SHT85" by Rob Tillaart, v0.2 or higher: https://github.com/RobTillaart/SHT85
|
||||||
|
|
||||||
## Usermod installation
|
## Usermod installation
|
||||||
Simply copy the below block (build task) to your `platformio_override.ini` and compile WLED using this new build task. Or use an existing one and add the buildflag `-D QUINLED_AN_PENTA`.
|
Simply copy the below block (build task) to your `platformio_override.ini` and compile WLED using this new build task. Or use an existing one, add the buildflag `-D QUINLED_AN_PENTA` and the below library dependencies.
|
||||||
|
|
||||||
ESP32 (**without** ethernet):
|
ESP32 (**without** ethernet):
|
||||||
```
|
```
|
||||||
@ -33,14 +33,19 @@ This mod has been optimized for an SSD1306 driven 128x64 OLED. Using a smaller O
|
|||||||
I highly recommend using these "two color monochromatic OLEDs", which have the first 16 pixels in a different color than the other 48, e.g. a yellow/blue OLED.
|
I highly recommend using these "two color monochromatic OLEDs", which have the first 16 pixels in a different color than the other 48, e.g. a yellow/blue OLED.
|
||||||
Also note, you need to have an **SPI** driven OLED, **not i2c**!
|
Also note, you need to have an **SPI** driven OLED, **not i2c**!
|
||||||
|
|
||||||
|
### Limitations combined with Ethernet
|
||||||
|
The initial development of this mod had been done with a beta version of the QuinLED-An-Penta, which had a different IO layout for the OLED: The CS pin used to be IO_0, but has been changed to IO27 with the first v1 public release. Unfortunately, IO27 is used by the Ethernet boards, so WLED will not let you enable the OLED screen, if you're using it with Ethernet. This unfortunately makes the development I've done to support/show Ethernet information void, as it cannot be used.
|
||||||
|
However (and I've not tried this, as I don't own a v1 board): You can try to modify this mod and try to use IO27 for the OLED and share it with the Ethernet board. It is "just" the chip select pin, so there is a chance that both can coexist and use the same IO. You need to skip WLEDs PinManager for the CS pin, so WLED will not block using it. If you don't know how this works: Leave it. If you know what I'm talking about: Try it and please let me know on the Intermit.Tech (QuinLED) Discord server: https://discord.gg/WdbAauG
|
||||||
|
|
||||||
### My OLED flickers after some time, what should I do?
|
### My OLED flickers after some time, what should I do?
|
||||||
That's a tricky one: During development I saw that the OLED sometimes starts to "bug out" / flicker and won't work anymore. This seems to be caused by the high PWM interference the board produces. It seems to loose it's settings and then doesn't know how to draw anymore. Turns out the only way to fix this is to call the libraries `begin()` method again which will re-initialize the display.
|
That's a tricky one: During development I saw that the OLED sometimes starts to "bug out" / flicker and won't work anymore. This seems to be caused by the high PWM interference the board produces. It seems to loose its settings and then doesn't know how to draw anymore. Turns out the only way to fix this is to call the libraries `begin()` method again which will re-initialize the display.
|
||||||
If you're facing this issue, you can enable a setting I've added which will call the `begin()` roughly every 60 seconds between a page change. This will make the page change take ~500ms, but will fix the display.
|
If you're facing this issue, you can enable a setting I've added which will call the `begin()` roughly every 60 seconds between a page change. This will make the page change take ~500ms, but will fix the display.
|
||||||
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
Navigate to the "Config" and then to the "Usermods" section. If you compiled WLED with `-D QUINLED_AN_PENTA`, you will see the config for it there:
|
Navigate to the "Config" and then to the "Usermods" section. If you compiled WLED with `-D QUINLED_AN_PENTA`, you will see the config for it there:
|
||||||
* Enable-OLED:
|
* Enable-OLED:
|
||||||
* What it does: Enabled the optional SPI driven OLED that can be mounted to the 7-pin female header
|
* What it does: Enables the optional SPI driven OLED that can be mounted to the 7-pin female header. Won't work with Ethernet, read above.
|
||||||
* Possible values: Enabled/Disabled
|
* Possible values: Enabled/Disabled
|
||||||
* Default: Disabled
|
* Default: Disabled
|
||||||
* OLED-Use-Progress-Bars:
|
* OLED-Use-Progress-Bars:
|
||||||
@ -60,10 +65,15 @@ Navigate to the "Config" and then to the "Usermods" section. If you compiled WLE
|
|||||||
* Possible values: Enabled/Disabled
|
* Possible values: Enabled/Disabled
|
||||||
* Default: Disabled
|
* Default: Disabled
|
||||||
* Enable-SHT30-Temp-Humidity-Sensor:
|
* Enable-SHT30-Temp-Humidity-Sensor:
|
||||||
* What it does: Enabled the onboard SHT30 temperature and humidity sensor
|
* What it does: Enables the onboard SHT30 temperature and humidity sensor
|
||||||
* Possible values: Enabled/Disabled
|
* Possible values: Enabled/Disabled
|
||||||
* Default: Disabled
|
* Default: Disabled
|
||||||
|
|
||||||
## Change log
|
## Change log
|
||||||
|
2021-12
|
||||||
|
* Adjusted IO layout to match An-Penta v1r1
|
||||||
2021-10
|
2021-10
|
||||||
* First implementation.
|
* First implementation.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
ezcGman | Andy: Find me on the Intermit.Tech (QuinLED) Discord server: https://discord.gg/WdbAauG
|
@ -65,7 +65,8 @@ private:
|
|||||||
{ 1, 0, 1, 1, 1, 1, 1 }, // 6
|
{ 1, 0, 1, 1, 1, 1, 1 }, // 6
|
||||||
{ 1, 1, 1, 0, 0, 0, 0 }, // 7
|
{ 1, 1, 1, 0, 0, 0, 0 }, // 7
|
||||||
{ 1, 1, 1, 1, 1, 1, 1 }, // 8
|
{ 1, 1, 1, 1, 1, 1, 1 }, // 8
|
||||||
{ 1, 1, 1, 1, 0, 1, 1 } // 9
|
{ 1, 1, 1, 1, 0, 1, 1 }, // 9
|
||||||
|
{ 0, 0, 0, 0, 0, 0, 0 } // blank
|
||||||
};
|
};
|
||||||
|
|
||||||
//String to reduce flash memory usage
|
//String to reduce flash memory usage
|
||||||
@ -100,39 +101,39 @@ private:
|
|||||||
switch (umSSDRDisplayMask[index]) {
|
switch (umSSDRDisplayMask[index]) {
|
||||||
case 'h':
|
case 'h':
|
||||||
timeVar = hourFormat12(localTime);
|
timeVar = hourFormat12(localTime);
|
||||||
_showElements(&umSSDRHours, timeVar, 0);
|
_showElements(&umSSDRHours, timeVar, 0, 1);
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
timeVar = hour(localTime);
|
timeVar = hour(localTime);
|
||||||
_showElements(&umSSDRHours, timeVar, 0);
|
_showElements(&umSSDRHours, timeVar, 0, 1);
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
timeVar = hour(localTime) + 1;
|
timeVar = hour(localTime) + 1;
|
||||||
_showElements(&umSSDRHours, timeVar, 0);
|
_showElements(&umSSDRHours, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
timeVar = minute(localTime);
|
timeVar = minute(localTime);
|
||||||
_showElements(&umSSDRMinutes, timeVar, 0);
|
_showElements(&umSSDRMinutes, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
timeVar = second(localTime);
|
timeVar = second(localTime);
|
||||||
_showElements(&umSSDRSeconds, timeVar, 0);
|
_showElements(&umSSDRSeconds, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
timeVar = day(localTime);
|
timeVar = day(localTime);
|
||||||
_showElements(&umSSDRDays, timeVar, 0);
|
_showElements(&umSSDRDays, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
timeVar = month(localTime);
|
timeVar = month(localTime);
|
||||||
_showElements(&umSSDRMonths, timeVar, 0);
|
_showElements(&umSSDRMonths, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
timeVar = second(localTime);
|
timeVar = second(localTime);
|
||||||
_showElements(&umSSDRYears, timeVar, 0);
|
_showElements(&umSSDRYears, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 'Y':
|
case 'Y':
|
||||||
timeVar = year(localTime);
|
timeVar = year(localTime);
|
||||||
_showElements(&umSSDRYears, timeVar, 0);
|
_showElements(&umSSDRYears, timeVar, 0, 0);
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
if (!colonsDone) { // only call _setColons once as all colons are printed when the first colon is found
|
if (!colonsDone) { // only call _setColons once as all colons are printed when the first colon is found
|
||||||
@ -148,14 +149,16 @@ private:
|
|||||||
void _setColons() {
|
void _setColons() {
|
||||||
if ( umSSDRColonblink ) {
|
if ( umSSDRColonblink ) {
|
||||||
if ( second(localTime) % 2 == 0 ) {
|
if ( second(localTime) % 2 == 0 ) {
|
||||||
_showElements(&umSSDRColons, 0, 1);
|
_showElements(&umSSDRColons, 0, 1, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_showElements(&umSSDRColons, 0, 1);
|
_showElements(&umSSDRColons, 0, 1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showElements(String *map, int timevar, bool isColon) {
|
void _showElements(String *map, int timevar, bool isColon, bool removeZero
|
||||||
|
|
||||||
|
) {
|
||||||
if (!(*map).equals("") && !(*map) == NULL) {
|
if (!(*map).equals("") && !(*map) == NULL) {
|
||||||
int length = String(timevar).length();
|
int length = String(timevar).length();
|
||||||
bool addZero = false;
|
bool addZero = false;
|
||||||
@ -165,8 +168,16 @@ private:
|
|||||||
}
|
}
|
||||||
int timeArr[length];
|
int timeArr[length];
|
||||||
if(addZero) {
|
if(addZero) {
|
||||||
|
if(removeZero)
|
||||||
|
{
|
||||||
|
timeArr[1] = 10;
|
||||||
|
timeArr[0] = timevar;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
timeArr[1] = 0;
|
timeArr[1] = 0;
|
||||||
timeArr[0] = timevar;
|
timeArr[0] = timevar;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (timevar) {
|
while (timevar) {
|
||||||
|
@ -2091,7 +2091,7 @@ uint16_t WS2812FX::mode_colortwinkle()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME_FIXED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2876,7 +2876,7 @@ uint16_t WS2812FX::candle(bool multi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME_FIXED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t WS2812FX::mode_candle()
|
uint16_t WS2812FX::mode_candle()
|
||||||
|
10
wled00/FX.h
10
wled00/FX.h
@ -48,7 +48,8 @@
|
|||||||
|
|
||||||
/* Not used in all effects yet */
|
/* Not used in all effects yet */
|
||||||
#define WLED_FPS 42
|
#define WLED_FPS 42
|
||||||
#define FRAMETIME (1000/WLED_FPS)
|
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
||||||
|
#define FRAMETIME _frametime
|
||||||
|
|
||||||
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
@ -71,7 +72,7 @@
|
|||||||
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS)
|
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS)
|
||||||
|
|
||||||
#define LED_SKIP_AMOUNT 1
|
#define LED_SKIP_AMOUNT 1
|
||||||
#define MIN_SHOW_DELAY 15
|
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
|
||||||
|
|
||||||
#define NUM_COLORS 3 /* number of colors per segment */
|
#define NUM_COLORS 3 /* number of colors per segment */
|
||||||
#define SEGMENT _segments[_segment_index]
|
#define SEGMENT _segments[_segment_index]
|
||||||
@ -648,12 +649,14 @@ class WS2812FX {
|
|||||||
calcGammaTable(float),
|
calcGammaTable(float),
|
||||||
trigger(void),
|
trigger(void),
|
||||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0, uint16_t offset = UINT16_MAX),
|
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 0, uint8_t spacing = 0, uint16_t offset = UINT16_MAX),
|
||||||
|
restartRuntime(),
|
||||||
resetSegments(),
|
resetSegments(),
|
||||||
makeAutoSegments(),
|
makeAutoSegments(),
|
||||||
fixInvalidSegments(),
|
fixInvalidSegments(),
|
||||||
setPixelColor(uint16_t n, uint32_t c),
|
setPixelColor(uint16_t n, uint32_t c),
|
||||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||||
show(void),
|
show(void),
|
||||||
|
setTargetFps(uint8_t fps),
|
||||||
setPixelSegment(uint8_t n),
|
setPixelSegment(uint8_t n),
|
||||||
deserializeMap(uint8_t n=0);
|
deserializeMap(uint8_t n=0);
|
||||||
|
|
||||||
@ -684,6 +687,7 @@ class WS2812FX {
|
|||||||
getActiveSegmentsNum(void),
|
getActiveSegmentsNum(void),
|
||||||
//getFirstSelectedSegment(void),
|
//getFirstSelectedSegment(void),
|
||||||
getMainSegmentId(void),
|
getMainSegmentId(void),
|
||||||
|
getTargetFps(void),
|
||||||
gamma8(uint8_t),
|
gamma8(uint8_t),
|
||||||
gamma8_cal(uint8_t, float),
|
gamma8_cal(uint8_t, float),
|
||||||
sin_gap(uint16_t),
|
sin_gap(uint16_t),
|
||||||
@ -855,6 +859,8 @@ class WS2812FX {
|
|||||||
uint16_t _usedSegmentData = 0;
|
uint16_t _usedSegmentData = 0;
|
||||||
uint16_t _transitionDur = 750;
|
uint16_t _transitionDur = 750;
|
||||||
|
|
||||||
|
uint8_t _targetFps = 42;
|
||||||
|
uint16_t _frametime = (1000/42);
|
||||||
uint16_t _cumulativeFps = 2;
|
uint16_t _cumulativeFps = 2;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -165,12 +165,12 @@ void WS2812FX::service() {
|
|||||||
_triggered = false;
|
_triggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||||
setPixelColor(n, R(c), G(c), B(c), W(c));
|
setPixelColor(n, R(c), G(c), B(c), W(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
|
//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
|
||||||
uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
uint16_t IRAM_ATTR WS2812FX::realPixelIndex(uint16_t i) {
|
||||||
int16_t iGroup = i * SEGMENT.groupLength();
|
int16_t iGroup = i * SEGMENT.groupLength();
|
||||||
|
|
||||||
/* reverse just an individual segment */
|
/* reverse just an individual segment */
|
||||||
@ -187,7 +187,7 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
|||||||
return realIndex;
|
return realIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||||
{
|
{
|
||||||
if (SEGLEN) {//from segment
|
if (SEGLEN) {//from segment
|
||||||
uint16_t realIndex = realPixelIndex(i);
|
uint16_t realIndex = realPixelIndex(i);
|
||||||
@ -350,6 +350,15 @@ uint16_t WS2812FX::getFps() {
|
|||||||
return _cumulativeFps +1;
|
return _cumulativeFps +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t WS2812FX::getTargetFps() {
|
||||||
|
return _targetFps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setTargetFps(uint8_t fps) {
|
||||||
|
if (fps > 0 && fps <= 120) _targetFps = fps;
|
||||||
|
_frametime = 1000 / _targetFps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forces the next frame to be computed on all active segments.
|
* Forces the next frame to be computed on all active segments.
|
||||||
*/
|
*/
|
||||||
@ -606,6 +615,12 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping,
|
|||||||
_segment_runtimes[n].reset();
|
_segment_runtimes[n].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WS2812FX::restartRuntime() {
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
|
||||||
|
_segment_runtimes[i].reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WS2812FX::resetSegments() {
|
void WS2812FX::resetSegments() {
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) if (_segments[i].name) delete[] _segments[i].name;
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) if (_segments[i].name) delete[] _segments[i].name;
|
||||||
mainSegment = 0;
|
mainSegment = 0;
|
||||||
@ -769,7 +784,7 @@ void WS2812FX::setTransitionMode(bool t)
|
|||||||
/*
|
/*
|
||||||
* color blend function
|
* color blend function
|
||||||
*/
|
*/
|
||||||
uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
|
uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) {
|
||||||
if(blend == 0) return color1;
|
if(blend == 0) return color1;
|
||||||
uint16_t blendmax = b16 ? 0xFFFF : 0xFF;
|
uint16_t blendmax = b16 ? 0xFFFF : 0xFF;
|
||||||
if(blend == blendmax) return color2;
|
if(blend == blendmax) return color2;
|
||||||
@ -872,13 +887,13 @@ void WS2812FX::blur(uint8_t blur_amount)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t WS2812FX::triwave16(uint16_t in)
|
uint16_t IRAM_ATTR WS2812FX::triwave16(uint16_t in)
|
||||||
{
|
{
|
||||||
if (in < 0x8000) return in *2;
|
if (in < 0x8000) return in *2;
|
||||||
return 0xFFFF - (in - 0x8000)*2;
|
return 0xFFFF - (in - 0x8000)*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::sin_gap(uint16_t in) {
|
uint8_t IRAM_ATTR WS2812FX::sin_gap(uint16_t in) {
|
||||||
if (in & 0x100) return 0;
|
if (in & 0x100) return 0;
|
||||||
//if (in > 255) return 0;
|
//if (in > 255) return 0;
|
||||||
return sin8(in + 192); //correct phase shift of sine so that it starts and stops at 0
|
return sin8(in + 192); //correct phase shift of sine so that it starts and stops at 0
|
||||||
@ -945,13 +960,13 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t WS2812FX::crgb_to_col(CRGB fastled)
|
uint32_t IRAM_ATTR WS2812FX::crgb_to_col(CRGB fastled)
|
||||||
{
|
{
|
||||||
return RGBW32(fastled.red, fastled.green, fastled.blue, 0);
|
return RGBW32(fastled.red, fastled.green, fastled.blue, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CRGB WS2812FX::col_to_crgb(uint32_t color)
|
CRGB IRAM_ATTR WS2812FX::col_to_crgb(uint32_t color)
|
||||||
{
|
{
|
||||||
CRGB fastled_col;
|
CRGB fastled_col;
|
||||||
fastled_col.red = R(color);
|
fastled_col.red = R(color);
|
||||||
@ -1074,7 +1089,7 @@ void WS2812FX::handle_palette(void)
|
|||||||
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
|
||||||
* @returns Single color from palette
|
* @returns Single color from palette
|
||||||
*/
|
*/
|
||||||
uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||||
{
|
{
|
||||||
if (SEGMENT.palette == 0 && mcol < 3) {
|
if (SEGMENT.palette == 0 && mcol < 3) {
|
||||||
uint32_t color = SEGCOLOR(mcol);
|
uint32_t color = SEGCOLOR(mcol);
|
||||||
|
@ -288,7 +288,7 @@ class BusPwm : public Bus {
|
|||||||
if (!pinManager.allocatePin(currentPin, true, PinOwner::BusPwm)) {
|
if (!pinManager.allocatePin(currentPin, true, PinOwner::BusPwm)) {
|
||||||
deallocatePins(); return;
|
deallocatePins(); return;
|
||||||
}
|
}
|
||||||
_pins[i] = currentPin; // store only after allocatePin() succeeds
|
_pins[i] = currentPin; //store only after allocatePin() succeeds
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
pinMode(_pins[i], OUTPUT);
|
pinMode(_pins[i], OUTPUT);
|
||||||
#else
|
#else
|
||||||
@ -397,7 +397,7 @@ class BusPwm : public Bus {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _pins[5] = {255, 255, 255, 255, 255};
|
uint8_t _pins[5] = {255, 255, 255, 255, 255};
|
||||||
uint8_t _data[5] = {255, 255, 255, 255, 255};
|
uint8_t _data[5] = {0};
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
uint8_t _ledcStart = 255;
|
uint8_t _ledcStart = 255;
|
||||||
#endif
|
#endif
|
||||||
|
@ -210,6 +210,7 @@ void handleAnalog(uint8_t b)
|
|||||||
void handleButton()
|
void handleButton()
|
||||||
{
|
{
|
||||||
static unsigned long lastRead = 0UL;
|
static unsigned long lastRead = 0UL;
|
||||||
|
bool analog = false;
|
||||||
|
|
||||||
for (uint8_t b=0; b<WLED_MAX_BUTTONS; b++) {
|
for (uint8_t b=0; b<WLED_MAX_BUTTONS; b++) {
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -221,7 +222,7 @@ void handleButton()
|
|||||||
if (usermods.handleButton(b)) continue; // did usermod handle buttons
|
if (usermods.handleButton(b)) continue; // did usermod handle buttons
|
||||||
|
|
||||||
if ((buttonType[b] == BTN_TYPE_ANALOG || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) && millis() - lastRead > 250) { // button is not a button but a potentiometer
|
if ((buttonType[b] == BTN_TYPE_ANALOG || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) && millis() - lastRead > 250) { // button is not a button but a potentiometer
|
||||||
if (b+1 == WLED_MAX_BUTTONS) lastRead = millis();
|
analog = true;
|
||||||
handleAnalog(b); continue;
|
handleAnalog(b); continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,6 +276,7 @@ void handleButton()
|
|||||||
shortPressAction(b);
|
shortPressAction(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (analog) lastRead = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleIO()
|
void handleIO()
|
||||||
|
@ -85,6 +85,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(cctFromRgb, hw_led[F("cr")]);
|
CJSON(cctFromRgb, hw_led[F("cr")]);
|
||||||
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
|
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||||
|
|
||||||
JsonArray ins = hw_led["ins"];
|
JsonArray ins = hw_led["ins"];
|
||||||
|
|
||||||
@ -376,7 +377,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
int act = timer["en"] | actPrev;
|
int act = timer["en"] | actPrev;
|
||||||
if (act) timerWeekday[it]++;
|
if (act) timerWeekday[it]++;
|
||||||
}
|
}
|
||||||
|
if (it<8) {
|
||||||
|
JsonObject start = timer["start"];
|
||||||
|
byte startm = start["mon"];
|
||||||
|
if (startm) timerMonth[it] = (startm << 4);
|
||||||
|
CJSON(timerDay[it], start["day"]);
|
||||||
|
JsonObject end = timer["end"];
|
||||||
|
CJSON(timerDayEnd[it], end["day"]);
|
||||||
|
byte endm = end["mon"];
|
||||||
|
if (startm) timerMonth[it] += endm & 0x0F;
|
||||||
|
if (!(timerMonth[it] & 0x0F)) timerMonth[it] += 12; //default end month to 12
|
||||||
|
}
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,6 +551,7 @@ void serializeConfig() {
|
|||||||
hw_led["cct"] = correctWB;
|
hw_led["cct"] = correctWB;
|
||||||
hw_led[F("cr")] = cctFromRgb;
|
hw_led[F("cr")] = cctFromRgb;
|
||||||
hw_led[F("cb")] = strip.cctBlending;
|
hw_led[F("cb")] = strip.cctBlending;
|
||||||
|
hw_led["fps"] = strip.getTargetFps();
|
||||||
hw_led[F("rgbwm")] = Bus::getAutoWhiteMode();
|
hw_led[F("rgbwm")] = Bus::getAutoWhiteMode();
|
||||||
|
|
||||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||||
@ -742,6 +754,14 @@ void serializeConfig() {
|
|||||||
timers_ins0["min"] = timerMinutes[i];
|
timers_ins0["min"] = timerMinutes[i];
|
||||||
timers_ins0["macro"] = timerMacro[i];
|
timers_ins0["macro"] = timerMacro[i];
|
||||||
timers_ins0[F("dow")] = timerWeekday[i] >> 1;
|
timers_ins0[F("dow")] = timerWeekday[i] >> 1;
|
||||||
|
if (i<8) {
|
||||||
|
JsonObject start = timers_ins0.createNestedObject("start");
|
||||||
|
start["mon"] = (timerMonth[i] >> 4) & 0xF;
|
||||||
|
start["day"] = timerDay[i];
|
||||||
|
JsonObject end = timers_ins0.createNestedObject("end");
|
||||||
|
end["mon"] = timerMonth[i] & 0xF;
|
||||||
|
end["day"] = timerDayEnd[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject ota = doc.createNestedObject("ota");
|
JsonObject ota = doc.createNestedObject("ota");
|
||||||
|
@ -571,6 +571,7 @@ ${i+1}:
|
|||||||
<option value="2">Linear (never wrap)</option>
|
<option value="2">Linear (never wrap)</option>
|
||||||
<option value="3">None (not recommended)</option>
|
<option value="3">None (not recommended)</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
|
Target refresh rate: <input type="number" class="s" min="1" max="120" name="FR" required> FPS
|
||||||
<hr style="width:260px">
|
<hr style="width:260px">
|
||||||
<div id="cfg">Config template: <input type="file" name="data2" accept=".json"> <input type="button" value="Apply" onclick="loadCfg(d.Sf.data2);"><br></div>
|
<div id="cfg">Config template: <input type="file" name="data2" accept=".json"> <input type="button" value="Apply" onclick="loadCfg(d.Sf.data2);"><br></div>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
<title>Time Settings</title>
|
<title>Time Settings</title>
|
||||||
<script>
|
<script>
|
||||||
var d=document;
|
var d=document;
|
||||||
|
var ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
|
||||||
|
var cals = 'style="font-size:27px;margin-top:-6px;cursor:pointer"'; //hack as to not repeat CSS on all pages
|
||||||
function H()
|
function H()
|
||||||
{
|
{
|
||||||
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");
|
window.open("https://kno.wled.ge/features/settings/#time-settings");
|
||||||
}
|
}
|
||||||
function B()
|
function B()
|
||||||
{
|
{
|
||||||
@ -16,12 +18,21 @@
|
|||||||
}
|
}
|
||||||
function S()
|
function S()
|
||||||
{
|
{
|
||||||
BTa();GetV();Cs();FC();
|
BTa();GetV();updLoc();Cs();FC();
|
||||||
}
|
}
|
||||||
function gId(s)
|
function gId(s)
|
||||||
{
|
{
|
||||||
return d.getElementById(s);
|
return d.getElementById(s);
|
||||||
}
|
}
|
||||||
|
function gN(s) {
|
||||||
|
return d.getElementsByName(s)[0];
|
||||||
|
}
|
||||||
|
function expand(o,i)
|
||||||
|
{
|
||||||
|
var t = gId("WD"+i);
|
||||||
|
t.style.display = t.style.display!=="none" ? "none" : "";
|
||||||
|
o.innerHTML = t.style.display==="none" ? "🗓" : "✕";
|
||||||
|
}
|
||||||
function Cs()
|
function Cs()
|
||||||
{
|
{
|
||||||
gId("cac").style.display="none";
|
gId("cac").style.display="none";
|
||||||
@ -43,37 +54,66 @@
|
|||||||
}
|
}
|
||||||
function BTa()
|
function BTa()
|
||||||
{
|
{
|
||||||
var ih="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";
|
var ih="<tr><th>En.</th><th>Hour</th><th>Minute</th><th>Preset</th><th></th></tr>";
|
||||||
for (i=0;i<8;i++)
|
for (i=0;i<8;i++) {
|
||||||
{
|
ih+=`<tr><td><input name="W${i}" id="W${i}" type="hidden"><input id="W${i}0" type="checkbox"></td>
|
||||||
ih+="<tr><td><input name=\"W"+i+"\" id=\"W"+i+"\" type=\"number\" style=\"display:none\"><input id=\"W"+i+"0\" type=\"checkbox\"></td><td><input name=\"H"+i+"\" type=\"number\" min=\"0\" max=\"24\"></td><td><input name=\"N"+i+"\" type=\"number\" min=\"0\" max=\"59\"></td><td><input name=\"T"+i+"\" type=\"number\" min=\"0\" max=\"250\"></td>";
|
<td><input name="H${i}" class="xs" type="number" min="0" max="24"></td>
|
||||||
for (j=1;j<8;j++) ih+="<td><input id=\"W"+i+j+"\" type=\"checkbox\"></td>";
|
<td><input name="N${i}" class="xs" type="number" min="0" max="59"></td>
|
||||||
|
<td><input name="T${i}" class="s" type="number" min="0" max="250"></td>
|
||||||
|
<td><div id="CB${i}" onclick="expand(this,${i})" ${cals}>🗓</div></td></tr>`;
|
||||||
|
ih+=`<tr><td colspan=5><div id="WD${i}" style="display:none;">Run on weekdays`;
|
||||||
|
ih+=`<table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`
|
||||||
|
for (j=1;j<8;j++) ih+=`<td><input id="W${i}${j}" type="checkbox"></td>`;
|
||||||
|
ih+=`</tr></table>from
|
||||||
|
<select name="M${i}">`;
|
||||||
|
for (j=0;j<12;j++) ih+=`<option value="${j+1}">${ms[j]}</option>`;
|
||||||
|
ih+=`</select><input name="D${i}" class="xs" type="number" min="1" max="31"></input> to
|
||||||
|
<select name="P${i}">`;
|
||||||
|
for (j=0;j<12;j++) ih+=`<option value="${j+1}">${ms[j]}</option>`;
|
||||||
|
ih+=`</select><input name="E${i}" class="xs" type="number" min="1" max="31"></input>
|
||||||
|
<hr></div></td></tr>`;
|
||||||
}
|
}
|
||||||
ih+="<tr><td><input name=\"W8\" id=\"W8\" type=\"number\" style=\"display:none\"><input id=\"W80\" type=\"checkbox\"></td><td>Sunrise<input name=\"H8\" value=\"255\" type=\"hidden\"></td><td><input name=\"N8\" type=\"number\" min=\"-59\" max=\"59\"></td><td><input name=\"T8\" type=\"number\" min=\"0\" max=\"250\"></td>";
|
ih+=`<tr><td><input name="W8" id="W8" type="hidden"><input id="W80" type="checkbox"></td>
|
||||||
for (j=1;j<8;j++) ih+="<td><input id=\"W8"+j+"\" type=\"checkbox\"></td>";
|
<td>Sunrise<input name="H8" value="255" type="hidden"></td>
|
||||||
ih+="<tr><td><input name=\"W9\" id=\"W9\" type=\"number\" style=\"display:none\"><input id=\"W90\" type=\"checkbox\"></td><td>Sunset<input name=\"H9\" value=\"255\" type=\"hidden\"></td><td><input name=\"N9\" type=\"number\" min=\"-59\" max=\"59\"><td><input name=\"T9\" type=\"number\" min=\"0\" max=\"250\"></td>";
|
<td><input name="N8" class="xs" type="number" min="-59" max="59"></td>
|
||||||
for (j=1;j<8;j++) ih+="<td><input id=\"W9"+j+"\" type=\"checkbox\"></td>";
|
<td><input name="T8" class="s" type="number" min="0" max="250"></td>
|
||||||
|
<td><div onclick="expand(this,8)" ${cals}>🗓</div></td></tr><tr><td colspan=5>`;
|
||||||
|
ih+=`<div id="WD8"style="display:none;"><table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`;
|
||||||
|
for (j=1;j<8;j++) ih+=`<td><input id="W8${j}" type="checkbox"></td>`;
|
||||||
|
ih+="</tr></table><hr></div></td></tr>";
|
||||||
|
ih+=`<tr><td><input name="W9" id="W9" type="hidden"><input id="W90" type="checkbox"></td>
|
||||||
|
<td>Sunset<input name="H9" value="255" type="hidden"></td>
|
||||||
|
<td><input name="N9" class="xs" type="number" min="-59" max="59"></td>
|
||||||
|
<td><input name="T9" class="s" type="number" min="0" max="250"></td>
|
||||||
|
<td><div onclick="expand(this,9)" ${cals}>🗓</div></td></tr><tr><td colspan=5>`;
|
||||||
|
ih+=`<div id="WD9" style="display:none;"><table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`;
|
||||||
|
for (j=1;j<8;j++) ih+=`<td><input id="W9${j}" type="checkbox"></td>`;
|
||||||
|
ih+="</tr></table><hr></div></td></tr>";
|
||||||
gId("TMT").innerHTML=ih;
|
gId("TMT").innerHTML=ih;
|
||||||
}
|
}
|
||||||
function FC()
|
function FC()
|
||||||
{
|
{
|
||||||
for(j=0;j<8;j++)
|
for(i=0;i<10;i++)
|
||||||
{
|
{
|
||||||
for(i=0;i<10;i++) gId("W"+i+j).checked=gId("W"+i).value>>j&1;
|
let wd = gId("W"+i).value;
|
||||||
|
for(j=0;j<8;j++) {
|
||||||
|
gId("W"+i+j).checked=wd>>j&1;
|
||||||
|
}
|
||||||
|
if ((wd&127) != 127 || (i<8 && (gN("M"+i).value != 1 || gN("D"+i).value != 1 || gN("P"+i).value != 12 || gN("E"+i).value != 31))) {
|
||||||
|
expand(gId("CB"+i),i); //expand macros with custom DOW or date range set
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function Wd()
|
function Wd()
|
||||||
{
|
{
|
||||||
a=[0,0,0,0,0,0,0,0,0,0];
|
a = [0,0,0,0,0,0,0,0,0,0];
|
||||||
for(i=0;i<10;i++)
|
for (i=0; i<10; i++) {
|
||||||
{
|
|
||||||
m=1;
|
m=1;
|
||||||
for(j=0;j<8;j++)
|
for(j=0;j<8;j++) { a[i]+=gId(("W"+i)+j).checked*m; m*=2;}
|
||||||
{
|
|
||||||
a[i]+=gId("W"+i+j).checked*m;m*=2;
|
|
||||||
}
|
|
||||||
gId("W"+i).value=a[i];
|
gId("W"+i).value=a[i];
|
||||||
}
|
}
|
||||||
|
if (d.Sf.LTR.value==="S") { d.Sf.LT.value = -1*parseFloat(d.Sf.LT.value); }
|
||||||
|
if (d.Sf.LNR.value==="W") { d.Sf.LN.value = -1*parseFloat(d.Sf.LN.value); }
|
||||||
}
|
}
|
||||||
function addRow(i,p,l,d) {
|
function addRow(i,p,l,d) {
|
||||||
var t = gId("macros"); // table
|
var t = gId("macros"); // table
|
||||||
@ -84,11 +124,15 @@
|
|||||||
td = tr.insertCell(0);
|
td = tr.insertCell(0);
|
||||||
td.innerHTML = `Button ${i}:`;
|
td.innerHTML = `Button ${i}:`;
|
||||||
td = tr.insertCell(1);
|
td = tr.insertCell(1);
|
||||||
td.innerHTML = `<input name="MP${b}" type="number" min="0" max="250" value="${p}" required>`;
|
td.innerHTML = `<input name="MP${b}" type="number" class="s" min="0" max="250" value="${p}" required>`;
|
||||||
td = tr.insertCell(2);
|
td = tr.insertCell(2);
|
||||||
td.innerHTML = `<input name="ML${b}" type="number" min="0" max="250" value="${l}" required>`;
|
td.innerHTML = `<input name="ML${b}" type="number" class="s" min="0" max="250" value="${l}" required>`;
|
||||||
td = tr.insertCell(3);
|
td = tr.insertCell(3);
|
||||||
td.innerHTML = `<input name="MD${b}" type="number" min="0" max="250" value="${d}" required>`;
|
td.innerHTML = `<input name="MD${b}" type="number" class="s" min="0" max="250" value="${d}" required>`;
|
||||||
|
}
|
||||||
|
function updLoc(i) {
|
||||||
|
if (parseFloat(d.Sf.LT.value)<0) { d.Sf.LTR.value = "S"; d.Sf.LT.value = -1*parseFloat(d.Sf.LT.value); } else d.Sf.LTR.value = "N";
|
||||||
|
if (parseFloat(d.Sf.LN.value)<0) { d.Sf.LNR.value = "W"; d.Sf.LN.value = -1*parseFloat(d.Sf.LN.value); } else d.Sf.LNR.value = "E";
|
||||||
}
|
}
|
||||||
function GetV()
|
function GetV()
|
||||||
{
|
{
|
||||||
@ -105,7 +149,7 @@
|
|||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
<h2>Time setup</h2>
|
<h2>Time setup</h2>
|
||||||
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
||||||
<input name="NS" maxlength="32"><br>
|
<input type="text" name="NS" maxlength="32"><br>
|
||||||
Use 24h format: <input type="checkbox" name="CF"><br>
|
Use 24h format: <input type="checkbox" name="CF"><br>
|
||||||
Time zone:
|
Time zone:
|
||||||
<select name="TZ">
|
<select name="TZ">
|
||||||
@ -134,8 +178,8 @@
|
|||||||
</select><br>
|
</select><br>
|
||||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||||
Current local time is <span class="times">unknown</span>.<br>
|
Current local time is <span class="times">unknown</span>.<br>
|
||||||
Latitude (N): <input name="LT" type="number" min="-66.6" max="66.6" step="0.01">
|
Latitude: <select name="LTR"><option value="N">N</option><option value="S">S</option></select><input name="LT" type="number" class="xl" min="0" max="66.6" step="0.01"><br>
|
||||||
Longitude (E): <input name="LN" type="number" min="-180" max="180" step="0.01">
|
Longitude: <select name="LNR"><option value="E">E</option><option value="W">W</option></select><input name="LN" type="number" class="xl" min="0" max="180" step="0.01">
|
||||||
<div id="sun" class="times"></div>
|
<div id="sun" class="times"></div>
|
||||||
<h3>Clock</h3>
|
<h3>Clock</h3>
|
||||||
Clock Overlay:
|
Clock Overlay:
|
||||||
@ -158,16 +202,16 @@
|
|||||||
</div>
|
</div>
|
||||||
Countdown Mode: <input type="checkbox" name="CE"><br>
|
Countdown Mode: <input type="checkbox" name="CE"><br>
|
||||||
Countdown Goal:<br>
|
Countdown Goal:<br>
|
||||||
Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
|
Date: <nowrap>20<input name="CY" class="xs" type="number" min="0" max="99" required>-<input name="CI" class="xs" type="number" min="1" max="12" required>-<input name="CD" class="xs" type="number" min="1" max="31" required></nowrap><br>
|
||||||
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
|
Time: <nowrap><input name="CH" class="xs" type="number" min="0" max="23" required>:<input name="CM" class="xs" type="number" min="0" max="59" required>:<input name="CS" class="xs" type="number" min="0" max="59" required></nowrap><br>
|
||||||
<h3>Macro presets</h3>
|
<h3>Macro presets</h3>
|
||||||
<b>Macros have moved!</b><br>
|
<b>Macros have moved!</b><br>
|
||||||
<i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br>
|
<i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br>
|
||||||
Just enter the preset id below!</i>
|
Just enter the preset ID below!</i>
|
||||||
<i>Use 0 for the default action instead of a preset</i><br>
|
<i>Use 0 for the default action instead of a preset</i><br>
|
||||||
Alexa On/Off Preset: <input name="A0" type="number" min="0" max="250" required> <input name="A1" type="number" min="0" max="250" required><br>
|
Alexa On/Off Preset: <input name="A0" class="m" type="number" min="0" max="250" required> <input name="A1" class="m" type="number" min="0" max="250" required><br>
|
||||||
Countdown-Over Preset: <input name="MC" type="number" min="0" max="250" required><br>
|
Countdown-Over Preset: <input name="MC" class="m" type="number" min="0" max="250" required><br>
|
||||||
Timed-Light-Over Presets: <input name="MN" type="number" min="0" max="250" required><br>
|
Timed-Light-Over Presets: <input name="MN" class="m" type="number" min="0" max="250" required><br>
|
||||||
<h3>Button actions</h3>
|
<h3>Button actions</h3>
|
||||||
<table style="margin: 0 auto;" id="macros">
|
<table style="margin: 0 auto;" id="macros">
|
||||||
<thead>
|
<thead>
|
||||||
@ -181,11 +225,12 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Macros#analog-button" target="_blank">Analog Button setup</a>
|
<a href="https://kno.wled.ge/features/macros/#analog-button" target="_blank">Analog Button setup</a>
|
||||||
<h3>Time-controlled presets</h3>
|
<h3>Time-controlled presets</h3>
|
||||||
<div style="display: inline-block">
|
<div style="display: inline-block">
|
||||||
<table id="TMT">
|
<table id="TMT" style="min-width:330px;"></table>
|
||||||
</table></div><hr>
|
</div>
|
||||||
|
<hr>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
@ -66,7 +66,6 @@ input[type="number"].xs {
|
|||||||
}
|
}
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
transform: scale(1.5);
|
transform: scale(1.5);
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
background: #333;
|
background: #333;
|
||||||
@ -80,7 +79,6 @@ td {
|
|||||||
.d5 {
|
.d5 {
|
||||||
width: 4.5em !important;
|
width: 4.5em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toast {
|
#toast {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32 //FS info bare IDF function until FS wrapper is available for ESP32
|
#ifdef ARDUINO_ARCH_ESP32 //FS info bare IDF function until FS wrapper is available for ESP32
|
||||||
#if WLED_FS != LITTLEFS
|
#if WLED_FS != LITTLEFS && ESP_IDF_VERSION_MAJOR < 4
|
||||||
#include "esp_spiffs.h"
|
#include "esp_spiffs.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -359,9 +359,9 @@ bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest)
|
|||||||
|
|
||||||
void updateFSInfo() {
|
void updateFSInfo() {
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#if WLED_FS == LITTLEFS
|
#if WLED_FS == LITTLEFS || ESP_IDF_VERSION_MAJOR >= 4
|
||||||
fsBytesTotal = LITTLEFS.totalBytes();
|
fsBytesTotal = WLED_FS.totalBytes();
|
||||||
fsBytesUsed = LITTLEFS.usedBytes();
|
fsBytesUsed = WLED_FS.usedBytes();
|
||||||
#else
|
#else
|
||||||
esp_spiffs_info(nullptr, &fsBytesTotal, &fsBytesUsed);
|
esp_spiffs_info(nullptr, &fsBytesTotal, &fsBytesUsed);
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Autogenerated from wled00/data/style.css, do not edit!!
|
// Autogenerated from wled00/data/style.css, do not edit!!
|
||||||
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}a{color:#28f;text-decoration:none}.btn,button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:1px 6px;cursor:pointer;text-decoration:none}.lnk{border:0}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input:disabled{color:#888}input[type=number]{width:4em;margin:2px}input[type=number].xxl{width:100px}input[type=number].xl{width:85px}input[type=number].l{width:63px}input[type=number].m{width:56px}input[type=number].s{width:49px}input[type=number].xs{width:42px}input[type=checkbox]{transform:scale(1.5);margin-right:10px}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)=====";
|
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}a{color:#28f;text-decoration:none}.btn,button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:1px 6px;cursor:pointer;text-decoration:none}.lnk{border:0}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input:disabled{color:#888}input[type=number]{width:4em;margin:2px}input[type=number].xxl{width:100px}input[type=number].xl{width:85px}input[type=number].l{width:63px}input[type=number].m{width:56px}input[type=number].s{width:49px}input[type=number].xs{width:42px}input[type=checkbox]{transform:scale(1.5)}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)=====";
|
||||||
|
|
||||||
|
|
||||||
// Autogenerated from wled00/data/settings.htm, do not edit!!
|
// Autogenerated from wled00/data/settings.htm, do not edit!!
|
||||||
@ -156,9 +156,10 @@ CCT additive blending: <input type="number" class="s" min="0" max="100"
|
|||||||
name="CB" required> %%</span><h3>Advanced</h3>Palette blending: <select
|
name="CB" required> %%</span><h3>Advanced</h3>Palette blending: <select
|
||||||
name="PB"><option value="0">Linear (wrap if moving)</option><option value="1">
|
name="PB"><option value="0">Linear (wrap if moving)</option><option value="1">
|
||||||
Linear (always wrap)</option><option value="2">Linear (never wrap)</option>
|
Linear (always wrap)</option><option value="2">Linear (never wrap)</option>
|
||||||
<option value="3">None (not recommended)</option></select><br><hr
|
<option value="3">None (not recommended)</option></select><br>
|
||||||
style="width:260px"><div id="cfg">Config template: <input type="file"
|
Target refresh rate: <input type="number" class="s" min="1" max="120" name="FR"
|
||||||
name="data2" accept=".json"> <input type="button" value="Apply"
|
required> FPS<hr style="width:260px"><div id="cfg">Config template: <input
|
||||||
|
type="file" name="data2" accept=".json"> <input type="button" value="Apply"
|
||||||
onclick="loadCfg(d.Sf.data2)"><br></div><hr><button type="button" onclick="B()">
|
onclick="loadCfg(d.Sf.data2)"><br></div><hr><button type="button" onclick="B()">
|
||||||
Back</button><button type="submit">Save</button></form></body></html>)=====";
|
Back</button><button type="submit">Save</button></form></body></html>)=====";
|
||||||
|
|
||||||
@ -340,32 +341,35 @@ type="submit">Save</button></form></body></html>)=====";
|
|||||||
// Autogenerated from wled00/data/settings_time.htm, do not edit!!
|
// Autogenerated from wled00/data/settings_time.htm, do not edit!!
|
||||||
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
||||||
<meta charset="utf-8"><title>Time Settings</title><script>
|
<meta charset="utf-8"><title>Time Settings</title><script>
|
||||||
var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),Cs(),FC()}function gId(t){return d.getElementById(t)}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var t="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for(i=0;i<8;i++)for(t+='<tr><td><input name="W'+i+'" id="W'+i+'" type="number" style="display:none"><input id="W'+i+'0" type="checkbox"></td><td><input name="H'+i+'" type="number" min="0" max="24"></td><td><input name="N'+i+'" type="number" min="0" max="59"></td><td><input name="T'+i+'" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W'+i+j+'" type="checkbox"></td>';for(t+='<tr><td><input name="W8" id="W8" type="number" style="display:none"><input id="W80" type="checkbox"></td><td>Sunrise<input name="H8" value="255" type="hidden"></td><td><input name="N8" type="number" min="-59" max="59"></td><td><input name="T8" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W8'+j+'" type="checkbox"></td>';for(t+='<tr><td><input name="W9" id="W9" type="number" style="display:none"><input id="W90" type="checkbox"></td><td>Sunset<input name="H9" value="255" type="hidden"></td><td><input name="N9" type="number" min="-59" max="59"><td><input name="T9" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W9'+j+'" type="checkbox"></td>';gId("TMT").innerHTML=t}function FC(){for(j=0;j<8;j++)for(i=0;i<10;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}}function addRow(t,e,n,i){var d=gId("macros"),u=d.rows.length,c=d.insertRow(u),m=String.fromCharCode((t<10?48:55)+t);document.createElement("td");c.insertCell(0).innerHTML=`Button ${t}:`,c.insertCell(1).innerHTML=`<input name="MP${m}" type="number" min="0" max="250" value="${e}" required>`,c.insertCell(2).innerHTML=`<input name="ML${m}" type="number" min="0" max="250" value="${n}" required>`,c.insertCell(3).innerHTML=`<input name="MD${m}" type="number" min="0" max="250" value="${i}" required>`}function GetV() {
|
var d=document,ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],cals='style="font-size:27px;margin-top:-6px;cursor:pointer"';function H(){window.open("https://kno.wled.ge/features/settings/#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),updLoc(),Cs(),FC()}function gId(t){return d.getElementById(t)}function gN(t){return d.getElementsByName(t)[0]}function expand(t,e){var n=gId("WD"+e);n.style.display="none"!==n.style.display?"none":"",t.innerHTML="none"===n.style.display?"🗓":"✕"}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var t="<tr><th>En.</th><th>Hour</th><th>Minute</th><th>Preset</th><th></th></tr>";for(i=0;i<8;i++){for(t+=`<tr><td><input name="W${i}" id="W${i}" type="hidden"><input id="W${i}0" type="checkbox"></td>\n<td><input name="H${i}" class="xs" type="number" min="0" max="24"></td>\n<td><input name="N${i}" class="xs" type="number" min="0" max="59"></td>\n<td><input name="T${i}" class="s" type="number" min="0" max="250"></td>\n<td><div id="CB${i}" onclick="expand(this,${i})" ${cals}>🗓</div></td></tr>`,t+=`<tr><td colspan=5><div id="WD${i}" style="display:none;">Run on weekdays`,t+='<table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>',j=1;j<8;j++)t+=`<td><input id="W${i}${j}" type="checkbox"></td>`;for(t+=`</tr></table>from\n<select name="M${i}">`,j=0;j<12;j++)t+=`<option value="${j+1}">${ms[j]}</option>`;for(t+=`</select><input name="D${i}" class="xs" type="number" min="1" max="31"></input> to\n<select name="P${i}">`,j=0;j<12;j++)t+=`<option value="${j+1}">${ms[j]}</option>`;t+=`</select><input name="E${i}" class="xs" type="number" min="1" max="31"></input>\n\t\t<hr></div></td></tr>`}for(t+=`<tr><td><input name="W8" id="W8" type="hidden"><input id="W80" type="checkbox"></td>\n<td>Sunrise<input name="H8" value="255" type="hidden"></td>\n<td><input name="N8" class="xs" type="number" min="-59" max="59"></td>\n<td><input name="T8" class="s" type="number" min="0" max="250"></td>\n<td><div onclick="expand(this,8)" ${cals}>🗓</div></td></tr><tr><td colspan=5>`,t+='<div id="WD8"style="display:none;"><table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>',j=1;j<8;j++)t+=`<td><input id="W8${j}" type="checkbox"></td>`;for(t+="</tr></table><hr></div></td></tr>",t+=`<tr><td><input name="W9" id="W9" type="hidden"><input id="W90" type="checkbox"></td>\n<td>Sunset<input name="H9" value="255" type="hidden"></td>\n<td><input name="N9" class="xs" type="number" min="-59" max="59"></td>\n<td><input name="T9" class="s" type="number" min="0" max="250"></td>\n<td><div onclick="expand(this,9)" ${cals}>🗓</div></td></tr><tr><td colspan=5>`,t+='<div id="WD9" style="display:none;"><table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>',j=1;j<8;j++)t+=`<td><input id="W9${j}" type="checkbox"></td>`;t+="</tr></table><hr></div></td></tr>",gId("TMT").innerHTML=t}function FC(){for(i=0;i<10;i++){let t=gId("W"+i).value;for(j=0;j<8;j++)gId("W"+i+j).checked=t>>j&1;(127!=(127&t)||i<8&&(1!=gN("M"+i).value||1!=gN("D"+i).value||12!=gN("P"+i).value||31!=gN("E"+i).value))&&expand(gId("CB"+i),i)}}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}"S"===d.Sf.LTR.value&&(d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)),"W"===d.Sf.LNR.value&&(d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value))}function addRow(t,e,n,i){var d=gId("macros"),a=d.rows.length,l=d.insertRow(a),s=String.fromCharCode((t<10?48:55)+t);document.createElement("td");l.insertCell(0).innerHTML=`Button ${t}:`,l.insertCell(1).innerHTML=`<input name="MP${s}" type="number" class="s" min="0" max="250" value="${e}" required>`,l.insertCell(2).innerHTML=`<input name="ML${s}" type="number" class="s" min="0" max="250" value="${n}" required>`,l.insertCell(3).innerHTML=`<input name="MD${s}" type="number" class="s" min="0" max="250" value="${i}" required>`}function updLoc(t){parseFloat(d.Sf.LT.value)<0?(d.Sf.LTR.value="S",d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)):d.Sf.LTR.value="N",parseFloat(d.Sf.LN.value)<0?(d.Sf.LNR.value="W",d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value)):d.Sf.LNR.value="E"}function GetV() {
|
||||||
%CSS%%SCSS%</head><body onload="S()"><form
|
%CSS%%SCSS%</head><body onload="S()"><form
|
||||||
id="form_s" name="Sf" method="post" onsubmit="Wd()"><div class="helpB"><button
|
id="form_s" name="Sf" method="post" onsubmit="Wd()"><div class="helpB"><button
|
||||||
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
||||||
Back</button><button type="submit">Save</button><hr><h2>Time setup</h2>
|
Back</button><button type="submit">Save</button><hr><h2>Time setup</h2>
|
||||||
Get time from NTP server: <input type="checkbox" name="NT"><br><input name="NS"
|
Get time from NTP server: <input type="checkbox" name="NT"><br><input
|
||||||
maxlength="32"><br>Use 24h format: <input type="checkbox" name="CF"><br>
|
type="text" name="NS" maxlength="32"><br>Use 24h format: <input type="checkbox"
|
||||||
Time zone: <select name="TZ"><option value="0" selected="selected">GMT(UTC)
|
name="CF"><br>Time zone: <select name="TZ"><option value="0"
|
||||||
</option><option value="1">GMT/BST</option><option value="2">CET/CEST</option>
|
selected="selected">GMT(UTC)</option><option value="1">GMT/BST</option><option
|
||||||
<option value="3">EET/EEST</option><option value="4">US-EST/EDT</option><option
|
value="2">CET/CEST</option><option value="3">EET/EEST</option><option value="4">
|
||||||
value="5">US-CST/CDT</option><option value="6">US-MST/MDT</option><option
|
US-EST/EDT</option><option value="5">US-CST/CDT</option><option value="6">
|
||||||
value="7">US-AZ</option><option value="8">US-PST/PDT</option><option value="9">
|
US-MST/MDT</option><option value="7">US-AZ</option><option value="8">US-PST/PDT
|
||||||
CST(AWST)</option><option value="10">JST(KST)</option><option value="11">
|
</option><option value="9">CST(AWST)</option><option value="10">JST(KST)
|
||||||
AEST/AEDT</option><option value="12">NZST/NZDT</option><option value="13">
|
</option><option value="11">AEST/AEDT</option><option value="12">NZST/NZDT
|
||||||
North Korea</option><option value="14">IST (India)</option><option value="15">
|
</option><option value="13">North Korea</option><option value="14">IST (India)
|
||||||
CA-Saskatchewan</option><option value="16">ACST</option><option value="17">
|
</option><option value="15">CA-Saskatchewan</option><option value="16">ACST
|
||||||
ACST/ACDT</option><option value="18">HST (Hawaii)</option><option value="19">
|
</option><option value="17">ACST/ACDT</option><option value="18">HST (Hawaii)
|
||||||
NOVT (Novosibirsk)</option><option value="20">AKST/AKDT (Anchorage)</option>
|
</option><option value="19">NOVT (Novosibirsk)</option><option value="20">
|
||||||
<option value="21">MX-CST/CDT</option></select><br>UTC offset: <input name="UO"
|
AKST/AKDT (Anchorage)</option><option value="21">MX-CST/CDT</option></select>
|
||||||
type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
<br>UTC offset: <input name="UO" type="number" min="-65500" max="65500"
|
||||||
Current local time is <span class="times">unknown</span>.<br>Latitude (N):
|
required> seconds (max. 18 hours)<br>Current local time is <span class="times">
|
||||||
<input name="LT" type="number" min="-66.6" max="66.6" step="0.01">
|
unknown</span>.<br>Latitude: <select name="LTR"><option value="N">N</option>
|
||||||
Longitude (E): <input name="LN" type="number" min="-180" max="180" step="0.01">
|
<option value="S">S</option></select><input name="LT" type="number" class="xl"
|
||||||
<div id="sun" class="times"></div><h3>Clock</h3>Clock Overlay: <select
|
min="0" max="66.6" step="0.01"><br>Longitude: <select name="LNR"><option
|
||||||
name="OL" onchange="Cs()"><option value="0" id="cn" selected="selected">None
|
value="E">E</option><option value="W">W</option></select><input name="LN"
|
||||||
</option><option value="1" id="ca">Analog Clock</option><option value="2">
|
type="number" class="xl" min="0" max="180" step="0.01"><div id="sun"
|
||||||
|
class="times"></div><h3>Clock</h3>Clock Overlay: <select name="OL"
|
||||||
|
onchange="Cs()"><option value="0" id="cn" selected="selected">None</option>
|
||||||
|
<option value="1" id="ca">Analog Clock</option><option value="2">
|
||||||
Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
|
Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
|
||||||
</select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
|
</select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
|
||||||
max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
|
max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
|
||||||
@ -374,28 +378,30 @@ max="255" required><br>Show 5min marks: <input type="checkbox" name="O5"><br>
|
|||||||
</div>Seconds (as trail): <input type="checkbox" name="OS"><br></div><div
|
</div>Seconds (as trail): <input type="checkbox" name="OS"><br></div><div
|
||||||
id="ccc">Cronixie Display: <input name="CX" maxlength="6"><br>
|
id="ccc">Cronixie Display: <input name="CX" maxlength="6"><br>
|
||||||
Cronixie Backlight: <input type="checkbox" name="CB"><br></div>Countdown Mode:
|
Cronixie Backlight: <input type="checkbox" name="CB"><br></div>Countdown Mode:
|
||||||
<input type="checkbox" name="CE"><br>Countdown Goal:<br>Year: 20 <input
|
<input type="checkbox" name="CE"><br>Countdown Goal:<br>Date: <nowrap>20
|
||||||
name="CY" type="number" min="0" max="99" required> Month: <input name="CI"
|
<input name="CY" class="xs" type="number" min="0" max="99" required>-<input
|
||||||
type="number" min="1" max="12" required> Day: <input name="CD" type="number"
|
name="CI" class="xs" type="number" min="1" max="12" required>-<input name="CD"
|
||||||
min="1" max="31" required><br>Hour: <input name="CH" type="number" min="0"
|
class="xs" type="number" min="1" max="31" required></nowrap><br>Time:<nowrap>
|
||||||
max="23" required> Minute: <input name="CM" type="number" min="0" max="59"
|
<input name="CH" class="xs" type="number" min="0" max="23" required>:<input
|
||||||
required> Second: <input name="CS" type="number" min="0" max="59" required><br>
|
name="CM" class="xs" type="number" min="0" max="59" required>:<input name="CS"
|
||||||
<h3>Macro presets</h3><b>Macros have moved!</b><br><i>
|
class="xs" type="number" min="0" max="59" required></nowrap><br><h3>
|
||||||
|
Macro presets</h3><b>Macros have moved!</b><br><i>
|
||||||
Presets now also can be used as macros to save both JSON and HTTP API commands.
|
Presets now also can be used as macros to save both JSON and HTTP API commands.
|
||||||
<br>Just enter the preset id below!</i> <i>
|
<br>Just enter the preset ID below!</i> <i>
|
||||||
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
|
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
|
||||||
<input name="A0" type="number" min="0" max="250" required> <input name="A1"
|
<input name="A0" class="m" type="number" min="0" max="250" required> <input
|
||||||
type="number" min="0" max="250" required><br>Countdown-Over Preset: <input
|
name="A1" class="m" type="number" min="0" max="250" required><br>
|
||||||
name="MC" type="number" min="0" max="250" required><br>
|
Countdown-Over Preset: <input name="MC" class="m" type="number" min="0"
|
||||||
Timed-Light-Over Presets: <input name="MN" type="number" min="0" max="250"
|
max="250" required><br>Timed-Light-Over Presets: <input name="MN" class="m"
|
||||||
required><br><h3>Button actions</h3><table style="margin:0 auto" id="macros">
|
type="number" min="0" max="250" required><br><h3>Button actions</h3><table
|
||||||
<thead><tr><td>push<br>switch</td><td>short<br>on->off</td><td>long<br>
|
style="margin:0 auto" id="macros"><thead><tr><td>push<br>switch</td><td>short
|
||||||
off->on</td><td>double<br>N/A</td></tr></thead><tbody></tbody></table><a
|
<br>on->off</td><td>long<br>off->on</td><td>double<br>N/A</td></tr>
|
||||||
href="https://github.com/Aircoookie/WLED/wiki/Macros#analog-button"
|
</thead><tbody></tbody></table><a
|
||||||
target="_blank">Analog Button setup</a><h3>Time-controlled presets</h3><div
|
href="https://kno.wled.ge/features/macros/#analog-button" target="_blank">
|
||||||
style="display:inline-block"><table id="TMT"></table></div><hr><button
|
Analog Button setup</a><h3>Time-controlled presets</h3><div
|
||||||
type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
style="display:inline-block"><table id="TMT" style="min-width:330px"></table>
|
||||||
</form></body></html>)=====";
|
</div><hr><button type="button" onclick="B()">Back</button><button
|
||||||
|
type="submit">Save</button></form></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
// Autogenerated from wled00/data/settings_sec.htm, do not edit!!
|
// Autogenerated from wled00/data/settings_sec.htm, do not edit!!
|
||||||
|
1611
wled00/html_ui.h
1611
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -535,7 +535,7 @@ void serializeInfo(JsonObject root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
leds[F("pwr")] = strip.currentMilliamps;
|
leds[F("pwr")] = strip.currentMilliamps;
|
||||||
leds[F("fps")] = strip.getFps();
|
leds["fps"] = strip.getFps();
|
||||||
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||||
leds[F("maxseg")] = strip.getMaxSegments();
|
leds[F("maxseg")] = strip.getMaxSegments();
|
||||||
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||||
|
@ -318,6 +318,32 @@ byte weekdayMondayFirst()
|
|||||||
return wd;
|
return wd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isTodayInDateRange(byte monthStart, byte dayStart, byte monthEnd, byte dayEnd)
|
||||||
|
{
|
||||||
|
if (monthStart == 0 || dayStart == 0) return true;
|
||||||
|
if (monthEnd == 0) monthEnd = monthStart;
|
||||||
|
if (dayEnd == 0) dayEnd = 31;
|
||||||
|
byte d = day(localTime);
|
||||||
|
byte m = month(localTime);
|
||||||
|
|
||||||
|
if (monthStart < monthEnd) {
|
||||||
|
if (m > monthStart && m < monthEnd) return true;
|
||||||
|
if (m == monthStart) return (d >= dayStart);
|
||||||
|
if (m == monthEnd) return (d <= dayEnd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (monthEnd < monthStart) { //range spans change of year
|
||||||
|
if (m > monthStart || m < monthEnd) return true;
|
||||||
|
if (m == monthStart) return (d >= dayStart);
|
||||||
|
if (m == monthEnd) return (d <= dayEnd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//start month and end month are the same
|
||||||
|
if (dayEnd < dayStart) return (m != monthStart || (d <= dayEnd || d >= dayStart)); //all year, except the designated days in this month
|
||||||
|
return (m == monthStart && d >= dayStart && d <= dayEnd); //just the designated days this month
|
||||||
|
}
|
||||||
|
|
||||||
void checkTimers()
|
void checkTimers()
|
||||||
{
|
{
|
||||||
if (lastTimerMinute != minute(localTime)) //only check once a new minute begins
|
if (lastTimerMinute != minute(localTime)) //only check once a new minute begins
|
||||||
@ -331,10 +357,12 @@ void checkTimers()
|
|||||||
for (uint8_t i = 0; i < 8; i++)
|
for (uint8_t i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
if (timerMacro[i] != 0
|
if (timerMacro[i] != 0
|
||||||
|
&& (timerWeekday[i] & 0x01) //timer is enabled
|
||||||
&& (timerHours[i] == hour(localTime) || timerHours[i] == 24) //if hour is set to 24, activate every hour
|
&& (timerHours[i] == hour(localTime) || timerHours[i] == 24) //if hour is set to 24, activate every hour
|
||||||
&& timerMinutes[i] == minute(localTime)
|
&& timerMinutes[i] == minute(localTime)
|
||||||
&& (timerWeekday[i] & 0x01) //timer is enabled
|
&& ((timerWeekday[i] >> weekdayMondayFirst()) & 0x01) //timer should activate at current day of week
|
||||||
&& ((timerWeekday[i] >> weekdayMondayFirst()) & 0x01)) //timer should activate at current day of week
|
&& isTodayInDateRange(((timerMonth[i] >> 4) & 0x0F), timerDay[i], timerMonth[i] & 0x0F, timerDayEnd[i])
|
||||||
|
)
|
||||||
{
|
{
|
||||||
unloadPlaylist();
|
unloadPlaylist();
|
||||||
applyPreset(timerMacro[i]);
|
applyPreset(timerMacro[i]);
|
||||||
|
@ -107,7 +107,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
|
|||||||
|
|
||||||
playlistRepeat = rep;
|
playlistRepeat = rep;
|
||||||
if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
|
if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
|
||||||
playlistEndPreset = playlistObj[F("end")] | 0;
|
playlistEndPreset = playlistObj["end"] | 0;
|
||||||
shuffle = shuffle || playlistObj["r"];
|
shuffle = shuffle || playlistObj["r"];
|
||||||
if (shuffle) playlistOptions += PL_OPTION_SHUFFLE;
|
if (shuffle) playlistOptions += PL_OPTION_SHUFFLE;
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
strip.cctBlending = request->arg(F("CB")).toInt();
|
strip.cctBlending = request->arg(F("CB")).toInt();
|
||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
Bus::setAutoWhiteMode(request->arg(F("AW")).toInt());
|
Bus::setAutoWhiteMode(request->arg(F("AW")).toInt());
|
||||||
|
strip.setTargetFps(request->arg(F("FR")).toInt());
|
||||||
|
|
||||||
for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) {
|
for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) {
|
||||||
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||||
@ -353,21 +354,27 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char k[3]; k[2] = 0;
|
char k[3]; k[2] = 0;
|
||||||
for (int i = 0; i<10; i++)
|
for (int i = 0; i<10; i++) {
|
||||||
{
|
k[1] = i+48;//ascii 0,1,2,3,...
|
||||||
k[1] = i+48;//ascii 0,1,2,3
|
|
||||||
|
|
||||||
k[0] = 'H'; //timer hours
|
k[0] = 'H'; //timer hours
|
||||||
timerHours[i] = request->arg(k).toInt();
|
timerHours[i] = request->arg(k).toInt();
|
||||||
|
|
||||||
k[0] = 'N'; //minutes
|
k[0] = 'N'; //minutes
|
||||||
timerMinutes[i] = request->arg(k).toInt();
|
timerMinutes[i] = request->arg(k).toInt();
|
||||||
|
|
||||||
k[0] = 'T'; //macros
|
k[0] = 'T'; //macros
|
||||||
timerMacro[i] = request->arg(k).toInt();
|
timerMacro[i] = request->arg(k).toInt();
|
||||||
|
|
||||||
k[0] = 'W'; //weekdays
|
k[0] = 'W'; //weekdays
|
||||||
timerWeekday[i] = request->arg(k).toInt();
|
timerWeekday[i] = request->arg(k).toInt();
|
||||||
|
if (i<8) {
|
||||||
|
k[0] = 'M'; //start month
|
||||||
|
timerMonth[i] = request->arg(k).toInt() & 0x0F;
|
||||||
|
timerMonth[i] <<= 4;
|
||||||
|
k[0] = 'P'; //end month
|
||||||
|
timerMonth[i] += (request->arg(k).toInt() & 0x0F);
|
||||||
|
k[0] = 'D'; //start day
|
||||||
|
timerDay[i] = request->arg(k).toInt();
|
||||||
|
k[0] = 'E'; //end day
|
||||||
|
timerDayEnd[i] = request->arg(k).toInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +193,8 @@ void WLED::loop()
|
|||||||
if (lastMqttReconnectAttempt > millis()) {
|
if (lastMqttReconnectAttempt > millis()) {
|
||||||
rolloverMillis++;
|
rolloverMillis++;
|
||||||
lastMqttReconnectAttempt = 0;
|
lastMqttReconnectAttempt = 0;
|
||||||
|
ntpLastSyncTime = 0;
|
||||||
|
strip.restartRuntime();
|
||||||
}
|
}
|
||||||
if (millis() - lastMqttReconnectAttempt > 30000) {
|
if (millis() - lastMqttReconnectAttempt > 30000) {
|
||||||
lastMqttReconnectAttempt = millis();
|
lastMqttReconnectAttempt = millis();
|
||||||
@ -682,8 +684,10 @@ void WLED::handleConnection()
|
|||||||
|
|
||||||
if (now < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS))
|
if (now < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS))
|
||||||
return;
|
return;
|
||||||
if (lastReconnectAttempt == 0)
|
if (lastReconnectAttempt == 0) {
|
||||||
initConnection();
|
initConnection();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// reconnect WiFi to clear stale allocations if heap gets too low
|
// reconnect WiFi to clear stale allocations if heap gets too low
|
||||||
if (now - heapTime > 5000) {
|
if (now - heapTime > 5000) {
|
||||||
|
@ -71,10 +71,14 @@
|
|||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <AsyncTCP.h>
|
#include <AsyncTCP.h>
|
||||||
//#include "SPIFFS.h"
|
//#include "SPIFFS.h"
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 4
|
||||||
#ifndef CONFIG_LITTLEFS_FOR_IDF_3_2
|
#ifndef CONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
#define CONFIG_LITTLEFS_FOR_IDF_3_2
|
#define CONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
#endif
|
#endif
|
||||||
#include <LITTLEFS.h>
|
#include <LITTLEFS.h>
|
||||||
|
#else
|
||||||
|
#include <LittleFS.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/dependencies/network/Network.h"
|
#include "src/dependencies/network/Network.h"
|
||||||
@ -173,7 +177,11 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument<PSRAM_Allocator>;
|
|||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define WLED_FS LittleFS
|
#define WLED_FS LittleFS
|
||||||
#else
|
#else
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 4
|
||||||
#define WLED_FS LITTLEFS
|
#define WLED_FS LITTLEFS
|
||||||
|
#else
|
||||||
|
#define WLED_FS LittleFS
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GLOBAL VARIABLES
|
// GLOBAL VARIABLES
|
||||||
@ -497,13 +505,17 @@ WLED_GLOBAL byte dP[] _INIT_N(({ 255, 255, 255, 255, 255, 255 }));
|
|||||||
WLED_GLOBAL unsigned long countdownTime _INIT(1514764800L);
|
WLED_GLOBAL unsigned long countdownTime _INIT(1514764800L);
|
||||||
WLED_GLOBAL bool countdownOverTriggered _INIT(true);
|
WLED_GLOBAL bool countdownOverTriggered _INIT(true);
|
||||||
|
|
||||||
// timer
|
//timer
|
||||||
WLED_GLOBAL byte lastTimerMinute _INIT(0);
|
WLED_GLOBAL byte lastTimerMinute _INIT(0);
|
||||||
WLED_GLOBAL byte timerHours[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
|
WLED_GLOBAL byte timerHours[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
|
||||||
WLED_GLOBAL int8_t timerMinutes[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
|
WLED_GLOBAL int8_t timerMinutes[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
|
||||||
WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
|
WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
|
||||||
WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 })); // weekdays to activate on
|
//weekdays to activate on, bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity
|
||||||
// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity
|
WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }));
|
||||||
|
//upper 4 bits start, lower 4 bits end month (default 28: start month 1 and end month 12)
|
||||||
|
WLED_GLOBAL byte timerMonth[] _INIT_N(({28,28,28,28,28,28,28,28}));
|
||||||
|
WLED_GLOBAL byte timerDay[] _INIT_N(({1,1,1,1,1,1,1,1}));
|
||||||
|
WLED_GLOBAL byte timerDayEnd[] _INIT_N(({31,31,31,31,31,31,31,31}));
|
||||||
|
|
||||||
// blynk
|
// blynk
|
||||||
WLED_GLOBAL bool blynkEnabled _INIT(false);
|
WLED_GLOBAL bool blynkEnabled _INIT(false);
|
||||||
|
@ -382,6 +382,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',SET_F("CCT"),correctWB);
|
sappend('c',SET_F("CCT"),correctWB);
|
||||||
sappend('c',SET_F("CR"),cctFromRgb);
|
sappend('c',SET_F("CR"),cctFromRgb);
|
||||||
sappend('v',SET_F("CB"),strip.cctBlending);
|
sappend('v',SET_F("CB"),strip.cctBlending);
|
||||||
|
sappend('v',SET_F("FR"),strip.getTargetFps());
|
||||||
sappend('v',SET_F("AW"),Bus::getAutoWhiteMode());
|
sappend('v',SET_F("AW"),Bus::getAutoWhiteMode());
|
||||||
|
|
||||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||||
@ -506,7 +507,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
memset(fpass,'*',l);
|
memset(fpass,'*',l);
|
||||||
sappends('s',SET_F("MQPASS"),fpass);
|
sappends('s',SET_F("MQPASS"),fpass);
|
||||||
sappends('s',SET_F("MQCID"),mqttClientID);
|
sappends('s',SET_F("MQCID"),mqttClientID);
|
||||||
sappends('s',SET_F("MD"),mqttDeviceTopic);
|
sappends('s',"MD",mqttDeviceTopic);
|
||||||
sappends('s',SET_F("MG"),mqttGroupTopic);
|
sappends('s',SET_F("MG"),mqttGroupTopic);
|
||||||
sappend('c',SET_F("BM"),buttonPublishMqtt);
|
sappend('c',SET_F("BM"),buttonPublishMqtt);
|
||||||
#endif
|
#endif
|
||||||
@ -597,6 +598,12 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
k[0] = 'N'; sappend('v',k,timerMinutes[i]);
|
k[0] = 'N'; sappend('v',k,timerMinutes[i]);
|
||||||
k[0] = 'T'; sappend('v',k,timerMacro[i]);
|
k[0] = 'T'; sappend('v',k,timerMacro[i]);
|
||||||
k[0] = 'W'; sappend('v',k,timerWeekday[i]);
|
k[0] = 'W'; sappend('v',k,timerWeekday[i]);
|
||||||
|
if (i<8) {
|
||||||
|
k[0] = 'M'; sappend('v',k,(timerMonth[i] >> 4) & 0x0F);
|
||||||
|
k[0] = 'P'; sappend('v',k,timerMonth[i] & 0x0F);
|
||||||
|
k[0] = 'D'; sappend('v',k,timerDay[i]);
|
||||||
|
k[0] = 'E'; sappend('v',k,timerDayEnd[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user