Merge branch 'master' into solidRgbwLedStrips
This commit is contained in:
commit
2188509d2c
@ -214,7 +214,7 @@ lib_deps =
|
|||||||
lib_ignore =
|
lib_ignore =
|
||||||
IRremoteESP8266
|
IRremoteESP8266
|
||||||
ESPAsyncUDP
|
ESPAsyncUDP
|
||||||
|
|
||||||
[env:esp8285_4CH_MagicHome]
|
[env:esp8285_4CH_MagicHome]
|
||||||
board = esp8285
|
board = esp8285
|
||||||
platform = ${common:esp8266_1M.platform}
|
platform = ${common:esp8266_1M.platform}
|
||||||
@ -258,4 +258,5 @@ build_flags =
|
|||||||
-D WLED_USE_H801
|
-D WLED_USE_H801
|
||||||
-D WLED_ENABLE_5CH_LEDS
|
-D WLED_ENABLE_5CH_LEDS
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps_external}
|
${common.lib_deps_external}
|
||||||
|
|
19
readme.md
19
readme.md
@ -10,13 +10,14 @@
|
|||||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
|
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
|
||||||
|
|
||||||
### Features:
|
### Features:
|
||||||
- WS2812FX library integrated for 80 special effects
|
- WS2812FX library integrated for almost 90 special effects
|
||||||
- FastLED noise effects and palettes
|
- FastLED noise effects and palettes
|
||||||
- Customizable Mobile and desktop UI with color and effect controls
|
- Modern UI with color, effect and segment controls
|
||||||
|
- Segments to set different effects and colors to parts of the LEDs
|
||||||
- Settings page - configuration over network
|
- Settings page - configuration over network
|
||||||
- Access Point and station mode - automatic failsafe AP
|
- Access Point and station mode - automatic failsafe AP
|
||||||
- Support for RGBW strips
|
- Support for RGBW strips
|
||||||
- 25 user presets to save and load colors/effects easily, supports cycling through them.
|
- 16 user presets to save and load colors/effects easily, supports cycling through them.
|
||||||
- Macro functions to automatically execute API calls
|
- Macro functions to automatically execute API calls
|
||||||
- Nightlight function (gradually dims down)
|
- Nightlight function (gradually dims down)
|
||||||
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
||||||
@ -42,6 +43,12 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
|
|||||||
|
|
||||||
See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
|
See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
|
||||||
|
|
||||||
|
DrZzs has made some excellent video guides:
|
||||||
|
[Introduction, hardware and installation](https://www.youtube.com/watch?v=tXvtxwK3jRk)
|
||||||
|
[Settings, tips and tricks](https://www.youtube.com/watch?v=6eCE2BpLaUQ)
|
||||||
|
|
||||||
|
If you'd rather read, here is a very [detailed step-by-step beginner tutorial](https://tynick.com/blog/11-03-2019/getting-started-with-wled-on-esp8266/) by tynick!
|
||||||
|
|
||||||
### Other
|
### Other
|
||||||
|
|
||||||
Licensed under the MIT license
|
Licensed under the MIT license
|
||||||
@ -52,3 +59,9 @@ Uses Linearicons by Perxis!
|
|||||||
Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED!
|
Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED!
|
||||||
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com).
|
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com).
|
||||||
If WLED really brightens up your every day, you can [![](https://img.shields.io/badge/send%20me%20a%20small%20gift-paypal-blue.svg?style=flat-square)](https://paypal.me/aircoookie)
|
If WLED really brightens up your every day, you can [![](https://img.shields.io/badge/send%20me%20a%20small%20gift-paypal-blue.svg?style=flat-square)](https://paypal.me/aircoookie)
|
||||||
|
|
||||||
|
*Disclaimer:*
|
||||||
|
If you are sensitive to photoeleptic seizures it is not recommended that you use this software.
|
||||||
|
In case you still want to try, don't use strobe, lighting or noise modes or high effect speed settings.
|
||||||
|
As per the MIT license, i assume no liability for any damage to you or any other person or equipment.
|
||||||
|
|
||||||
|
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt
Normal file
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
These files allow WLED 0.8.6 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up.
|
||||||
|
|
||||||
|
This code uses Aircookie's WLED software. It has a premade file for user modifications. I use it to publish the temperature from the dallas temperature sensor on the Quinled board. The entries for the top of the WLED00 file, initializes the required libraries, and variables for the sensor. The .ino file waits for 60 seconds, and checks to see if the MQTT server is connected (thanks Aircoookie). It then poles the sensor, and published it using the MQTT service already running, using the main topic programmed in the WLED UI.
|
||||||
|
|
||||||
|
To install:
|
||||||
|
|
||||||
|
Add the enties in the WLED00 file to the top of the same file from Aircoookies WLED.
|
||||||
|
Replace the WLED06_usermod.ino file in Aircoookies WLED folder.
|
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt
Normal file
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//Intiating code for QuinLED Dig-Uno temp sensor
|
||||||
|
//Uncomment Celsius if that is your prefered temperature scale
|
||||||
|
#include <DallasTemperature.h>
|
||||||
|
OneWire oneWire(14);
|
||||||
|
DallasTemperature sensors(&oneWire);
|
||||||
|
long temptimer = millis();
|
||||||
|
long lastMeasure = 0;
|
||||||
|
//#define Celsius
|
41
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino
Normal file
41
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//starts Dallas Temp service on boot
|
||||||
|
void userSetup()
|
||||||
|
{
|
||||||
|
// Start the DS18B20 sensor
|
||||||
|
sensors.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
|
||||||
|
void userConnected()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void userLoop()
|
||||||
|
{
|
||||||
|
temptimer = millis();
|
||||||
|
|
||||||
|
// Timer to publishe new temperature every 60 seconds
|
||||||
|
if (temptimer - lastMeasure > 60000) {
|
||||||
|
lastMeasure = temptimer;
|
||||||
|
|
||||||
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
|
if (mqtt != nullptr){
|
||||||
|
sensors.requestTemperatures();
|
||||||
|
|
||||||
|
//Gets prefered temperature scale based on selection in definitions section
|
||||||
|
#ifdef Celsius
|
||||||
|
float board_temperature = sensors.getTempCByIndex(0);
|
||||||
|
#else
|
||||||
|
float board_temperature = sensors.getTempFByIndex(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server.
|
||||||
|
char subuf[38];
|
||||||
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
|
strcat(subuf, "/temperature");
|
||||||
|
mqtt->publish(subuf, 0, true, String(board_temperature).c_str());
|
||||||
|
return;}
|
||||||
|
return;}
|
||||||
|
return;
|
||||||
|
}
|
18
usermods/readme.md
Normal file
18
usermods/readme.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
### Usermods
|
||||||
|
|
||||||
|
This folder serves as a repository for usermods (custom `wled06_usermod.ino` files)!
|
||||||
|
|
||||||
|
If you have created an usermod that you believe is useful (for example to support a particular sensor, display, feature...), feel free to contribute by opening a pull request!
|
||||||
|
|
||||||
|
In order for other people to be able to have fun with your usermod, please keep these points in mind:
|
||||||
|
|
||||||
|
- Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`)
|
||||||
|
- Include your custom `wled06_usermod.ino` file
|
||||||
|
- If your usermod requieres changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod
|
||||||
|
- Create a pull request!
|
||||||
|
- If your feature is useful for the majority of WLED users, I will consider adding it to the base code!
|
||||||
|
|
||||||
|
While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break.
|
||||||
|
I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod.
|
||||||
|
|
||||||
|
Thank you for your help :)
|
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();
|
||||||
|
}
|
||||||
|
}
|
35
usermods/ssd1306_i2c_oled_u8g2/README.md
Normal file
35
usermods/ssd1306_i2c_oled_u8g2/README.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# SSD1306 128x32 OLED via I2C with u8g2
|
||||||
|
This usermod allows to connect 128x32 Oled display to WLED controlled and show
|
||||||
|
the next information:
|
||||||
|
- Current SSID
|
||||||
|
- IP address if obtained
|
||||||
|
* in AP mode and turned off lightning AP password is shown
|
||||||
|
- Current effect
|
||||||
|
- Current palette
|
||||||
|
- On/Off icon (sun/moon)
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
![Hardware connection](assets/hw_connection.png)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
Functionality checked with:
|
||||||
|
- commit 095429a7df4f9e2b34dd464f7bbfd068df6558eb
|
||||||
|
- Wemos d1 mini
|
||||||
|
- PlatformIO
|
||||||
|
- Generic SSD1306 128x32 I2C OLED display from aliexpress
|
||||||
|
|
||||||
|
### Platformio
|
||||||
|
Add `U8g2@~2.27.2` dependency to `lib_deps_external` under `[common]` section in `platformio.ini`:
|
||||||
|
```ini
|
||||||
|
# platformio.ini
|
||||||
|
...
|
||||||
|
[common]
|
||||||
|
...
|
||||||
|
lib_deps_external =
|
||||||
|
...
|
||||||
|
U8g2@~2.27.2
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arduino IDE
|
||||||
|
Install library `U8g2 by oliver` in `Tools | Include Library | Manage libraries` menu.
|
BIN
usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png
Normal file
BIN
usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
149
usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino
Normal file
149
usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// gets called once at boot. Do all initialization that doesn't depend on
|
||||||
|
// network here
|
||||||
|
void userSetup() {
|
||||||
|
u8x8.begin();
|
||||||
|
u8x8.setPowerSave(0);
|
||||||
|
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||||
|
u8x8.drawString(0, 0, "Loading...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||||
|
// interfaces here
|
||||||
|
void userConnected() {}
|
||||||
|
|
||||||
|
// needRedraw marks if redraw is required to prevent often redrawing.
|
||||||
|
bool needRedraw = true;
|
||||||
|
|
||||||
|
// Next variables hold the previous known values to determine if redraw is
|
||||||
|
// required.
|
||||||
|
String knownSsid = "";
|
||||||
|
IPAddress knownIp;
|
||||||
|
uint8_t knownBrightness = 0;
|
||||||
|
uint8_t knownMode = 0;
|
||||||
|
uint8_t knownPalette = 0;
|
||||||
|
|
||||||
|
long lastUpdate = 0;
|
||||||
|
// How often we are redrawing screen
|
||||||
|
#define USER_LOOP_REFRESH_RATE_MS 5000
|
||||||
|
|
||||||
|
void userLoop() {
|
||||||
|
|
||||||
|
// Check if we time interval for redrawing passes.
|
||||||
|
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastUpdate = millis();
|
||||||
|
|
||||||
|
// Check if values which are shown on display changed from the last tiem.
|
||||||
|
if ((apActive == true ? String(apSSID) : WiFi.SSID()) != knownSsid) {
|
||||||
|
needRedraw = true;
|
||||||
|
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
|
||||||
|
needRedraw = true;
|
||||||
|
} else if (knownBrightness != bri) {
|
||||||
|
needRedraw = true;
|
||||||
|
} else if (knownMode != strip.getMode()) {
|
||||||
|
needRedraw = true;
|
||||||
|
} else if (knownPalette != strip.getSegment(0).palette) {
|
||||||
|
needRedraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needRedraw) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
needRedraw = false;
|
||||||
|
|
||||||
|
// Update last known values.
|
||||||
|
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
|
||||||
|
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
|
||||||
|
knownBrightness = bri;
|
||||||
|
knownMode = strip.getMode();
|
||||||
|
knownPalette = strip.getSegment(0).palette;
|
||||||
|
|
||||||
|
u8x8.clear();
|
||||||
|
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||||
|
|
||||||
|
// First row with Wifi name
|
||||||
|
u8x8.setCursor(1, 0);
|
||||||
|
u8x8.print(ssid.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())
|
||||||
|
u8x8.print("~");
|
||||||
|
|
||||||
|
// Second row with IP or Psssword
|
||||||
|
u8x8.setCursor(1, 1);
|
||||||
|
// Print password in AP mode and if led is OFF.
|
||||||
|
if (apActive && bri == 0)
|
||||||
|
u8x8.print(apPass);
|
||||||
|
else
|
||||||
|
u8x8.print(ip);
|
||||||
|
|
||||||
|
// Third row with mode name
|
||||||
|
u8x8.setCursor(2, 2);
|
||||||
|
uint8_t qComma = 0;
|
||||||
|
bool insideQuotes = false;
|
||||||
|
uint8_t printedChars = 0;
|
||||||
|
char singleJsonSymbol;
|
||||||
|
// Find the mode name in JSON
|
||||||
|
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
|
||||||
|
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
|
||||||
|
switch (singleJsonSymbol) {
|
||||||
|
case '"':
|
||||||
|
insideQuotes = !insideQuotes;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
qComma++;
|
||||||
|
default:
|
||||||
|
if (!insideQuotes || (qComma != knownMode))
|
||||||
|
break;
|
||||||
|
u8x8.print(singleJsonSymbol);
|
||||||
|
printedChars++;
|
||||||
|
}
|
||||||
|
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Fourth row with palette name
|
||||||
|
u8x8.setCursor(2, 3);
|
||||||
|
qComma = 0;
|
||||||
|
insideQuotes = false;
|
||||||
|
printedChars = 0;
|
||||||
|
// Looking for palette name in JSON.
|
||||||
|
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
|
||||||
|
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
|
||||||
|
switch (singleJsonSymbol) {
|
||||||
|
case '"':
|
||||||
|
insideQuotes = !insideQuotes;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
qComma++;
|
||||||
|
default:
|
||||||
|
if (!insideQuotes || (qComma != knownPalette))
|
||||||
|
break;
|
||||||
|
u8x8.print(singleJsonSymbol);
|
||||||
|
printedChars++;
|
||||||
|
}
|
||||||
|
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
|
||||||
|
u8x8.drawGlyph(0, 0, 80); // wifi icon
|
||||||
|
u8x8.drawGlyph(0, 1, 68); // home icon
|
||||||
|
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
|
||||||
|
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
|
||||||
|
}
|
407
wled00/FX.cpp
407
wled00/FX.cpp
@ -141,7 +141,7 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) {
|
|||||||
SEGENV.step = 0;
|
SEGENV.step = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ledIndex = (prog * SEGLEN) >> 15;
|
uint16_t ledIndex = (prog * SEGLEN) >> 15;
|
||||||
uint16_t rem = 0;
|
uint16_t rem = 0;
|
||||||
rem = (prog * SEGLEN) * 2; //mod 0xFFFF
|
rem = (prog * SEGLEN) * 2; //mod 0xFFFF
|
||||||
@ -262,7 +262,7 @@ uint16_t WS2812FX::mode_dynamic(void) {
|
|||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::mode_breath(void) {
|
uint16_t WS2812FX::mode_breath(void) {
|
||||||
uint16_t var = 0;
|
uint16_t var = 0;
|
||||||
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)) & 0xFFFF;
|
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10));
|
||||||
counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048
|
counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048
|
||||||
if (counter < 16384) {
|
if (counter < 16384) {
|
||||||
if (counter > 8192) counter = 8192 - (counter - 8192);
|
if (counter > 8192) counter = 8192 - (counter - 8192);
|
||||||
@ -282,9 +282,8 @@ uint16_t WS2812FX::mode_breath(void) {
|
|||||||
* Fades the LEDs between two colors
|
* Fades the LEDs between two colors
|
||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::mode_fade(void) {
|
uint16_t WS2812FX::mode_fade(void) {
|
||||||
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10)) & 0xFFFF;
|
uint16_t counter = (now * ((SEGMENT.speed >> 3) +10));
|
||||||
if (counter > 32767) counter = 32768 - (counter - 32768);
|
uint8_t lum = triwave16(counter) >> 8;
|
||||||
uint8_t lum = counter >> 7;
|
|
||||||
|
|
||||||
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum));
|
setPixelColor(i, color_blend(SEGCOLOR(1), color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), lum));
|
||||||
@ -534,11 +533,18 @@ uint16_t WS2812FX::mode_dissolve_random(void) {
|
|||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::mode_sparkle(void) {
|
uint16_t WS2812FX::mode_sparkle(void) {
|
||||||
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
|
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1));
|
||||||
}
|
}
|
||||||
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
uint32_t cycleTime = 10 + (255 - SEGMENT.speed)*2;
|
||||||
|
uint32_t it = now / cycleTime;
|
||||||
|
if (it != SEGENV.step)
|
||||||
|
{
|
||||||
|
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
||||||
|
SEGENV.step = it;
|
||||||
|
}
|
||||||
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(0));
|
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(0));
|
||||||
return 10 + (uint16_t)(255 - SEGMENT.speed);
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -547,15 +553,10 @@ uint16_t WS2812FX::mode_sparkle(void) {
|
|||||||
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
* Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
|
||||||
*/
|
*/
|
||||||
uint16_t WS2812FX::mode_flash_sparkle(void) {
|
uint16_t WS2812FX::mode_flash_sparkle(void) {
|
||||||
if(SEGENV.call == 0) {
|
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) {
|
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
||||||
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i = SEGMENT.start + SEGENV.aux0;
|
|
||||||
setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0));
|
|
||||||
|
|
||||||
if(random8(5) == 0) {
|
if(random8(5) == 0) {
|
||||||
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
SEGENV.aux0 = random16(SEGLEN); // aux0 stores the random led index
|
||||||
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(1));
|
setPixelColor(SEGMENT.start + SEGENV.aux0, SEGCOLOR(1));
|
||||||
@ -614,7 +615,6 @@ uint16_t WS2812FX::mode_multi_strobe(void) {
|
|||||||
uint16_t WS2812FX::mode_android(void) {
|
uint16_t WS2812FX::mode_android(void) {
|
||||||
if (SEGENV.call == 0)
|
if (SEGENV.call == 0)
|
||||||
{
|
{
|
||||||
SEGENV.aux0 = 0;
|
|
||||||
SEGENV.step = SEGMENT.start;
|
SEGENV.step = SEGMENT.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1100,182 +1100,56 @@ uint16_t WS2812FX::mode_loading(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//American Police Light with all LEDs Red and Blue
|
||||||
* Lights all LEDs after each other up starting from the outer edges and
|
uint16_t WS2812FX::police_base(uint32_t color1, uint32_t color2)
|
||||||
* finishing in the middle. Then turns them in reverse order off. Repeat.
|
{
|
||||||
*/
|
uint16_t counter = now * ((SEGMENT.speed >> 3) +1);
|
||||||
uint16_t WS2812FX::mode_dual_color_wipe_in_out(void) {
|
uint16_t idexR = (counter * SEGLEN) >> 16;
|
||||||
int end = SEGLEN - SEGENV.step - 1;
|
if (idexR >= SEGLEN) idexR = 0;
|
||||||
bool odd = (SEGLEN % 2) == 1;
|
|
||||||
int mid = odd ? ((SEGLEN / 2) + 1) : (SEGLEN / 2);
|
uint16_t topindex = SEGLEN >> 1;
|
||||||
if (SEGENV.step < mid) {
|
uint16_t idexB = idexR + topindex;
|
||||||
byte pindex = map(SEGENV.step, 0, mid -1, 0, 255);
|
|
||||||
uint32_t col = color_from_palette(pindex, false, false, 0);
|
if (idexR > topindex) idexB -= SEGLEN;
|
||||||
|
if (idexB >= SEGLEN) idexB = 0; //otherwise overflow on odd number of LEDs
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step, col);
|
|
||||||
setPixelColor(SEGMENT.start + end, col);
|
setPixelColor(SEGMENT.start + idexR, color1);
|
||||||
} else {
|
setPixelColor(SEGMENT.start + idexB, color2);
|
||||||
if (odd) {
|
|
||||||
// If odd, we need to 'double count' the center LED (once to turn it on,
|
return FRAMETIME;
|
||||||
// once to turn it off). So trail one behind after the middle LED.
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step - 1, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + end + 1, SEGCOLOR(1));
|
|
||||||
} else {
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + end, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SEGENV.step++;
|
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step > SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step >= SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SPEED_FORMULA_L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//American Police Light with all LEDs Red and Blue
|
||||||
* Lights all LEDs after each other up starting from the outer edges and
|
uint16_t WS2812FX::mode_police_all()
|
||||||
* finishing in the middle. Then turns them in that order off. Repeat.
|
{
|
||||||
*/
|
return police_base(RED, BLUE);
|
||||||
uint16_t WS2812FX::mode_dual_color_wipe_in_in(void) {
|
|
||||||
bool odd = (SEGLEN % 2) == 1;
|
|
||||||
int mid = SEGLEN / 2;
|
|
||||||
byte pindex = 0;
|
|
||||||
uint32_t col = 0;
|
|
||||||
if (SEGENV.step <= mid)
|
|
||||||
{
|
|
||||||
pindex = map(SEGENV.step, 0, mid, 0, 255);
|
|
||||||
col = color_from_palette(pindex, false, false, 0);
|
|
||||||
}
|
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step <= mid) {
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step, col);
|
|
||||||
setPixelColor(SEGMENT.start + SEGLEN - SEGENV.step - 1, col);
|
|
||||||
} else {
|
|
||||||
int i = SEGENV.step - mid;
|
|
||||||
setPixelColor(SEGMENT.start + i - 1, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + SEGLEN - i, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step < mid) {
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step, col);
|
|
||||||
setPixelColor(SEGMENT.start + SEGLEN - SEGENV.step - 1, col);
|
|
||||||
} else {
|
|
||||||
int i = SEGENV.step - mid;
|
|
||||||
setPixelColor(SEGMENT.start + i, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + SEGLEN - i - 1, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SEGENV.step++;
|
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step > SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step >= SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SPEED_FORMULA_L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
//Police Lights Red and Blue
|
||||||
* Lights all LEDs after each other up starting from the middle and
|
uint16_t WS2812FX::mode_police()
|
||||||
* finishing at the edges. Then turns them off in that order. Repeat.
|
{
|
||||||
*/
|
fill(SEGCOLOR(1));
|
||||||
uint16_t WS2812FX::mode_dual_color_wipe_out_out(void) {
|
|
||||||
int end = SEGLEN - SEGENV.step - 1;
|
return police_base(RED, BLUE);
|
||||||
bool odd = (SEGLEN % 2) == 1;
|
}
|
||||||
int mid = SEGLEN / 2;
|
|
||||||
byte pindex = 0;
|
|
||||||
uint32_t col = 0;
|
|
||||||
if (SEGENV.step <= mid)
|
|
||||||
{
|
|
||||||
pindex = map(SEGENV.step, 0, mid, 255, 0);
|
|
||||||
col = color_from_palette(pindex, false, false, 0);
|
|
||||||
}
|
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step <= mid) {
|
|
||||||
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
|
|
||||||
setPixelColor(SEGMENT.start + mid - SEGENV.step, col);
|
|
||||||
} else {
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step - 1, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + end + 1, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step < mid) {
|
|
||||||
setPixelColor(SEGMENT.start + mid - SEGENV.step - 1, col);
|
|
||||||
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
|
|
||||||
} else {
|
|
||||||
setPixelColor(SEGMENT.start + SEGENV.step, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + end, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SEGENV.step++;
|
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step > SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step >= SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SPEED_FORMULA_L;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
//Police All with custom colors
|
||||||
* Lights all LEDs after each other up starting from the middle and
|
uint16_t WS2812FX::mode_two_areas()
|
||||||
* finishing at the edges. Then turns them off in reverse order. Repeat.
|
{
|
||||||
*/
|
return police_base(SEGCOLOR(0), SEGCOLOR(1));
|
||||||
uint16_t WS2812FX::mode_dual_color_wipe_out_in(void) {
|
}
|
||||||
bool odd = (SEGLEN % 2) == 1;
|
|
||||||
int mid = SEGLEN / 2;
|
|
||||||
byte pindex = 0;
|
//Police Lights with custom colors
|
||||||
uint32_t col = 0;
|
uint16_t WS2812FX::mode_two_dots()
|
||||||
if (SEGENV.step <= mid)
|
{
|
||||||
{
|
fill(SEGCOLOR(2));
|
||||||
pindex = map(SEGENV.step, 0, mid, 255, 0);
|
uint32_t color2 = (SEGCOLOR(1) == SEGCOLOR(2)) ? SEGCOLOR(0) : SEGCOLOR(1);
|
||||||
col = color_from_palette(pindex, false, false, 0);
|
|
||||||
}
|
return police_base(SEGCOLOR(0), color2);
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step <= mid) {
|
|
||||||
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
|
|
||||||
setPixelColor(SEGMENT.start + mid - SEGENV.step, col);
|
|
||||||
} else {
|
|
||||||
int i = SEGENV.step - mid;
|
|
||||||
setPixelColor(SEGMENT.start + i - 1, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + SEGLEN - i, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step < mid) {
|
|
||||||
setPixelColor(SEGMENT.start + mid - SEGENV.step - 1, col);
|
|
||||||
setPixelColor(SEGMENT.start + mid + SEGENV.step, col);
|
|
||||||
} else {
|
|
||||||
int i = SEGENV.step - mid;
|
|
||||||
setPixelColor(SEGMENT.start + i, SEGCOLOR(1));
|
|
||||||
setPixelColor(SEGMENT.start + SEGLEN - i - 1, SEGCOLOR(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SEGENV.step++;
|
|
||||||
if (odd) {
|
|
||||||
if (SEGENV.step > SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SEGENV.step >= SEGLEN) {
|
|
||||||
SEGENV.step = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SPEED_FORMULA_L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1657,13 +1531,13 @@ uint16_t WS2812FX::mode_palette()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0));
|
bool noWrap = (paletteBlend == 2 || (paletteBlend == 0 && SEGMENT.speed == 0));
|
||||||
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++)
|
for (uint16_t i = 0; i < SEGLEN; i++)
|
||||||
{
|
{
|
||||||
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
|
uint8_t colorIndex = (i * 255 / SEGLEN) - counter;
|
||||||
|
|
||||||
if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end"
|
if (noWrap) colorIndex = map(colorIndex, 0, 255, 0, 240); //cut off blend at palette "end"
|
||||||
|
|
||||||
setPixelColor(i, color_from_palette(colorIndex, false, true, 255));
|
setPixelColor(SEGMENT.start + i, color_from_palette(colorIndex, false, true, 255));
|
||||||
}
|
}
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
@ -2197,7 +2071,7 @@ CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
|
|||||||
// "CalculateOneTwinkle" on each pixel. It then displays
|
// "CalculateOneTwinkle" on each pixel. It then displays
|
||||||
// either the twinkle color of the background color,
|
// either the twinkle color of the background color,
|
||||||
// whichever is brighter.
|
// whichever is brighter.
|
||||||
void WS2812FX::twinklefox_base(bool cat)
|
uint16_t WS2812FX::twinklefox_base(bool cat)
|
||||||
{
|
{
|
||||||
// "PRNG16" is the pseudorandom number generator
|
// "PRNG16" is the pseudorandom number generator
|
||||||
// It MUST be reset to the same starting value each time
|
// It MUST be reset to the same starting value each time
|
||||||
@ -2253,18 +2127,17 @@ void WS2812FX::twinklefox_base(bool cat)
|
|||||||
setPixelColor(i, bg.r, bg.g, bg.b);
|
setPixelColor(i, bg.r, bg.g, bg.b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t WS2812FX::mode_twinklefox()
|
uint16_t WS2812FX::mode_twinklefox()
|
||||||
{
|
{
|
||||||
twinklefox_base(false);
|
return twinklefox_base(false);
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t WS2812FX::mode_twinklecat()
|
uint16_t WS2812FX::mode_twinklecat()
|
||||||
{
|
{
|
||||||
twinklefox_base(true);
|
return twinklefox_base(true);
|
||||||
return FRAMETIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2324,3 +2197,155 @@ uint16_t WS2812FX::mode_halloween_eyes()
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Speed slider sets amount of LEDs lit, intensity sets unlit
|
||||||
|
uint16_t WS2812FX::mode_static_pattern()
|
||||||
|
{
|
||||||
|
uint16_t lit = 1 + SEGMENT.speed;
|
||||||
|
uint16_t unlit = 1 + SEGMENT.intensity;
|
||||||
|
bool drawingLit = true;
|
||||||
|
uint16_t cnt = 0;
|
||||||
|
|
||||||
|
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
|
setPixelColor(i, (drawingLit) ? color_from_palette(i, true, PALETTE_SOLID_WRAP, 0) : SEGCOLOR(1));
|
||||||
|
cnt++;
|
||||||
|
if (cnt >= ((drawingLit) ? lit : unlit)) {
|
||||||
|
cnt = 0;
|
||||||
|
drawingLit = !drawingLit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::mode_tri_static_pattern()
|
||||||
|
{
|
||||||
|
uint8_t segSize = (SEGMENT.intensity >> 5) +1;
|
||||||
|
uint8_t currSeg = 0;
|
||||||
|
uint16_t currSegCount = 0;
|
||||||
|
|
||||||
|
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
|
if ( currSeg % 3 == 0 ) {
|
||||||
|
setPixelColor(i, SEGCOLOR(0));
|
||||||
|
} else if( currSeg % 3 == 1) {
|
||||||
|
setPixelColor(i, SEGCOLOR(1));
|
||||||
|
} else {
|
||||||
|
setPixelColor(i, (SEGCOLOR(2) > 0 ? SEGCOLOR(2) : WHITE));
|
||||||
|
}
|
||||||
|
currSegCount += 1;
|
||||||
|
if (currSegCount >= segSize) {
|
||||||
|
currSeg +=1;
|
||||||
|
currSegCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t WS2812FX::spots_base(uint16_t threshold)
|
||||||
|
{
|
||||||
|
fill(SEGCOLOR(1));
|
||||||
|
|
||||||
|
uint16_t maxZones = SEGLEN >> 2;
|
||||||
|
uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8);
|
||||||
|
uint16_t zoneLen = SEGLEN / zones;
|
||||||
|
uint16_t offset = (SEGLEN - zones * zoneLen) >> 1;
|
||||||
|
|
||||||
|
for (uint16_t z = 0; z < zones; z++)
|
||||||
|
{
|
||||||
|
uint16_t pos = offset + z * zoneLen;
|
||||||
|
for (uint16_t i = 0; i < zoneLen; i++)
|
||||||
|
{
|
||||||
|
uint16_t wave = triwave16((i * 0xFFFF) / zoneLen);
|
||||||
|
if (wave > threshold) {
|
||||||
|
uint16_t index = SEGMENT.start + pos + i;
|
||||||
|
uint8_t s = (wave - threshold)*255 / (0xFFFF - threshold);
|
||||||
|
setPixelColor(index, color_blend(color_from_palette(index, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Intensity slider sets number of "lights", speed sets LEDs per light
|
||||||
|
uint16_t WS2812FX::mode_spots()
|
||||||
|
{
|
||||||
|
return spots_base((255 - SEGMENT.speed) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Intensity slider sets number of "lights", LEDs per light fade in and out
|
||||||
|
uint16_t WS2812FX::mode_spots_fade()
|
||||||
|
{
|
||||||
|
uint16_t counter = now * ((SEGMENT.speed >> 2) +8);
|
||||||
|
uint16_t t = triwave16(counter);
|
||||||
|
uint16_t tr = (t >> 1) + (t >> 2);
|
||||||
|
return spots_base(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6
|
||||||
|
uint16_t WS2812FX::mode_glitter()
|
||||||
|
{
|
||||||
|
mode_palette();
|
||||||
|
|
||||||
|
if (SEGMENT.intensity > random8())
|
||||||
|
{
|
||||||
|
setPixelColor(SEGMENT.start + random16(SEGLEN), ULTRAWHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//values close to 100 produce 5Hz flicker, which looks very candle-y
|
||||||
|
//Inspired by https://github.com/avanhanegem/ArduinoCandleEffectNeoPixel
|
||||||
|
//and https://cpldcpu.wordpress.com/2016/01/05/reverse-engineering-a-real-candle/
|
||||||
|
|
||||||
|
uint16_t WS2812FX::mode_candle()
|
||||||
|
{
|
||||||
|
if (SEGENV.call == 0) {
|
||||||
|
SEGENV.aux0 = 128; SEGENV.aux1 = 132; SEGENV.step = 1;
|
||||||
|
}
|
||||||
|
bool newTarget = false;
|
||||||
|
|
||||||
|
uint8_t s = SEGENV.aux0, target = SEGENV.aux1, fadeStep = SEGENV.step;
|
||||||
|
|
||||||
|
if (target > s) { //fade up
|
||||||
|
s = qadd8(s, fadeStep);
|
||||||
|
if (s >= target) newTarget = true;
|
||||||
|
} else {
|
||||||
|
s = qsub8(s, fadeStep);
|
||||||
|
if (s <= target) newTarget = true;
|
||||||
|
}
|
||||||
|
SEGENV.aux0 = s;
|
||||||
|
|
||||||
|
for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) {
|
||||||
|
setPixelColor(i, color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 0), SEGCOLOR(1), 255-s));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTarget)
|
||||||
|
{
|
||||||
|
uint8_t valrange = SEGMENT.intensity;
|
||||||
|
uint8_t rndval = valrange >> 1;
|
||||||
|
target = random8(rndval) + random8(rndval);
|
||||||
|
if (target < (rndval >> 1)) target = (rndval >> 1) + random8(rndval);
|
||||||
|
uint8_t offset = (255 - valrange) >> 1;
|
||||||
|
target += offset;
|
||||||
|
|
||||||
|
uint8_t dif = (target > s) ? target - s : s - target;
|
||||||
|
|
||||||
|
//how much to move closer to target per frame
|
||||||
|
fadeStep = dif >> 2; //mode called every ~25 ms, so 4 frames to have a new target every 100ms
|
||||||
|
if (fadeStep == 0) fadeStep = 1;
|
||||||
|
|
||||||
|
SEGENV.step = fadeStep;
|
||||||
|
SEGENV.aux1 = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
104
wled00/FX.h
104
wled00/FX.h
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
/* Not used in all effects yet */
|
/* Not used in all effects yet */
|
||||||
#define WLED_FPS 42
|
#define WLED_FPS 42
|
||||||
#define FRAMETIME 1000/WLED_FPS
|
#define FRAMETIME (1000/WLED_FPS)
|
||||||
|
|
||||||
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
|
/* each segment uses 37 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 */
|
||||||
@ -84,7 +84,7 @@
|
|||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
||||||
|
|
||||||
#define MODE_COUNT 83
|
#define MODE_COUNT 89
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -134,10 +134,10 @@
|
|||||||
#define FX_MODE_FIRE_FLICKER 45
|
#define FX_MODE_FIRE_FLICKER 45
|
||||||
#define FX_MODE_GRADIENT 46
|
#define FX_MODE_GRADIENT 46
|
||||||
#define FX_MODE_LOADING 47
|
#define FX_MODE_LOADING 47
|
||||||
#define FX_MODE_DUAL_COLOR_WIPE_IN_OUT 48
|
#define FX_MODE_POLICE 48
|
||||||
#define FX_MODE_DUAL_COLOR_WIPE_IN_IN 49
|
#define FX_MODE_POLICE_ALL 49
|
||||||
#define FX_MODE_DUAL_COLOR_WIPE_OUT_OUT 50
|
#define FX_MODE_TWO_DOTS 50
|
||||||
#define FX_MODE_DUAL_COLOR_WIPE_OUT_IN 51
|
#define FX_MODE_TWO_AREAS 51
|
||||||
#define FX_MODE_CIRCUS_COMBUSTUS 52
|
#define FX_MODE_CIRCUS_COMBUSTUS 52
|
||||||
#define FX_MODE_HALLOWEEN 53
|
#define FX_MODE_HALLOWEEN 53
|
||||||
#define FX_MODE_TRICOLOR_CHASE 54
|
#define FX_MODE_TRICOLOR_CHASE 54
|
||||||
@ -149,7 +149,6 @@
|
|||||||
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
||||||
#define FX_MODE_RANDOM_CHASE 61
|
#define FX_MODE_RANDOM_CHASE 61
|
||||||
#define FX_MODE_OSCILLATE 62
|
#define FX_MODE_OSCILLATE 62
|
||||||
//Modes that use FastLED -->
|
|
||||||
#define FX_MODE_PRIDE_2015 63
|
#define FX_MODE_PRIDE_2015 63
|
||||||
#define FX_MODE_JUGGLE 64
|
#define FX_MODE_JUGGLE 64
|
||||||
#define FX_MODE_PALETTE 65
|
#define FX_MODE_PALETTE 65
|
||||||
@ -170,6 +169,12 @@
|
|||||||
#define FX_MODE_TWINKLEFOX 80
|
#define FX_MODE_TWINKLEFOX 80
|
||||||
#define FX_MODE_TWINKLECAT 81
|
#define FX_MODE_TWINKLECAT 81
|
||||||
#define FX_MODE_HALLOWEEN_EYES 82
|
#define FX_MODE_HALLOWEEN_EYES 82
|
||||||
|
#define FX_MODE_STATIC_PATTERN 83
|
||||||
|
#define FX_MODE_TRI_STATIC_PATTERN 84
|
||||||
|
#define FX_MODE_SPOTS 85
|
||||||
|
#define FX_MODE_SPOTS_FADE 86
|
||||||
|
#define FX_MODE_GLITTER 87
|
||||||
|
#define FX_MODE_CANDLE 88
|
||||||
|
|
||||||
|
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
@ -177,7 +182,7 @@ class WS2812FX {
|
|||||||
|
|
||||||
// segment parameters
|
// segment parameters
|
||||||
public:
|
public:
|
||||||
typedef struct Segment { // 21 bytes
|
typedef struct Segment { // 24 bytes
|
||||||
uint16_t start;
|
uint16_t start;
|
||||||
uint16_t stop; //segment invalid if stop == 0
|
uint16_t stop; //segment invalid if stop == 0
|
||||||
uint8_t speed;
|
uint8_t speed;
|
||||||
@ -185,6 +190,8 @@ class WS2812FX {
|
|||||||
uint8_t palette;
|
uint8_t palette;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected
|
uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected
|
||||||
|
uint8_t group, spacing;
|
||||||
|
uint8_t opacity;
|
||||||
uint32_t colors[NUM_COLORS];
|
uint32_t colors[NUM_COLORS];
|
||||||
void setOption(uint8_t n, bool val)
|
void setOption(uint8_t n, bool val)
|
||||||
{
|
{
|
||||||
@ -271,10 +278,10 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
||||||
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
|
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
|
||||||
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
|
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
|
||||||
_mode[FX_MODE_DUAL_COLOR_WIPE_IN_OUT] = &WS2812FX::mode_dual_color_wipe_in_out;
|
_mode[FX_MODE_POLICE] = &WS2812FX::mode_police;
|
||||||
_mode[FX_MODE_DUAL_COLOR_WIPE_IN_IN] = &WS2812FX::mode_dual_color_wipe_in_in;
|
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_police_all;
|
||||||
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_OUT] = &WS2812FX::mode_dual_color_wipe_out_out;
|
_mode[FX_MODE_TWO_DOTS] = &WS2812FX::mode_two_dots;
|
||||||
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_IN] = &WS2812FX::mode_dual_color_wipe_out_in;
|
_mode[FX_MODE_TWO_AREAS] = &WS2812FX::mode_two_areas;
|
||||||
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
||||||
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
||||||
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
||||||
@ -308,6 +315,12 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
_mode[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
||||||
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
|
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
|
||||||
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
|
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
|
||||||
|
_mode[FX_MODE_STATIC_PATTERN] = &WS2812FX::mode_static_pattern;
|
||||||
|
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
||||||
|
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
||||||
|
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
||||||
|
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
|
||||||
|
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
|
||||||
|
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
@ -322,15 +335,11 @@ class WS2812FX {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
init(bool supportWhite, uint16_t countPixels, bool skipFirs),
|
init(bool supportWhite, uint16_t countPixels, bool skipFirs, uint8_t disableNLeds),
|
||||||
service(void),
|
service(void),
|
||||||
blur(uint8_t),
|
blur(uint8_t),
|
||||||
fade_out(uint8_t r),
|
fade_out(uint8_t r),
|
||||||
setMode(uint8_t m),
|
|
||||||
setMode(uint8_t segid, uint8_t m),
|
setMode(uint8_t segid, uint8_t m),
|
||||||
setSpeed(uint8_t s),
|
|
||||||
setIntensity(uint8_t i),
|
|
||||||
setPalette(uint8_t p),
|
|
||||||
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||||
setColor(uint8_t slot, uint32_t c),
|
setColor(uint8_t slot, uint32_t c),
|
||||||
setBrightness(uint8_t b),
|
setBrightness(uint8_t b),
|
||||||
@ -356,27 +365,33 @@ class WS2812FX {
|
|||||||
reverseMode = false,
|
reverseMode = false,
|
||||||
gammaCorrectBri = false,
|
gammaCorrectBri = false,
|
||||||
gammaCorrectCol = true,
|
gammaCorrectCol = true,
|
||||||
|
applyToAllSelected = true,
|
||||||
|
segmentsAreIdentical(Segment* a, Segment* b),
|
||||||
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
|
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
returnedSegment = 0,
|
mainSegment = 0,
|
||||||
paletteFade = 0,
|
paletteFade = 0,
|
||||||
paletteBlend = 0,
|
paletteBlend = 0,
|
||||||
colorOrder = 0,
|
colorOrder = 0,
|
||||||
|
milliampsPerLed = 55,
|
||||||
|
_disableNLeds = 0,
|
||||||
getBrightness(void),
|
getBrightness(void),
|
||||||
getMode(void),
|
getMode(void),
|
||||||
getSpeed(void),
|
getSpeed(void),
|
||||||
getModeCount(void),
|
getModeCount(void),
|
||||||
getPaletteCount(void),
|
getPaletteCount(void),
|
||||||
getMaxSegments(void),
|
getMaxSegments(void),
|
||||||
getFirstSelectedSegment(void),
|
//getFirstSelectedSegment(void),
|
||||||
getReturnedSegmentId(void),
|
getMainSegmentId(void),
|
||||||
gamma8(uint8_t),
|
gamma8(uint8_t),
|
||||||
get_random_wheel_index(uint8_t);
|
get_random_wheel_index(uint8_t);
|
||||||
|
|
||||||
uint16_t
|
uint16_t
|
||||||
ablMilliampsMax,
|
ablMilliampsMax,
|
||||||
currentMilliamps;
|
currentMilliamps,
|
||||||
|
triwave16(uint16_t),
|
||||||
|
getUsableCount();
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
timebase,
|
timebase,
|
||||||
@ -384,6 +399,7 @@ class WS2812FX {
|
|||||||
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
|
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
|
||||||
color_blend(uint32_t,uint32_t,uint8_t),
|
color_blend(uint32_t,uint32_t,uint8_t),
|
||||||
gamma32(uint32_t),
|
gamma32(uint32_t),
|
||||||
|
getLastShow(void),
|
||||||
getPixelColor(uint16_t),
|
getPixelColor(uint16_t),
|
||||||
getColor(void);
|
getColor(void);
|
||||||
|
|
||||||
@ -447,10 +463,10 @@ class WS2812FX {
|
|||||||
mode_fire_flicker(void),
|
mode_fire_flicker(void),
|
||||||
mode_gradient(void),
|
mode_gradient(void),
|
||||||
mode_loading(void),
|
mode_loading(void),
|
||||||
mode_dual_color_wipe_in_out(void),
|
mode_police(void),
|
||||||
mode_dual_color_wipe_in_in(void),
|
mode_police_all(void),
|
||||||
mode_dual_color_wipe_out_out(void),
|
mode_two_dots(void),
|
||||||
mode_dual_color_wipe_out_in(void),
|
mode_two_areas(void),
|
||||||
mode_circus_combustus(void),
|
mode_circus_combustus(void),
|
||||||
mode_bicolor_chase(void),
|
mode_bicolor_chase(void),
|
||||||
mode_tricolor_chase(void),
|
mode_tricolor_chase(void),
|
||||||
@ -481,7 +497,14 @@ class WS2812FX {
|
|||||||
mode_ripple(void),
|
mode_ripple(void),
|
||||||
mode_twinklefox(void),
|
mode_twinklefox(void),
|
||||||
mode_twinklecat(void),
|
mode_twinklecat(void),
|
||||||
mode_halloween_eyes(void);
|
mode_halloween_eyes(void),
|
||||||
|
mode_static_pattern(void),
|
||||||
|
mode_tri_static_pattern(void),
|
||||||
|
mode_spots(void),
|
||||||
|
mode_spots_fade(void),
|
||||||
|
mode_glitter(void),
|
||||||
|
mode_candle(void);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -492,14 +515,13 @@ class WS2812FX {
|
|||||||
CRGBPalette16 targetPalette;
|
CRGBPalette16 targetPalette;
|
||||||
|
|
||||||
uint32_t now;
|
uint32_t now;
|
||||||
uint16_t _length;
|
uint16_t _length, _lengthRaw, _usableCount;
|
||||||
uint16_t _rand16seed;
|
uint16_t _rand16seed;
|
||||||
uint8_t _brightness;
|
uint8_t _brightness;
|
||||||
|
|
||||||
void handle_palette(void);
|
void handle_palette(void);
|
||||||
void fill(uint32_t);
|
void fill(uint32_t);
|
||||||
bool modeUsesLock(uint8_t);
|
bool modeUsesLock(uint8_t);
|
||||||
void twinklefox_base(bool);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_modeUsesLock,
|
_modeUsesLock,
|
||||||
@ -524,8 +546,11 @@ class WS2812FX {
|
|||||||
dissolve(uint32_t),
|
dissolve(uint32_t),
|
||||||
chase(uint32_t, uint32_t, uint32_t, bool),
|
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||||
gradient_base(bool),
|
gradient_base(bool),
|
||||||
|
police_base(uint32_t, uint32_t),
|
||||||
running(uint32_t, uint32_t),
|
running(uint32_t, uint32_t),
|
||||||
tricolor_chase(uint32_t, uint32_t);
|
tricolor_chase(uint32_t, uint32_t),
|
||||||
|
twinklefox_base(bool),
|
||||||
|
spots_base(uint16_t);
|
||||||
|
|
||||||
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
||||||
|
|
||||||
@ -534,9 +559,9 @@ class WS2812FX {
|
|||||||
|
|
||||||
uint8_t _segment_index = 0;
|
uint8_t _segment_index = 0;
|
||||||
uint8_t _segment_index_palette_last = 99;
|
uint8_t _segment_index_palette_last = 99;
|
||||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 21 bytes per element
|
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
|
||||||
// start, stop, speed, intensity, palette, mode, options, color[]
|
// start, stop, speed, intensity, palette, mode, options, 3 unused bytes (group, spacing, opacity), color[]
|
||||||
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, {DEFAULT_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: 16 bytes per element
|
||||||
};
|
};
|
||||||
@ -546,13 +571,13 @@ class WS2812FX {
|
|||||||
const char JSON_mode_names[] PROGMEM = R"=====([
|
const char JSON_mode_names[] PROGMEM = R"=====([
|
||||||
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
|
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
|
||||||
"Scan","Dual Scan","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
|
"Scan","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",
|
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
|
||||||
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
||||||
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","In Out","In In",
|
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
|
||||||
"Out Out","Out In","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||||
"Dual Scanner","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","BPM","Fill Noise",
|
"Scanner Dual ","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
||||||
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Smooth Meteor","Railway","Ripple",
|
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
|
||||||
"Twinklefox","Twinklecat","Halloween Eyes"
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
@ -561,7 +586,8 @@ const char JSON_palette_names[] PROGMEM = R"=====([
|
|||||||
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
|
"Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash",
|
||||||
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
"Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64",
|
||||||
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
"Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn",
|
||||||
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura"
|
"Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura",
|
||||||
|
"Aurora"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,45 +30,61 @@
|
|||||||
#define LED_SKIP_AMOUNT 1
|
#define LED_SKIP_AMOUNT 1
|
||||||
#define MIN_SHOW_DELAY 15
|
#define MIN_SHOW_DELAY 15
|
||||||
|
|
||||||
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uint8_t disableNLeds)
|
||||||
{
|
{
|
||||||
if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL) return;
|
if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && disableNLeds == _disableNLeds) return;
|
||||||
RESET_RUNTIME;
|
RESET_RUNTIME;
|
||||||
_rgbwMode = supportWhite;
|
_rgbwMode = supportWhite;
|
||||||
_skipFirstMode = skipFirst;
|
_skipFirstMode = skipFirst;
|
||||||
_length = countPixels;
|
_length = countPixels;
|
||||||
|
|
||||||
|
if (disableNLeds > 0) {
|
||||||
|
uint16_t groupCount = disableNLeds +1;
|
||||||
|
//since 1st led is lit, even partial group has a led lit, whereas int division truncates decimal.
|
||||||
|
bool hasExtraLight = _length % groupCount != 0;
|
||||||
|
_usableCount = _length/groupCount;
|
||||||
|
_usableCount += hasExtraLight ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
_usableCount = _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
_disableNLeds = disableNLeds;
|
||||||
|
|
||||||
uint8_t ty = 1;
|
uint8_t ty = 1;
|
||||||
if (supportWhite) ty =2;
|
if (supportWhite) ty =2;
|
||||||
uint16_t lengthRaw = _length;
|
_lengthRaw = _length;
|
||||||
if (_skipFirstMode) lengthRaw += LED_SKIP_AMOUNT;
|
if (_skipFirstMode) {
|
||||||
bus->Begin((NeoPixelType)ty, lengthRaw);
|
_lengthRaw += LED_SKIP_AMOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
bus->Begin((NeoPixelType)ty, _lengthRaw);
|
||||||
|
|
||||||
delete[] _locked;
|
delete[] _locked;
|
||||||
_locked = new byte[_length];
|
_locked = new byte[_length];
|
||||||
|
|
||||||
_segments[0].start = 0;
|
_segments[0].start = 0;
|
||||||
_segments[0].stop = _length;
|
_segments[0].stop = _usableCount;
|
||||||
|
|
||||||
unlockAll();
|
unlockAll();
|
||||||
setBrightness(_brightness);
|
setBrightness(_brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::service() {
|
void WS2812FX::service() {
|
||||||
now = millis() + timebase; // Be aware, millis() rolls over every 49 days
|
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
||||||
if (now - _lastShow < MIN_SHOW_DELAY) return;
|
now = nowUp + timebase;
|
||||||
|
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
||||||
bool doShow = false;
|
bool doShow = false;
|
||||||
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
{
|
{
|
||||||
_segment_index = i;
|
_segment_index = i;
|
||||||
if (SEGMENT.isActive())
|
if (SEGMENT.isActive())
|
||||||
{
|
{
|
||||||
if(now > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
|
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
|
||||||
{
|
{
|
||||||
doShow = true;
|
doShow = true;
|
||||||
handle_palette();
|
handle_palette();
|
||||||
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
||||||
SEGENV.next_time = now + delay;
|
SEGENV.next_time = nowUp + delay;
|
||||||
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +92,6 @@ void WS2812FX::service() {
|
|||||||
if(doShow) {
|
if(doShow) {
|
||||||
yield();
|
yield();
|
||||||
show();
|
show();
|
||||||
_lastShow = millis();
|
|
||||||
}
|
}
|
||||||
_triggered = false;
|
_triggered = false;
|
||||||
}
|
}
|
||||||
@ -90,17 +105,18 @@ bool WS2812FX::modeUsesLock(uint8_t m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||||
uint8_t w = (c >> 24) & 0xFF;
|
uint8_t w = (c >> 24);
|
||||||
uint8_t r = (c >> 16) & 0xFF;
|
uint8_t r = (c >> 16);
|
||||||
uint8_t g = (c >> 8) & 0xFF;
|
uint8_t g = (c >> 8);
|
||||||
uint8_t b = c & 0xFF;
|
uint8_t b = c ;
|
||||||
setPixelColor(n, r, g, b, w);
|
setPixelColor(n, r, g, b, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||||
{
|
{
|
||||||
|
i = i * (_disableNLeds+1);
|
||||||
if (_locked[i] && !_modeUsesLock) return;
|
if (_locked[i] && !_modeUsesLock) return;
|
||||||
if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment
|
if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment
|
||||||
byte tmpg = g;
|
byte tmpg = g;
|
||||||
switch (colorOrder) //0 = Grb, default
|
switch (colorOrder) //0 = Grb, default
|
||||||
{
|
{
|
||||||
@ -117,17 +133,21 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
|
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
|
||||||
i += LED_SKIP_AMOUNT;
|
i += LED_SKIP_AMOUNT;
|
||||||
}
|
}
|
||||||
|
if (i < _lengthRaw) bus->SetPixelColor(i, RgbwColor(r,g,b,w));
|
||||||
bus->SetPixelColor(i, RgbwColor(r,g,b,w));
|
if (_disableNLeds > 0) {
|
||||||
|
for(uint16_t offCount=0; offCount < _disableNLeds; offCount++) {
|
||||||
|
if (i < _lengthRaw) bus->SetPixelColor((i + offCount + 1), RgbwColor(0,0,0,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(i>6)return;
|
if(i>6)return;
|
||||||
byte o = 10*i;
|
byte o = 10*i;
|
||||||
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
|
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
|
||||||
{
|
{
|
||||||
byte r2 = (_segments[0].colors[1] >>16) & 0xFF;
|
byte r2 = _segments[0].colors[1] >>16;
|
||||||
byte g2 = (_segments[0].colors[1] >> 8) & 0xFF;
|
byte g2 = _segments[0].colors[1] >> 8;
|
||||||
byte b2 = (_segments[0].colors[1] ) & 0xFF;
|
byte b2 = _segments[0].colors[1];
|
||||||
byte w2 = (_segments[0].colors[1] >>24) & 0xFF;
|
byte w2 = _segments[0].colors[1] >>24;
|
||||||
for (int j=o; j< o+19; j++)
|
for (int j=o; j< o+19; j++)
|
||||||
{
|
{
|
||||||
bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2));
|
bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2));
|
||||||
@ -183,11 +203,7 @@ void WS2812FX::setCronixieDigits(byte d[])
|
|||||||
//Stay safe with high amperage and have a reasonable safety margin!
|
//Stay safe with high amperage and have a reasonable safety margin!
|
||||||
//I am NOT to be held liable for burned down garages!
|
//I am NOT to be held liable for burned down garages!
|
||||||
|
|
||||||
//fine tune power estimation constants for your setup
|
//fine tune power estimation constants for your setup
|
||||||
#define PU_PER_MA 3600 //power units per milliamperere for accurate power estimation
|
|
||||||
//formula: 195075 divided by mA per fully lit LED, here ~54mA)
|
|
||||||
//lowering the value increases the estimated usage and therefore makes the ABL more aggressive
|
|
||||||
|
|
||||||
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
|
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
|
||||||
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
||||||
|
|
||||||
@ -197,12 +213,13 @@ void WS2812FX::show(void) {
|
|||||||
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
||||||
//so A=2,R=255,G=0,B=0 would use 510 PU per LED (1mA is about 3700 PU)
|
//so A=2,R=255,G=0,B=0 would use 510 PU per LED (1mA is about 3700 PU)
|
||||||
|
|
||||||
if (ablMilliampsMax > 149 && ablMilliampsMax < 65000) //lower numbers and 65000 turn off calculation
|
if (ablMilliampsMax > 149 && milliampsPerLed > 0) //0 mA per LED and too low numbers turn off calculation
|
||||||
{
|
{
|
||||||
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * PU_PER_MA; //100mA for ESP power
|
uint32_t puPerMilliamp = 195075 / milliampsPerLed;
|
||||||
if (powerBudget > PU_PER_MA * _length) //each LED uses about 1mA in standby, exclude that from power budget
|
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
|
||||||
|
if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget
|
||||||
{
|
{
|
||||||
powerBudget -= PU_PER_MA * _length;
|
powerBudget -= puPerMilliamp * _length;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
powerBudget = 0;
|
powerBudget = 0;
|
||||||
@ -232,10 +249,10 @@ void WS2812FX::show(void) {
|
|||||||
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
||||||
uint8_t newBri = scale8(_brightness, scaleB);
|
uint8_t newBri = scale8(_brightness, scaleB);
|
||||||
bus->SetBrightness(newBri);
|
bus->SetBrightness(newBri);
|
||||||
currentMilliamps = (powerSum0 * newBri) / PU_PER_MA;
|
currentMilliamps = (powerSum0 * newBri) / puPerMilliamp;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
currentMilliamps = powerSum / PU_PER_MA;
|
currentMilliamps = powerSum / puPerMilliamp;
|
||||||
bus->SetBrightness(_brightness);
|
bus->SetBrightness(_brightness);
|
||||||
}
|
}
|
||||||
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
||||||
@ -246,6 +263,7 @@ void WS2812FX::show(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bus->Show();
|
bus->Show();
|
||||||
|
_lastShow = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::trigger() {
|
void WS2812FX::trigger() {
|
||||||
@ -284,48 +302,28 @@ uint8_t WS2812FX::getPaletteCount()
|
|||||||
|
|
||||||
//TODO transitions
|
//TODO transitions
|
||||||
|
|
||||||
void WS2812FX::setMode(uint8_t m) {
|
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
|
||||||
{
|
|
||||||
if (_segments[i].isSelected()) setMode(i, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::setSpeed(uint8_t s) {
|
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
|
||||||
{
|
|
||||||
if (_segments[i].isSelected()) _segments[i].speed = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::setIntensity(uint8_t in) {
|
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
|
||||||
{
|
|
||||||
if (_segments[i].isSelected()) _segments[i].intensity = in;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WS2812FX::setPalette(uint8_t p) {
|
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
|
||||||
{
|
|
||||||
if (_segments[i].isSelected()) _segments[i].palette = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
||||||
uint8_t retSeg = getReturnedSegmentId();
|
uint8_t mainSeg = getMainSegmentId();
|
||||||
Segment& seg = _segments[retSeg];
|
Segment& seg = _segments[getMainSegmentId()];
|
||||||
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
||||||
|
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
if (applyToAllSelected) {
|
||||||
{
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
if (_segments[i].isSelected())
|
|
||||||
{
|
{
|
||||||
_segments[i].speed = s;
|
if (_segments[i].isSelected())
|
||||||
_segments[i].intensity = in;
|
{
|
||||||
_segments[i].palette = p;
|
_segments[i].speed = s;
|
||||||
setMode(i, m);
|
_segments[i].intensity = in;
|
||||||
|
_segments[i].palette = p;
|
||||||
|
setMode(i, m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
seg.speed = s;
|
||||||
|
seg.intensity = in;
|
||||||
|
seg.palette = p;
|
||||||
|
setMode(mainSegment, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
|
if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
|
||||||
@ -338,9 +336,13 @@ void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w
|
|||||||
|
|
||||||
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
|
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
|
||||||
if (slot >= NUM_COLORS) return;
|
if (slot >= NUM_COLORS) return;
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
if (applyToAllSelected) {
|
||||||
{
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
|
{
|
||||||
|
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_segments[getMainSegmentId()].colors[slot] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,11 +354,11 @@ void WS2812FX::setBrightness(uint8_t b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::getMode(void) {
|
uint8_t WS2812FX::getMode(void) {
|
||||||
return _segments[getReturnedSegmentId()].mode;
|
return _segments[getMainSegmentId()].mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::getSpeed(void) {
|
uint8_t WS2812FX::getSpeed(void) {
|
||||||
return _segments[getReturnedSegmentId()].speed;
|
return _segments[getMainSegmentId()].speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::getBrightness(void) {
|
uint8_t WS2812FX::getBrightness(void) {
|
||||||
@ -367,7 +369,7 @@ uint8_t WS2812FX::getMaxSegments(void) {
|
|||||||
return MAX_NUM_SEGMENTS;
|
return MAX_NUM_SEGMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::getFirstSelectedSegment(void)
|
/*uint8_t WS2812FX::getFirstSelectedSegment(void)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||||
{
|
{
|
||||||
@ -378,24 +380,22 @@ uint8_t WS2812FX::getFirstSelectedSegment(void)
|
|||||||
if (_segments[i].isActive()) return i;
|
if (_segments[i].isActive()) return i;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
uint8_t WS2812FX::getReturnedSegmentId(void) {
|
uint8_t WS2812FX::getMainSegmentId(void) {
|
||||||
if (returnedSegment >= MAX_NUM_SEGMENTS || !_segments[returnedSegment].isActive())
|
if (mainSegment >= MAX_NUM_SEGMENTS) return 0;
|
||||||
{
|
return mainSegment;
|
||||||
return getFirstSelectedSegment();
|
|
||||||
}
|
|
||||||
return returnedSegment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WS2812FX::getColor(void) {
|
uint32_t WS2812FX::getColor(void) {
|
||||||
return _segments[getReturnedSegmentId()].colors[0];
|
return _segments[getMainSegmentId()].colors[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||||
{
|
{
|
||||||
|
i = i * (_disableNLeds+1);
|
||||||
if (reverseMode) i = _length- 1 -i;
|
if (reverseMode) i = _length- 1 -i;
|
||||||
if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment
|
if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment
|
||||||
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
||||||
if (_cronixieMode)
|
if (_cronixieMode)
|
||||||
{
|
{
|
||||||
@ -416,6 +416,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
|
|||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (i >= _lengthRaw) return 0;
|
||||||
RgbwColor lColor = bus->GetPixelColorRgbw(i);
|
RgbwColor lColor = bus->GetPixelColorRgbw(i);
|
||||||
byte r = lColor.R, g = lColor.G, b = lColor.B;
|
byte r = lColor.R, g = lColor.G, b = lColor.B;
|
||||||
switch (colorOrder)
|
switch (colorOrder)
|
||||||
@ -441,6 +442,14 @@ WS2812FX::Segment* WS2812FX::getSegments(void) {
|
|||||||
return _segments;
|
return _segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::getUsableCount(void) {
|
||||||
|
return _usableCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WS2812FX::getLastShow(void) {
|
||||||
|
return _lastShow;
|
||||||
|
}
|
||||||
|
|
||||||
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
|
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
|
||||||
if (n >= MAX_NUM_SEGMENTS) return;
|
if (n >= MAX_NUM_SEGMENTS) return;
|
||||||
Segment& seg = _segments[n];
|
Segment& seg = _segments[n];
|
||||||
@ -451,6 +460,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
|
|||||||
unlockRange(seg.start, seg.stop);
|
unlockRange(seg.start, seg.stop);
|
||||||
_modeUsesLock = true;
|
_modeUsesLock = true;
|
||||||
}
|
}
|
||||||
|
_segment_index = n; fill(0); //turn old segment range off
|
||||||
if (i2 <= i1) //disable segment
|
if (i2 <= i1) //disable segment
|
||||||
{
|
{
|
||||||
seg.stop = 0; return;
|
seg.stop = 0; return;
|
||||||
@ -471,6 +481,10 @@ void WS2812FX::resetSegments() {
|
|||||||
_segments[0].speed = DEFAULT_SPEED;
|
_segments[0].speed = DEFAULT_SPEED;
|
||||||
_segments[0].stop = _length;
|
_segments[0].stop = _length;
|
||||||
_segments[0].setOption(0, 1); //select
|
_segments[0].setOption(0, 1); //select
|
||||||
|
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
||||||
|
{
|
||||||
|
_segments[i].colors[0] = color_wheel(i*51);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
|
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
|
||||||
@ -532,7 +546,7 @@ void WS2812FX::unlockAll()
|
|||||||
|
|
||||||
void WS2812FX::setTransitionMode(bool t)
|
void WS2812FX::setTransitionMode(bool t)
|
||||||
{
|
{
|
||||||
_segment_index = 0;
|
_segment_index = getMainSegmentId();
|
||||||
SEGMENT.setOption(7,t);
|
SEGMENT.setOption(7,t);
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
|
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
|
||||||
@ -635,6 +649,12 @@ void WS2812FX::blur(uint8_t blur_amount)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t WS2812FX::triwave16(uint16_t in)
|
||||||
|
{
|
||||||
|
if (in < 0x8000) return in *2;
|
||||||
|
return 0xFFFF - (in - 0x8000)*2;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Put a value 0 to 255 in to get a color value.
|
* Put a value 0 to 255 in to get a color value.
|
||||||
* The colours are a transition r -> g -> b -> back to r
|
* The colours are a transition r -> g -> b -> back to r
|
||||||
@ -695,7 +715,8 @@ void WS2812FX::handle_palette(void)
|
|||||||
_segment_index_palette_last = _segment_index;
|
_segment_index_palette_last = _segment_index;
|
||||||
|
|
||||||
byte paletteIndex = SEGMENT.palette;
|
byte paletteIndex = SEGMENT.palette;
|
||||||
if ((SEGMENT.mode >= FX_MODE_METEOR) && SEGMENT.palette == 0) paletteIndex = 4;
|
if (SEGMENT.mode == FX_MODE_GLITTER && paletteIndex == 0) paletteIndex = 11;
|
||||||
|
if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4;
|
||||||
|
|
||||||
switch (paletteIndex)
|
switch (paletteIndex)
|
||||||
{
|
{
|
||||||
@ -709,6 +730,7 @@ void WS2812FX::handle_palette(void)
|
|||||||
case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow
|
case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow
|
||||||
case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
||||||
case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
||||||
|
//case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break;
|
||||||
|
|
||||||
default: targetPalette = PartyColors_p; break;//palette, bpm
|
default: targetPalette = PartyColors_p; break;//palette, bpm
|
||||||
}
|
}
|
||||||
@ -747,7 +769,8 @@ void WS2812FX::handle_palette(void)
|
|||||||
case 5: {//based on primary + secondary
|
case 5: {//based on primary + secondary
|
||||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||||
targetPalette = CRGBPalette16(sec,prim,CRGB::White); break;}
|
CRGB ter = col_to_crgb(SEGCOLOR(2));
|
||||||
|
targetPalette = CRGBPalette16(ter,sec,prim); break;}
|
||||||
case 6: //Party colors
|
case 6: //Party colors
|
||||||
targetPalette = PartyColors_p; break;
|
targetPalette = PartyColors_p; break;
|
||||||
case 7: //Cloud colors
|
case 7: //Cloud colors
|
||||||
@ -786,6 +809,22 @@ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8
|
|||||||
return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b;
|
return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b)
|
||||||
|
{
|
||||||
|
//if (a->start != b->start) return false;
|
||||||
|
//if (a->stop != b->stop) return false;
|
||||||
|
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
||||||
|
{
|
||||||
|
if (a->colors[i] != b->colors[i]) return false;
|
||||||
|
}
|
||||||
|
if (a->mode != b->mode) return false;
|
||||||
|
if (a->speed != b->speed) return false;
|
||||||
|
if (a->intensity != b->intensity) return false;
|
||||||
|
if (a->palette != b->palette) return false;
|
||||||
|
//if (a->getOption(1) != b->getOption(1)) return false; //reverse
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//gamma 2.4 lookup table used for color correction
|
//gamma 2.4 lookup table used for color correction
|
||||||
const byte gammaT[] = {
|
const byte gammaT[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
@ -813,10 +852,10 @@ uint8_t WS2812FX::gamma8(uint8_t b)
|
|||||||
uint32_t WS2812FX::gamma32(uint32_t color)
|
uint32_t WS2812FX::gamma32(uint32_t color)
|
||||||
{
|
{
|
||||||
if (!gammaCorrectCol) return color;
|
if (!gammaCorrectCol) return color;
|
||||||
uint8_t w = (color >> 24) & 0xFF;
|
uint8_t w = (color >> 24);
|
||||||
uint8_t r = (color >> 16) & 0xFF;
|
uint8_t r = (color >> 16);
|
||||||
uint8_t g = (color >> 8) & 0xFF;
|
uint8_t g = (color >> 8);
|
||||||
uint8_t b = color & 0xFF;
|
uint8_t b = color;
|
||||||
w = gammaT[w];
|
w = gammaT[w];
|
||||||
r = gammaT[r];
|
r = gammaT[r];
|
||||||
g = gammaT[g];
|
g = gammaT[g];
|
||||||
|
@ -3,20 +3,21 @@
|
|||||||
#define NpbWrapper_h
|
#define NpbWrapper_h
|
||||||
|
|
||||||
//PIN CONFIGURATION
|
//PIN CONFIGURATION
|
||||||
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
||||||
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
||||||
#ifdef WLED_USE_H801
|
//#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 BTNPIN -1 //button pin. Needs to have pullup (gpio0 recommended)
|
//#define WLED_USE_H801 //H801 5 channel controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well
|
||||||
#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
|
//#define WLED_USE_5CH
|
||||||
#else
|
|
||||||
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
#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 IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0
|
||||||
#endif
|
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
|
||||||
#define RLYPIN -1 //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 AUXPIN -1 //debug auxiliary output pin (-1 to disable)
|
|
||||||
|
|
||||||
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
||||||
|
|
||||||
|
//END CONFIGURATION
|
||||||
|
|
||||||
#ifdef USE_APA102
|
#ifdef USE_APA102
|
||||||
#define CLKPIN 0
|
#define CLKPIN 0
|
||||||
#define DATAPIN 2
|
#define DATAPIN 2
|
||||||
@ -32,7 +33,11 @@
|
|||||||
#define GPIN 13 //G pin for analog LED strip
|
#define GPIN 13 //G pin for analog LED strip
|
||||||
#define BPIN 12 //B 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 WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04)
|
||||||
#define W2PIN 04 //W2 pin for analog LED strip
|
#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
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
|
//PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller
|
||||||
#define RPIN 5 //R pin for analog LED strip
|
#define RPIN 5 //R pin for analog LED strip
|
||||||
@ -40,6 +45,8 @@
|
|||||||
#define BPIN 15 //B 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)
|
#define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04)
|
||||||
#endif
|
#endif
|
||||||
|
#undef RLYPIN
|
||||||
|
#define RLYPIN -1 //disable as pin 12 is used by analog LEDs
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//automatically uses the right driver method for each platform
|
//automatically uses the right driver method for each platform
|
||||||
@ -168,66 +175,51 @@ public:
|
|||||||
byte b;
|
byte b;
|
||||||
switch (_type)
|
switch (_type)
|
||||||
{
|
{
|
||||||
case NeoPixelType_Grb: {
|
case NeoPixelType_Grb: _pGrb->Show(); break;
|
||||||
_pGrb->Show();
|
case NeoPixelType_Grbw: _pGrbw->Show(); break;
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
RgbColor color = _pGrb->GetPixelColor(0);
|
|
||||||
b = _pGrb->GetBrightness();
|
|
||||||
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NeoPixelType_Grbw: {
|
|
||||||
_pGrbw->Show();
|
|
||||||
#ifdef WLED_USE_ANALOG_LEDS
|
|
||||||
RgbwColor colorW = _pGrbw->GetPixelColor(0);
|
|
||||||
b = _pGrbw->GetBrightness();
|
|
||||||
// check color values for Warm / COld white mix (for RGBW) // EsplanexaDevice.cpp
|
|
||||||
#ifdef WLED_USE_5CH_LEDS
|
|
||||||
if (colorW.R == 255 & colorW.G == 255 && colorW.B == 255 && colorW.W == 255) {
|
|
||||||
SetRgbwPwm(0, 0, 0, 0, colorW.W * b / 255);
|
|
||||||
} else if (colorW.R == 127 & colorW.G == 127 && colorW.B == 127 && colorW.W == 255) {
|
|
||||||
SetRgbwPwm(0, 0, 0, colorW.W * b / 512, colorW.W * b / 255);
|
|
||||||
} else if (colorW.R == 0 & colorW.G == 0 && colorW.B == 0 && colorW.W == 255) {
|
|
||||||
SetRgbwPwm(0, 0, 0, colorW.W * b / 255, 0);
|
|
||||||
} else if (colorW.R == 130 & colorW.G == 90 && colorW.B == 0 && colorW.W == 255) {
|
|
||||||
SetRgbwPwm(0, 0, 0, colorW.W * b / 255, colorW.W * b / 512);
|
|
||||||
} else if (colorW.R == 255 & colorW.G == 153 && colorW.B == 0 && colorW.W == 255) {
|
|
||||||
SetRgbwPwm(0, 0, 0, colorW.W * b / 255, 0);
|
|
||||||
} else { // not only white colors
|
|
||||||
SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CanShow() const
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->CanShow(); break;
|
|
||||||
case NeoPixelType_Grbw: _pGrbw->CanShow(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPixelColor(uint16_t indexPixel, RgbColor color)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
|
void SetPixelColor(uint16_t indexPixel, RgbwColor color)
|
||||||
{
|
{
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
|
case NeoPixelType_Grb: {
|
||||||
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
|
_pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B));
|
||||||
|
#ifdef WLED_USE_ANALOG_LEDS
|
||||||
|
if (indexPixel != 0) return; //set analog LEDs from first pixel
|
||||||
|
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
|
||||||
|
b = _pGrbw->GetBrightness();
|
||||||
|
// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp
|
||||||
|
#ifdef WLED_USE_5CH_LEDS
|
||||||
|
if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, 0, color.W * b / 255);
|
||||||
|
} else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 512, colorW.W * b / 255);
|
||||||
|
} else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
|
||||||
|
} else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512);
|
||||||
|
} else if (color.R == 255 & color.G == 153 && color.B == 0 && color.W == 255) {
|
||||||
|
SetRgbwPwm(0, 0, 0, color.W * b / 255, 0);
|
||||||
|
} else { // not only white colors
|
||||||
|
SetRgbwPwm(color.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, color.W * b / 255);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBrightness(byte b)
|
void SetBrightness(byte b)
|
||||||
@ -238,15 +230,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RgbColor GetPixelColor(uint16_t indexPixel) const
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
|
|
||||||
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Due to feature differences, some support RGBW but the method name
|
// NOTE: Due to feature differences, some support RGBW but the method name
|
||||||
// here needs to be unique, thus GetPixeColorRgbw
|
// here needs to be unique, thus GetPixeColorRgbw
|
||||||
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
|
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
|
||||||
@ -258,21 +241,6 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearTo(RgbColor color)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearTo(RgbwColor color)
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case NeoPixelType_Grb: break;
|
|
||||||
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelType _type;
|
NeoPixelType _type;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#define ESP_PLATFORM
|
#define ESP_PLATFORM
|
||||||
#define HAVE_CONFIG_H
|
#define HAVE_CONFIG_H
|
||||||
#define F_CPU 240000000L
|
#define F_CPU 240000000L
|
||||||
#define ARDUINO 10807
|
#define ARDUINO 10809
|
||||||
#define ARDUINO_ESP32_DEV
|
#define ARDUINO_ESP32_DEV
|
||||||
#define ARDUINO_ARCH_ESP32
|
#define ARDUINO_ARCH_ESP32
|
||||||
#define ESP32
|
#define ESP32
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
64
wled00/data/liveview.htm
Normal file
64
wled00/data/liveview.htm
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||||
|
<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();
|
||||||
|
|
||||||
|
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>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,657 +0,0 @@
|
|||||||
/*
|
|
||||||
* Binary arrays for the classic desktop UI index page.
|
|
||||||
* gzip is used for smaller size and improved speeds.
|
|
||||||
*
|
|
||||||
* Workflow for creating them from HTML source:
|
|
||||||
* 1. Minify HTML (https://htmlcompressor.com/compressor/) (optional)
|
|
||||||
* 2. Compress with gzip (https://online-converting.com/archives/convert-to-gzip/)
|
|
||||||
* 3. Convert gzip binary to c array (https://littlevgl.com/image-to-c-array) (select RAW as color format)
|
|
||||||
* alternative: https://sourceforge.net/projects/bin2header/
|
|
||||||
* 4. update length value
|
|
||||||
*/
|
|
||||||
|
|
||||||
const uint16_t PAGE_index_L = 10256;
|
|
||||||
|
|
||||||
const uint8_t PAGE_index[] PROGMEM = {
|
|
||||||
0x1f, 0x8b, 0x08, 0x08, 0x58, 0x17, 0x80, 0x5c, 0x00, 0x03, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65,
|
|
||||||
0x73, 0x73, 0x65, 0x64, 0x20, 0x28, 0x31, 0x34, 0x29, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0xcc,
|
|
||||||
0x5a, 0xe9, 0x72, 0xdb, 0x46, 0xb6, 0xfe, 0xaf, 0xa7, 0x80, 0xe9, 0x4a, 0x4c, 0x46, 0x04, 0x88,
|
|
||||||
0x9d, 0x00, 0x29, 0x28, 0x65, 0x2b, 0xde, 0xaa, 0x1c, 0x45, 0x65, 0x69, 0x62, 0xa5, 0x32, 0x29,
|
|
||||||
0x17, 0x88, 0x85, 0xc4, 0x18, 0x04, 0x68, 0x00, 0xa4, 0xa4, 0x30, 0x7a, 0xf7, 0xf9, 0x4e, 0x77,
|
|
||||||
0x93, 0x04, 0xa8, 0x8d, 0xf4, 0x64, 0xe6, 0x5e, 0x57, 0x19, 0x40, 0xf7, 0x39, 0xdd, 0x67, 0x5f,
|
|
||||||
0xba, 0xa9, 0xa3, 0x67, 0x3f, 0xfd, 0x72, 0x72, 0xf1, 0xdb, 0xd9, 0x6b, 0x69, 0x52, 0x4d, 0xd3,
|
|
||||||
0xe3, 0x23, 0xf1, 0x8c, 0xfc, 0xf0, 0xf8, 0x68, 0x1a, 0x55, 0xbe, 0x14, 0x4c, 0xfc, 0xa2, 0x8c,
|
|
||||||
0x2a, 0x6f, 0x5e, 0xc5, 0xb2, 0x23, 0xe6, 0x32, 0x7f, 0x1a, 0x79, 0xd5, 0x24, 0x9a, 0x46, 0x72,
|
|
||||||
0x90, 0xa7, 0x79, 0x21, 0x05, 0x79, 0x56, 0x45, 0x59, 0xe5, 0x3d, 0x8f, 0xe3, 0xf8, 0xf8, 0x28,
|
|
||||||
0x4d, 0xb2, 0x2f, 0x52, 0x11, 0xa5, 0xde, 0x8b, 0x72, 0x92, 0x17, 0x55, 0x30, 0xaf, 0xa4, 0x04,
|
|
||||||
0x18, 0x2f, 0xa4, 0xea, 0x66, 0x16, 0x79, 0xc9, 0xd4, 0x1f, 0x47, 0xbd, 0x6b, 0x99, 0xa6, 0xa4,
|
|
||||||
0x49, 0x11, 0xc5, 0xde, 0x8b, 0x5e, 0xec, 0x2f, 0x68, 0xa8, 0xe0, 0xf1, 0xa2, 0x77, 0x7c, 0x54,
|
|
||||||
0x25, 0x55, 0x1a, 0x1d, 0x7f, 0xfa, 0xf0, 0xfa, 0x27, 0x49, 0x55, 0x1c, 0xc5, 0x3c, 0xea, 0xf1,
|
|
||||||
0x19, 0xe9, 0xa8, 0x0c, 0x8a, 0x64, 0x56, 0x1d, 0x2f, 0xfc, 0x42, 0x0a, 0xbd, 0x30, 0x0f, 0xe6,
|
|
||||||
0x53, 0x90, 0x1d, 0xd2, 0xf0, 0xca, 0xbb, 0x4a, 0xb2, 0x30, 0xbf, 0x52, 0xc6, 0x51, 0x75, 0x92,
|
|
||||||
0x4f, 0x67, 0xf3, 0x2a, 0x0a, 0xcf, 0xab, 0x9b, 0x34, 0x6a, 0x87, 0xca, 0xd7, 0x79, 0x54, 0xdc,
|
|
||||||
0x9c, 0x47, 0x69, 0x14, 0x54, 0x79, 0xd1, 0x6e, 0x91, 0x8c, 0xad, 0x4e, 0x67, 0x58, 0x44, 0xe5,
|
|
||||||
0xcc, 0x6b, 0xb5, 0xd8, 0xf2, 0x2c, 0xf5, 0xbd, 0xd8, 0x4f, 0xcb, 0x88, 0x8f, 0x8a, 0xc6, 0xa8,
|
|
||||||
0xac, 0x8f, 0xca, 0x2a, 0xaf, 0x8d, 0xe6, 0x57, 0x8b, 0x3a, 0x6c, 0x14, 0x7b, 0x55, 0x31, 0xe7,
|
|
||||||
0x83, 0x38, 0x29, 0xca, 0x2a, 0xcd, 0xfd, 0x70, 0x33, 0x95, 0xfa, 0x65, 0x55, 0x5e, 0x7b, 0x2a,
|
|
||||||
0xdf, 0xf6, 0xbc, 0xf2, 0xab, 0x48, 0x0c, 0x82, 0x85, 0xf8, 0x48, 0xa7, 0xe2, 0x23, 0xbe, 0x4e,
|
|
||||||
0x56, 0x5f, 0xb3, 0xf5, 0xd7, 0x75, 0xe6, 0x69, 0x43, 0xff, 0x84, 0xb8, 0x1e, 0xb1, 0x67, 0xc8,
|
|
||||||
0x9e, 0xf1, 0x3c, 0x0b, 0xaa, 0x04, 0xfa, 0x1c, 0xbf, 0x0f, 0xdb, 0x65, 0xe7, 0x60, 0x59, 0x44,
|
|
||||||
0xd5, 0xbc, 0xc8, 0xa4, 0x90, 0xb4, 0xf1, 0x3a, 0x8d, 0x48, 0x4b, 0xaf, 0x6e, 0x18, 0x6c, 0x78,
|
|
||||||
0x7b, 0xb0, 0xc6, 0xfe, 0xc7, 0x49, 0x9e, 0xb6, 0x81, 0x8d, 0x0d, 0x99, 0xde, 0xce, 0x8a, 0x7c,
|
|
||||||
0x16, 0x15, 0xd5, 0xcd, 0xaf, 0x7e, 0x3a, 0x8f, 0xda, 0x2d, 0x59, 0xf6, 0x81, 0xd0, 0xea, 0x10,
|
|
||||||
0xa9, 0xfb, 0xe1, 0x23, 0x0e, 0x0f, 0x1f, 0x82, 0x87, 0x02, 0xbe, 0x6d, 0x01, 0xf2, 0xa2, 0xdf,
|
|
||||||
0xb7, 0xbd, 0xe8, 0x8f, 0x56, 0x47, 0x81, 0xa7, 0xbd, 0xac, 0xaa, 0x22, 0x19, 0xc1, 0x7c, 0xed,
|
|
||||||
0x96, 0x70, 0xab, 0x56, 0x77, 0x74, 0xd2, 0xe0, 0x1b, 0x8a, 0x2b, 0xaa, 0xf9, 0x8c, 0x58, 0xff,
|
|
||||||
0x46, 0xd3, 0x73, 0xc9, 0x87, 0x27, 0xbf, 0xb6, 0xd5, 0xce, 0x10, 0x44, 0xdf, 0x83, 0x50, 0xb1,
|
|
||||||
0xf0, 0xd3, 0xf6, 0xdb, 0xf7, 0xbf, 0x74, 0x2d, 0x55, 0xc5, 0x2c, 0xbe, 0xda, 0x0c, 0x76, 0x91,
|
|
||||||
0x4c, 0xa3, 0x7c, 0x5e, 0xb5, 0x57, 0xe4, 0xdb, 0x9d, 0x65, 0x9c, 0xa4, 0x69, 0x7c, 0x4d, 0x6b,
|
|
||||||
0x6f, 0xbb, 0xba, 0xaa, 0x3e, 0x81, 0xa6, 0x11, 0x9a, 0x45, 0x68, 0x35, 0x19, 0xd8, 0xf6, 0x07,
|
|
||||||
0xcb, 0x2c, 0x0f, 0xfc, 0x60, 0x12, 0x79, 0xad, 0xef, 0xd7, 0x5f, 0x87, 0x3f, 0xfb, 0xd5, 0x44,
|
|
||||||
0x29, 0x7c, 0x88, 0x34, 0x6d, 0x77, 0x7e, 0xd0, 0x54, 0xf6, 0x8f, 0xd9, 0xbf, 0x88, 0x20, 0x4f,
|
|
||||||
0x59, 0x79, 0x59, 0x74, 0x25, 0x5d, 0xfe, 0xfc, 0xe1, 0x5d, 0x55, 0xcd, 0x3e, 0xf2, 0xa9, 0x36,
|
|
||||||
0xb9, 0x33, 0xfb, 0x52, 0xf2, 0xac, 0x40, 0xf8, 0xde, 0x94, 0xe4, 0x5d, 0x88, 0xde, 0x6c, 0x1c,
|
|
||||||
0x79, 0x1b, 0x9e, 0x0e, 0x96, 0x49, 0xdc, 0xae, 0x26, 0x49, 0xa9, 0x30, 0x24, 0xee, 0x82, 0x9e,
|
|
||||||
0xd9, 0x59, 0x4f, 0xd3, 0xb2, 0x79, 0xe9, 0x79, 0x24, 0x56, 0x0d, 0xb7, 0x9c, 0xe5, 0x59, 0x19,
|
|
||||||
0x81, 0xe6, 0x33, 0x2f, 0x9b, 0xa7, 0x69, 0x67, 0x19, 0x2a, 0x27, 0xb1, 0x72, 0xfe, 0x52, 0x59,
|
|
||||||
0x90, 0xad, 0xbd, 0x6d, 0xac, 0x9a, 0xdf, 0x95, 0xaf, 0x6e, 0x2e, 0xfc, 0xf1, 0x29, 0x8c, 0xdd,
|
|
||||||
0x7e, 0xe1, 0x07, 0x2f, 0x3a, 0xbf, 0xab, 0x7f, 0x28, 0xc1, 0x24, 0x49, 0xc3, 0xd3, 0x3c, 0x8c,
|
|
||||||
0x4a, 0x1a, 0x65, 0xf8, 0x60, 0x2e, 0x33, 0xe4, 0x9b, 0x7e, 0xdc, 0x6f, 0xd3, 0x20, 0xdd, 0x65,
|
|
||||||
0xd3, 0xb7, 0xdf, 0xb0, 0xa9, 0xf6, 0xd4, 0xa6, 0xaf, 0xbe, 0x61, 0x53, 0xfd, 0xe1, 0x4d, 0xef,
|
|
||||||
0x51, 0xf7, 0x03, 0x3b, 0x5d, 0x2d, 0x1e, 0x95, 0xf9, 0xd8, 0x53, 0x57, 0x16, 0xfa, 0xb4, 0x1f,
|
|
||||||
0x8b, 0x4f, 0x6c, 0x3c, 0xa4, 0x7c, 0xc7, 0xd2, 0xd9, 0x6d, 0x84, 0xa4, 0xb7, 0xdc, 0xa4, 0x3f,
|
|
||||||
0xb8, 0x36, 0x12, 0xd6, 0x8e, 0x54, 0xe2, 0xeb, 0xc7, 0xa9, 0x50, 0xc6, 0xdb, 0x75, 0xab, 0xd9,
|
|
||||||
0x2e, 0xd6, 0xbf, 0xdc, 0x4f, 0x0b, 0xe5, 0x13, 0xfc, 0xb1, 0x4d, 0xdf, 0xef, 0xb9, 0x69, 0xf2,
|
|
||||||
0xc4, 0xa6, 0x54, 0x82, 0x76, 0xb5, 0x7f, 0x26, 0x7c, 0x3e, 0xc9, 0xb2, 0xa8, 0x78, 0x77, 0xf1,
|
|
||||||
0xf3, 0x87, 0xce, 0x33, 0x4f, 0xfd, 0x91, 0x0c, 0x33, 0xe0, 0xe6, 0x80, 0x2b, 0xad, 0xeb, 0x8f,
|
|
||||||
0x70, 0x85, 0xd3, 0x13, 0x90, 0x8e, 0x82, 0x2f, 0x51, 0xb8, 0x3b, 0x99, 0xf8, 0x09, 0x32, 0x5c,
|
|
||||||
0xbb, 0xa7, 0xfb, 0x29, 0x22, 0x0b, 0x77, 0x31, 0xd9, 0xc5, 0x9e, 0x9b, 0x56, 0x4f, 0x6d, 0xba,
|
|
||||||
0x6a, 0x17, 0xc4, 0x62, 0x64, 0x3a, 0x94, 0x08, 0xaa, 0x38, 0xab, 0xb2, 0xb5, 0xae, 0x78, 0xdd,
|
|
||||||
0x5d, 0xe3, 0xd9, 0x7f, 0x94, 0x66, 0x67, 0x57, 0xa2, 0xa3, 0xbd, 0x88, 0x8e, 0xfe, 0x1e, 0xa2,
|
|
||||||
0xc1, 0x5e, 0x44, 0x1f, 0x4f, 0xdc, 0x3b, 0x13, 0x0d, 0xf7, 0x22, 0xfa, 0xb8, 0x9f, 0xec, 0x4c,
|
|
||||||
0xb4, 0xdc, 0x8b, 0xe8, 0xfc, 0xef, 0x21, 0x5a, 0xed, 0x45, 0xf4, 0x71, 0xe7, 0xdd, 0xdd, 0xa6,
|
|
||||||
0x6f, 0xb2, 0xdd, 0x69, 0xc6, 0x4f, 0xd0, 0xdc, 0xf4, 0x48, 0x33, 0x3a, 0x02, 0xa0, 0x45, 0xda,
|
|
||||||
0x35, 0x6d, 0x4c, 0x9f, 0x30, 0x5c, 0x47, 0x54, 0x0f, 0x84, 0xf9, 0xc5, 0x25, 0x64, 0xa0, 0xee,
|
|
||||||
0x2c, 0x0a, 0xdf, 0x67, 0x61, 0x74, 0xed, 0xa1, 0x8a, 0x0c, 0x79, 0x72, 0xdd, 0x9a, 0x9f, 0x25,
|
|
||||||
0x54, 0x63, 0xd6, 0x3d, 0x35, 0xcf, 0x3f, 0xeb, 0x1e, 0x5a, 0x7c, 0xec, 0x9c, 0xd8, 0x8a, 0xfb,
|
|
||||||
0x12, 0x9b, 0x36, 0x58, 0x6d, 0x74, 0xb8, 0xfb, 0x4e, 0xe5, 0x7d, 0x3b, 0xe9, 0xd8, 0x29, 0x6c,
|
|
||||||
0xae, 0x38, 0x41, 0xf3, 0x5f, 0xb2, 0x35, 0x2d, 0x28, 0x24, 0x68, 0x35, 0x57, 0xed, 0x9a, 0xe6,
|
|
||||||
0xc2, 0x6d, 0x72, 0xc3, 0x7f, 0xfc, 0x0a, 0x23, 0xdd, 0xe2, 0xdf, 0x41, 0x23, 0xe7, 0xd3, 0x56,
|
|
||||||
0x87, 0x68, 0x2b, 0xdf, 0x5f, 0xb4, 0x0e, 0xd6, 0x9d, 0xe1, 0x2c, 0xca, 0xda, 0xad, 0xb7, 0xaf,
|
|
||||||
0x2f, 0x5a, 0xdd, 0x16, 0x5a, 0xe6, 0xd6, 0x21, 0x43, 0x12, 0x8d, 0x67, 0x97, 0xd2, 0xfa, 0xa6,
|
|
||||||
0x8b, 0x2c, 0xa3, 0x2c, 0x6c, 0xb3, 0x56, 0x6f, 0x7d, 0x4e, 0xaa, 0x77, 0xaf, 0x27, 0x6d, 0x76,
|
|
||||||
0xca, 0xe0, 0x34, 0x5e, 0xa2, 0x69, 0xad, 0x75, 0x83, 0xc3, 0xd5, 0xfc, 0x47, 0x31, 0xff, 0x71,
|
|
||||||
0x6b, 0xfe, 0xad, 0x98, 0x7f, 0xbb, 0x35, 0xff, 0x4a, 0xcc, 0x8b, 0xb6, 0x8a, 0x8a, 0x18, 0x1a,
|
|
||||||
0x8c, 0xb5, 0x28, 0x9f, 0x04, 0x58, 0xb4, 0x34, 0x5c, 0x72, 0xde, 0xa6, 0xd7, 0x59, 0xbb, 0xac,
|
|
||||||
0xb3, 0xf6, 0xe6, 0x92, 0x2f, 0xda, 0xf6, 0xb3, 0x35, 0xcd, 0x73, 0x81, 0xb0, 0x6a, 0x11, 0xd6,
|
|
||||||
0x80, 0xf7, 0x02, 0xb0, 0x2a, 0xf3, 0x0f, 0x91, 0x8b, 0xaa, 0x8f, 0x6f, 0x5f, 0xad, 0x8e, 0x22,
|
|
||||||
0x45, 0x77, 0xdc, 0x1d, 0x75, 0x93, 0x6e, 0xdc, 0x9d, 0x75, 0xbf, 0x76, 0xf9, 0xc9, 0x74, 0xe2,
|
|
||||||
0xf1, 0x82, 0xf6, 0x8e, 0xef, 0xd3, 0x2d, 0xc5, 0xf8, 0x5c, 0x8c, 0x17, 0x9e, 0x6e, 0x59, 0xc3,
|
|
||||||
0xc4, 0x63, 0x6d, 0x7f, 0x9c, 0xe6, 0x38, 0xa7, 0x4c, 0x7e, 0xb0, 0x3b, 0xc3, 0xd8, 0xc3, 0x4b,
|
|
||||||
0x4e, 0x86, 0x33, 0x6f, 0xf1, 0x43, 0x5b, 0x93, 0x71, 0x74, 0xfb, 0xca, 0xbf, 0xe2, 0x1f, 0xf0,
|
|
||||||
0x5d, 0xf1, 0x6f, 0x1a, 0x76, 0x68, 0x5c, 0x5e, 0x25, 0x55, 0x30, 0x69, 0x27, 0xdf, 0xd9, 0x9d,
|
|
||||||
0x65, 0xe0, 0x97, 0x91, 0xa4, 0x0e, 0x0a, 0x6f, 0xd1, 0x1d, 0x7b, 0x55, 0x77, 0xe4, 0xcd, 0x86,
|
|
||||||
0x23, 0xb4, 0xfb, 0x5f, 0x86, 0x0c, 0xa0, 0x01, 0xf0, 0x15, 0x80, 0xc5, 0x36, 0x40, 0x07, 0x60,
|
|
||||||
0x26, 0x00, 0x55, 0x1d, 0x60, 0x08, 0xc0, 0x57, 0x00, 0x16, 0x75, 0x80, 0x09, 0x40, 0x05, 0xc0,
|
|
||||||
0x6c, 0x1b, 0x60, 0x09, 0xe2, 0x04, 0xf8, 0x0a, 0x75, 0x35, 0x1b, 0xfb, 0x62, 0xab, 0x27, 0x1f,
|
|
||||||
0x6f, 0xb5, 0xd3, 0xa3, 0x21, 0xf9, 0x57, 0x43, 0xcb, 0x67, 0x0d, 0xa3, 0x9e, 0x71, 0xd3, 0xbc,
|
|
||||||
0x39, 0xdb, 0x32, 0xea, 0x1d, 0xeb, 0x20, 0x79, 0x2d, 0xf8, 0x99, 0x07, 0xc7, 0xf6, 0xce, 0x49,
|
|
||||||
0x9a, 0x97, 0xd1, 0x79, 0x54, 0x55, 0x49, 0x36, 0x2e, 0x81, 0x48, 0xa7, 0xe5, 0x56, 0x99, 0xbe,
|
|
||||||
0xa4, 0x83, 0x27, 0x4b, 0xa7, 0x61, 0x52, 0xce, 0x52, 0xff, 0xc6, 0x6b, 0x65, 0x79, 0x16, 0xb5,
|
|
||||||
0x04, 0xbc, 0x18, 0x8f, 0x1e, 0x47, 0x98, 0x94, 0x8f, 0xc3, 0xd3, 0x4f, 0x8f, 0xc2, 0xab, 0xf4,
|
|
||||||
0xf2, 0x09, 0xf8, 0xd9, 0x13, 0xf0, 0xd3, 0x87, 0xe0, 0x90, 0x7b, 0x71, 0xa4, 0xb3, 0x73, 0x1c,
|
|
||||||
0x05, 0xd2, 0xc3, 0xec, 0x8c, 0xd2, 0x3c, 0xf8, 0xd2, 0x7a, 0x44, 0x21, 0x02, 0xe1, 0xf6, 0x40,
|
|
||||||
0xf8, 0xd9, 0x62, 0xed, 0x65, 0x8f, 0x28, 0x49, 0x2c, 0x62, 0x57, 0x1a, 0x0d, 0x07, 0x7c, 0x58,
|
|
||||||
0x6f, 0x9b, 0x25, 0x5a, 0xd3, 0x35, 0x1f, 0x56, 0x85, 0x58, 0xd2, 0xf0, 0xd7, 0x87, 0x15, 0x7b,
|
|
||||||
0x17, 0xdb, 0x1c, 0x3c, 0xac, 0xc6, 0xb5, 0xd8, 0xc1, 0x02, 0x0e, 0x3e, 0x0d, 0x47, 0x02, 0x81,
|
|
||||||
0x4e, 0xf6, 0x5e, 0x3b, 0x9d, 0x1e, 0xab, 0x9d, 0x1f, 0xfd, 0x93, 0x41, 0x78, 0x52, 0x77, 0x3a,
|
|
||||||
0xe8, 0x42, 0x9f, 0x44, 0xd7, 0xed, 0x22, 0x0a, 0xbb, 0xe3, 0x22, 0x8a, 0xb2, 0xee, 0x88, 0xaa,
|
|
||||||
0x1e, 0x4f, 0x10, 0xe3, 0x91, 0x47, 0xa3, 0xbf, 0xda, 0x0c, 0x72, 0x74, 0xe4, 0x74, 0xfe, 0x22,
|
|
||||||
0xc4, 0xa3, 0x23, 0xcd, 0xa6, 0x4c, 0x4b, 0xd7, 0x36, 0x2f, 0x9e, 0xbf, 0x38, 0x6c, 0xab, 0xd7,
|
|
||||||
0xe2, 0xe0, 0x7f, 0x88, 0x25, 0x1d, 0xa5, 0xca, 0xcf, 0xab, 0x02, 0x6e, 0xdb, 0x06, 0x9a, 0x52,
|
|
||||||
0xa6, 0x49, 0x10, 0xb5, 0xb5, 0x4e, 0x8d, 0x66, 0x0a, 0x58, 0xe1, 0x87, 0x6d, 0x96, 0x80, 0x3a,
|
|
||||||
0xe2, 0xfe, 0xa7, 0x85, 0xd9, 0xc8, 0x2f, 0x64, 0x82, 0x24, 0x28, 0x24, 0xed, 0xd6, 0xe1, 0xe8,
|
|
||||||
0xe4, 0x10, 0xc9, 0xff, 0x70, 0xcd, 0x22, 0x43, 0x3f, 0x6c, 0x75, 0x1a, 0xd9, 0x9d, 0x32, 0xdd,
|
|
||||||
0x01, 0x0e, 0x0d, 0xa3, 0x3c, 0xbc, 0x11, 0x02, 0x8f, 0xfc, 0xe0, 0xcb, 0xb8, 0xc8, 0xe7, 0x59,
|
|
||||||
0xe8, 0xad, 0x48, 0xd5, 0x22, 0xba, 0x5b, 0x8b, 0xe6, 0x6e, 0x2d, 0x92, 0xd9, 0xc5, 0xc8, 0xbb,
|
|
||||||
0xf3, 0xdd, 0x50, 0xe3, 0xeb, 0xa6, 0x76, 0x59, 0x4e, 0xd8, 0xce, 0xdb, 0x1b, 0x85, 0x67, 0x69,
|
|
||||||
0x13, 0x1d, 0xc7, 0xa7, 0x35, 0xa8, 0x7a, 0x10, 0x24, 0xdc, 0x97, 0x57, 0x79, 0x08, 0x59, 0x77,
|
|
||||||
0xe2, 0x19, 0x12, 0xb0, 0xb6, 0xf6, 0x01, 0xb6, 0x14, 0x2b, 0xd6, 0x20, 0xfd, 0x0e, 0xe8, 0xae,
|
|
||||||
0x4f, 0xdf, 0xb3, 0x85, 0xbf, 0xeb, 0x16, 0xfa, 0xb7, 0x70, 0xe1, 0x9f, 0xdc, 0xe3, 0xf8, 0xfb,
|
|
||||||
0x71, 0xe1, 0x93, 0xf3, 0x56, 0xe3, 0xa6, 0xca, 0x6a, 0xe5, 0x7c, 0xa3, 0xf2, 0x78, 0x76, 0xb9,
|
|
||||||
0x15, 0x20, 0xed, 0x07, 0x4c, 0x24, 0x02, 0x67, 0x20, 0xf2, 0x50, 0x9c, 0xc7, 0xdb, 0xbb, 0xdf,
|
|
||||||
0x59, 0x65, 0x9b, 0x6b, 0x32, 0xd3, 0xe2, 0x29, 0xec, 0x23, 0xed, 0x9e, 0xb8, 0xbb, 0x18, 0x5f,
|
|
||||||
0x88, 0x0b, 0xae, 0x26, 0xf7, 0x9b, 0xc2, 0x71, 0xe1, 0xa9, 0xad, 0x61, 0xfd, 0xde, 0x4a, 0xe5,
|
|
||||||
0x9d, 0x68, 0x1d, 0x43, 0xa7, 0x50, 0xb8, 0xbf, 0xd6, 0x9f, 0x5f, 0xbd, 0xb9, 0x64, 0xd7, 0xab,
|
|
||||||
0xec, 0xfa, 0xd6, 0xbb, 0x87, 0xaf, 0xc3, 0x92, 0x72, 0x6e, 0xe6, 0x79, 0xb2, 0xf6, 0xd7, 0x5f,
|
|
||||||
0x78, 0xc5, 0xd7, 0x59, 0x87, 0xc7, 0xe2, 0xf0, 0xbe, 0x66, 0x37, 0x63, 0xd8, 0x47, 0x6a, 0xe7,
|
|
||||||
0x3e, 0xa0, 0xca, 0x80, 0xc7, 0xb4, 0xc5, 0x7d, 0x60, 0xd6, 0x2e, 0x4c, 0x93, 0xac, 0x6d, 0x5b,
|
|
||||||
0x5d, 0xe0, 0xc8, 0x1a, 0x18, 0xbe, 0x6c, 0xf2, 0x7b, 0x31, 0x7e, 0x77, 0xfe, 0x4a, 0xa8, 0x24,
|
|
||||||
0xa0, 0x42, 0x70, 0xb0, 0xc4, 0xbb, 0xf3, 0x23, 0xbb, 0xf6, 0x1c, 0xe0, 0xa9, 0xad, 0x3b, 0xf1,
|
|
||||||
0x5f, 0x91, 0xcc, 0xa8, 0x8d, 0xac, 0x0b, 0x4b, 0x91, 0x72, 0x76, 0xde, 0xbe, 0x66, 0xb9, 0x80,
|
|
||||||
0xca, 0xed, 0x1b, 0xa1, 0xb5, 0xf5, 0x79, 0xa0, 0x31, 0xdd, 0x39, 0xbc, 0x26, 0x8e, 0x1b, 0x73,
|
|
||||||
0xb0, 0x53, 0x73, 0xa9, 0x76, 0x07, 0xe5, 0x58, 0xb7, 0xb6, 0x70, 0x74, 0xab, 0x2e, 0xc4, 0xd9,
|
|
||||||
0xcb, 0x6a, 0x53, 0xfb, 0xf9, 0xd2, 0x57, 0xeb, 0x9b, 0x0c, 0x78, 0xda, 0xf7, 0x67, 0x2f, 0x3d,
|
|
||||||
0x0d, 0x9e, 0x46, 0x6f, 0x58, 0xb7, 0x8e, 0x77, 0xd2, 0xc4, 0x3b, 0x11, 0x78, 0x27, 0xdb, 0x78,
|
|
||||||
0x6f, 0x9a, 0x78, 0x97, 0x02, 0xef, 0x92, 0xf0, 0xea, 0x9c, 0x9c, 0xc3, 0x21, 0x4a, 0xea, 0x27,
|
|
||||||
0x18, 0x4f, 0x24, 0x09, 0x1b, 0xad, 0x7c, 0xe7, 0xec, 0xdc, 0x5b, 0xed, 0xdb, 0x10, 0x68, 0xdb,
|
|
||||||
0xc7, 0xce, 0x3e, 0x3c, 0x84, 0x77, 0x70, 0xc7, 0xe5, 0x7e, 0x41, 0xcb, 0xbe, 0xe9, 0x58, 0x0e,
|
|
||||||
0x96, 0xf4, 0xeb, 0x03, 0xbb, 0x7f, 0x2b, 0x9b, 0x39, 0x0e, 0x41, 0x1c, 0x84, 0xaf, 0xee, 0xef,
|
|
||||||
0x02, 0xca, 0x2a, 0xde, 0x06, 0x24, 0x19, 0x95, 0x06, 0xd6, 0x20, 0x94, 0xa3, 0xb8, 0xc3, 0x30,
|
|
||||||
0x8a, 0xc0, 0x6b, 0xf5, 0x4a, 0x41, 0x0b, 0xab, 0x46, 0xf1, 0xe6, 0x6a, 0x6f, 0xdd, 0x4f, 0x35,
|
|
||||||
0x3b, 0x28, 0xce, 0x0f, 0xc7, 0xda, 0x62, 0x28, 0xbc, 0x97, 0xa1, 0x15, 0xdd, 0x7b, 0x58, 0xe2,
|
|
||||||
0xbc, 0x36, 0xbc, 0xf7, 0xbc, 0xbd, 0xe9, 0xdd, 0x0e, 0x96, 0xdb, 0xdd, 0x1b, 0xf7, 0xdc, 0xa6,
|
|
||||||
0x82, 0x1a, 0x1e, 0x7c, 0x31, 0x3e, 0x65, 0x3f, 0x6f, 0xd0, 0xc5, 0xda, 0x33, 0x3c, 0x58, 0x3c,
|
|
||||||
0xa1, 0x14, 0xac, 0x0d, 0x71, 0x0a, 0x43, 0x1c, 0x36, 0xae, 0xb0, 0xd6, 0xdd, 0xff, 0xe9, 0xc5,
|
|
||||||
0x1a, 0x74, 0xd1, 0x00, 0xb5, 0xb7, 0xee, 0xd2, 0xc8, 0x63, 0x4e, 0xdf, 0x70, 0x8f, 0xc1, 0x9b,
|
|
||||||
0x3c, 0x86, 0xf1, 0x55, 0xa3, 0xa1, 0x3e, 0x9c, 0x51, 0xc0, 0x22, 0xe3, 0x90, 0x1f, 0x3a, 0x0f,
|
|
||||||
0x19, 0x87, 0xec, 0xfb, 0xd8, 0xe8, 0xac, 0xcf, 0xb6, 0x0f, 0xd4, 0xac, 0xf5, 0x09, 0xe6, 0xd4,
|
|
||||||
0x53, 0xbf, 0xff, 0x78, 0x4a, 0x64, 0x9a, 0x5d, 0xfe, 0x16, 0x5c, 0x6b, 0x6d, 0x35, 0xfb, 0x1b,
|
|
||||||
0xb8, 0x76, 0x77, 0xbd, 0x71, 0x07, 0xae, 0x3d, 0x2c, 0x06, 0xaf, 0xf2, 0xa2, 0xc3, 0x41, 0x4f,
|
|
||||||
0x81, 0xa6, 0x62, 0xd4, 0x2d, 0x3c, 0xbf, 0x18, 0xb3, 0x3b, 0x0b, 0x3a, 0xfe, 0xf7, 0x70, 0xc8,
|
|
||||||
0xc1, 0x81, 0x60, 0x33, 0xa5, 0xf1, 0xa9, 0x51, 0x6d, 0x4a, 0xe7, 0x53, 0x93, 0x6e, 0x89, 0x43,
|
|
||||||
0x11, 0xcf, 0x6f, 0xfe, 0xaa, 0x47, 0xe9, 0x86, 0x49, 0x1c, 0x7b, 0x0b, 0x79, 0x9d, 0xf6, 0x6a,
|
|
||||||
0xd3, 0xc1, 0xe6, 0x07, 0x8e, 0x60, 0xd5, 0xfb, 0xb4, 0x17, 0x72, 0xd0, 0xe9, 0xd9, 0x3d, 0x82,
|
|
||||||
0x1f, 0x6a, 0x3d, 0x7d, 0x78, 0xcb, 0x32, 0x0f, 0x6d, 0x42, 0x97, 0xe3, 0x13, 0xaf, 0x5c, 0x25,
|
|
||||||
0xff, 0x25, 0x0e, 0x64, 0x98, 0xee, 0x2d, 0x86, 0x45, 0xc1, 0xbe, 0x82, 0x76, 0x81, 0xb3, 0xc1,
|
|
||||||
0x58, 0x7c, 0x8f, 0x3b, 0xc3, 0xd1, 0x48, 0x7c, 0x8f, 0x58, 0xd0, 0x17, 0x9e, 0xe7, 0x2d, 0x68,
|
|
||||||
0x8b, 0xd1, 0x48, 0x1e, 0x8f, 0xf9, 0x26, 0x12, 0xe6, 0xc7, 0xab, 0xf9, 0xb6, 0xd6, 0x33, 0x3a,
|
|
||||||
0x87, 0x45, 0x21, 0x8f, 0x46, 0x1b, 0xe8, 0x68, 0x0d, 0xd5, 0x09, 0x3a, 0x1e, 0xcb, 0x45, 0x31,
|
|
||||||
0x64, 0x87, 0xf6, 0xc9, 0x11, 0x31, 0x74, 0x88, 0xdc, 0xb8, 0x46, 0x9e, 0x1c, 0x6b, 0x98, 0x92,
|
|
||||||
0x69, 0x8a, 0xa1, 0x94, 0x28, 0x63, 0x8d, 0x53, 0xa4, 0x37, 0x19, 0x36, 0x4e, 0x91, 0x5e, 0xd9,
|
|
||||||
0x08, 0xd3, 0xf3, 0x76, 0x42, 0xc1, 0x29, 0xce, 0x84, 0xf7, 0xf8, 0xcc, 0xa7, 0x87, 0x9c, 0xe5,
|
|
||||||
0xd5, 0x43, 0x5e, 0xf2, 0x71, 0xcb, 0x81, 0x6a, 0x0e, 0x72, 0xb6, 0xd5, 0x4f, 0xaf, 0x01, 0x27,
|
|
||||||
0xad, 0xad, 0x43, 0xe1, 0x66, 0x33, 0x16, 0x14, 0x77, 0x1c, 0x69, 0x7e, 0xf2, 0x5b, 0x7b, 0x9d,
|
|
||||||
0x5f, 0x1b, 0xa9, 0xfc, 0xb7, 0x7a, 0xc0, 0x9d, 0xfc, 0xc6, 0x03, 0x0e, 0xef, 0x75, 0x2a, 0x47,
|
|
||||||
0x5e, 0xd5, 0xf8, 0xb1, 0xf0, 0x4c, 0xdb, 0x0a, 0xe6, 0x33, 0x5d, 0x00, 0xf4, 0x6d, 0xc0, 0x85,
|
|
||||||
0x00, 0xac, 0x62, 0xfc, 0x0e, 0x43, 0x1f, 0xeb, 0xe7, 0xce, 0x33, 0x16, 0xcb, 0x77, 0x70, 0xc4,
|
|
||||||
0xcf, 0x7c, 0xf1, 0x0c, 0xa8, 0x91, 0xd7, 0x3a, 0xca, 0x67, 0x34, 0x7d, 0xfc, 0xba, 0x28, 0xf2,
|
|
||||||
0x42, 0xa2, 0xcb, 0x18, 0xe4, 0x26, 0x34, 0xe8, 0x65, 0xf5, 0xec, 0xa8, 0x27, 0x60, 0xad, 0x61,
|
|
||||||
0x94, 0x7a, 0xf1, 0xec, 0x47, 0x76, 0x88, 0x1d, 0xb0, 0xf2, 0x3e, 0x8c, 0x23, 0x32, 0x16, 0x26,
|
|
||||||
0x5f, 0xf4, 0xfe, 0x55, 0xe6, 0x59, 0x6f, 0xe6, 0xa7, 0x2f, 0x06, 0xe2, 0x3b, 0x8a, 0xe3, 0x17,
|
|
||||||
0x38, 0x04, 0x4c, 0x22, 0xf8, 0x7d, 0x54, 0x7a, 0xc7, 0x94, 0x15, 0x9f, 0xe1, 0x4b, 0xc9, 0xbf,
|
|
||||||
0x74, 0x96, 0x51, 0x5a, 0xbb, 0x47, 0xa2, 0x74, 0x2d, 0x7e, 0xfd, 0x25, 0x38, 0xad, 0x26, 0x6e,
|
|
||||||
0xc5, 0x62, 0x1a, 0x62, 0x35, 0xc5, 0xe9, 0x35, 0xfb, 0xe1, 0x38, 0x2f, 0xda, 0x89, 0x94, 0x64,
|
|
||||||
0x12, 0x01, 0x3a, 0xcb, 0xeb, 0xc3, 0x35, 0xfb, 0x12, 0x77, 0xab, 0x7f, 0xb6, 0x5a, 0x87, 0xc9,
|
|
||||||
0x61, 0xeb, 0x9f, 0xad, 0xe3, 0xd6, 0x21, 0xe1, 0xfc, 0x9e, 0xfc, 0x71, 0xd8, 0x92, 0xda, 0x6c,
|
|
||||||
0xb2, 0x53, 0x13, 0xe7, 0xf6, 0xa0, 0xc1, 0xc5, 0x35, 0xe4, 0xbb, 0x73, 0x81, 0xf7, 0x63, 0x3c,
|
|
||||||
0x4b, 0x06, 0x74, 0xbf, 0x47, 0xcc, 0x43, 0x5b, 0xf4, 0x6b, 0x36, 0xed, 0xa9, 0xa4, 0x51, 0x36,
|
|
||||||
0xae, 0x26, 0xe2, 0x26, 0xab, 0xa3, 0x04, 0x3e, 0x53, 0xc4, 0xe6, 0x77, 0xd4, 0x6d, 0x01, 0x3b,
|
|
||||||
0xb7, 0x47, 0x3d, 0xf1, 0x97, 0x00, 0xd2, 0x11, 0x2b, 0x23, 0xc7, 0x83, 0x22, 0xcf, 0xab, 0x25,
|
|
||||||
0xbf, 0xbf, 0x1f, 0x3c, 0x0f, 0xdd, 0x91, 0xa1, 0xa9, 0x43, 0x7e, 0xb3, 0x3e, 0x78, 0xae, 0x8e,
|
|
||||||
0x8c, 0xc0, 0x0a, 0x87, 0xfc, 0xce, 0x7b, 0xf0, 0x5c, 0x0b, 0xf5, 0xbe, 0xa1, 0x0d, 0xf9, 0x6d,
|
|
||||||
0xf4, 0xe0, 0xb9, 0xa1, 0x3b, 0x41, 0x40, 0xc3, 0x92, 0x23, 0xab, 0xb4, 0xb0, 0x6a, 0x82, 0x82,
|
|
||||||
0x37, 0xd9, 0xe0, 0xd7, 0xa8, 0x08, 0xfd, 0xcc, 0xbf, 0x55, 0x82, 0xaa, 0x48, 0x3f, 0x8f, 0xf2,
|
|
||||||
0xeb, 0xe5, 0x14, 0xa9, 0x2b, 0xc9, 0x06, 0xfe, 0xbc, 0xca, 0x87, 0x57, 0x49, 0x58, 0x4d, 0x06,
|
|
||||||
0x8e, 0xba, 0xb8, 0x1a, 0x6e, 0xce, 0x4a, 0xfc, 0x87, 0xed, 0x01, 0xd4, 0xdd, 0xe6, 0xc4, 0x3b,
|
|
||||||
0xc3, 0x59, 0x5e, 0x26, 0x24, 0xd6, 0xc0, 0x1f, 0x95, 0x79, 0x3a, 0xaf, 0xa2, 0x61, 0x95, 0xcf,
|
|
||||||
0x06, 0x96, 0xf5, 0xdd, 0x30, 0x8d, 0xe2, 0x6a, 0x60, 0xa9, 0xdf, 0x0d, 0xab, 0xc2, 0xcf, 0x4a,
|
|
||||||
0x58, 0x66, 0x3a, 0x60, 0x5f, 0x29, 0xb2, 0x7e, 0x5b, 0x06, 0xa0, 0x4b, 0x0f, 0x9c, 0x93, 0x92,
|
|
||||||
0xb4, 0x8a, 0x8a, 0x41, 0x58, 0xe4, 0x33, 0xb9, 0x9c, 0xf8, 0x61, 0x7e, 0x05, 0xe8, 0xec, 0x5a,
|
|
||||||
0x62, 0x0f, 0xfa, 0xcf, 0xc9, 0x91, 0x34, 0x9d, 0xce, 0xad, 0x52, 0x86, 0xe5, 0x92, 0x33, 0x87,
|
|
||||||
0x03, 0xe5, 0x77, 0xc3, 0x49, 0x94, 0x8c, 0x27, 0xd5, 0x40, 0xd3, 0x17, 0x93, 0x21, 0xe7, 0x5f,
|
|
||||||
0x26, 0x06, 0x30, 0x04, 0x6a, 0x2a, 0x44, 0x92, 0x19, 0x2f, 0x4c, 0x2e, 0x31, 0x51, 0xb0, 0x55,
|
|
||||||
0xf5, 0x19, 0xb1, 0x4a, 0x08, 0xde, 0xef, 0x2f, 0xae, 0x6e, 0x9f, 0x97, 0xe9, 0xcb, 0x65, 0x0d,
|
|
||||||
0xac, 0x02, 0xbc, 0x51, 0xc6, 0x60, 0xfb, 0x34, 0x5a, 0xe5, 0x12, 0xdb, 0x16, 0xc7, 0x63, 0x20,
|
|
||||||
0x75, 0x6f, 0xa2, 0x34, 0xcd, 0xaf, 0x3a, 0xb4, 0xcb, 0xc7, 0xe5, 0xee, 0xcb, 0x70, 0x78, 0x66,
|
|
||||||
0x6b, 0xde, 0xee, 0xb1, 0x86, 0x9d, 0xbd, 0xd9, 0xaa, 0x57, 0x7b, 0xac, 0x62, 0xa7, 0x78, 0x5a,
|
|
||||||
0xf4, 0x69, 0x8f, 0x45, 0x57, 0x93, 0xa4, 0xe2, 0xab, 0xde, 0xed, 0xb4, 0x8a, 0x2e, 0x0d, 0xf2,
|
|
||||||
0x82, 0x7e, 0xb5, 0x17, 0x0a, 0x11, 0x57, 0x08, 0xc1, 0x8d, 0xcf, 0xef, 0x11, 0xba, 0x8b, 0x24,
|
|
||||||
0x4f, 0xa3, 0x6a, 0x2d, 0xf7, 0xf9, 0x4e, 0xdb, 0x62, 0x93, 0x9b, 0x9a, 0xd8, 0xa7, 0x7b, 0x48,
|
|
||||||
0x80, 0x5c, 0xf2, 0x75, 0x9e, 0x27, 0x25, 0x97, 0xe2, 0x62, 0x8f, 0x95, 0x2b, 0x8b, 0x2a, 0x55,
|
|
||||||
0x9e, 0xa7, 0xe5, 0x7f, 0xec, 0x5b, 0x97, 0xdf, 0xa4, 0xf6, 0xf7, 0xfb, 0xfa, 0x12, 0xdd, 0x7a,
|
|
||||||
0x2c, 0xe3, 0x3c, 0xab, 0xe4, 0xd8, 0x9f, 0x26, 0xe9, 0xcd, 0x2a, 0x7c, 0xdf, 0x64, 0x9d, 0xee,
|
|
||||||
0xbb, 0x28, 0x5d, 0x44, 0x55, 0x12, 0xf8, 0xdd, 0x12, 0x91, 0x29, 0x97, 0x51, 0x91, 0xc4, 0xc3,
|
|
||||||
0x2a, 0xba, 0xae, 0x64, 0x3f, 0x4d, 0xc6, 0xd9, 0x20, 0x88, 0xe8, 0x0f, 0x49, 0x1e, 0x73, 0x7a,
|
|
||||||
0xbe, 0x19, 0xe5, 0xa5, 0x0e, 0x27, 0xda, 0x59, 0x87, 0x24, 0x85, 0xa7, 0x48, 0x29, 0x6a, 0x3d,
|
|
||||||
0x89, 0x14, 0xd1, 0x2c, 0xf2, 0xab, 0x41, 0x96, 0x8b, 0xaf, 0x3a, 0xcc, 0xaf, 0x2a, 0x3f, 0x98,
|
|
||||||
0x50, 0xfb, 0x34, 0x88, 0x93, 0xeb, 0x28, 0x1c, 0xd6, 0x33, 0x0e, 0x25, 0xb1, 0xce, 0x2d, 0xfd,
|
|
||||||
0xcd, 0xcb, 0xb2, 0x46, 0xe3, 0x36, 0x89, 0x0b, 0x7f, 0x1a, 0x2d, 0x45, 0xe7, 0x3d, 0xa0, 0xc6,
|
|
||||||
0x7b, 0x38, 0xca, 0x8b, 0x10, 0x49, 0x45, 0xdd, 0x2f, 0xbb, 0x0c, 0x1f, 0xc8, 0x80, 0x82, 0x9a,
|
|
||||||
0x4d, 0x09, 0xe0, 0x3f, 0x4e, 0x78, 0xb7, 0xe5, 0x62, 0xcc, 0xfe, 0x94, 0x46, 0x48, 0x15, 0xb2,
|
|
||||||
0x3c, 0x2a, 0x52, 0x9a, 0xbe, 0xa1, 0xa6, 0xa9, 0x0b, 0xf4, 0x85, 0x7b, 0xa6, 0xc7, 0x24, 0x9b,
|
|
||||||
0xcd, 0xab, 0xe5, 0x7e, 0x42, 0x3f, 0xe0, 0x1b, 0x1b, 0x8f, 0xb8, 0x1d, 0xcd, 0xab, 0x2a, 0xcf,
|
|
||||||
0xea, 0x8e, 0x57, 0x33, 0x7b, 0xc3, 0x44, 0x5c, 0x18, 0xa1, 0x7d, 0xc5, 0x0a, 0x26, 0x12, 0x94,
|
|
||||||
0x94, 0x84, 0x52, 0x1d, 0x5f, 0x04, 0xc5, 0x28, 0xc7, 0xa6, 0xd3, 0x81, 0x06, 0x9d, 0xfe, 0xdd,
|
|
||||||
0xfc, 0xf2, 0x4a, 0xbd, 0x0b, 0xbf, 0xd5, 0x0e, 0xfc, 0xfe, 0xdd, 0xdc, 0x31, 0x1b, 0xfd, 0xce,
|
|
||||||
0xfe, 0x78, 0x30, 0x9b, 0x4f, 0x47, 0x51, 0xf1, 0xc7, 0xdf, 0xc5, 0x29, 0x77, 0x22, 0x23, 0x9a,
|
|
||||||
0xd6, 0x69, 0xb0, 0xe4, 0xfb, 0xc7, 0x52, 0xbe, 0x8a, 0x46, 0x5f, 0x12, 0x04, 0xf6, 0x0c, 0x31,
|
|
||||||
0x87, 0xb9, 0x20, 0xe2, 0x91, 0x22, 0x5c, 0x5e, 0x36, 0x21, 0x88, 0x7a, 0x77, 0xdd, 0x20, 0xce,
|
|
||||||
0x83, 0x79, 0xb9, 0xcc, 0xe7, 0x15, 0x45, 0xfe, 0xe0, 0x3e, 0x8c, 0xc1, 0x6a, 0xeb, 0x12, 0xfc,
|
|
||||||
0x44, 0x85, 0x5c, 0xcc, 0xb3, 0xcc, 0x1f, 0xa5, 0x91, 0x0c, 0xef, 0x0f, 0xbe, 0x3c, 0x54, 0xac,
|
|
||||||
0x83, 0x79, 0x51, 0x42, 0xb8, 0x59, 0x9e, 0x6c, 0xa7, 0x98, 0x9a, 0x44, 0x3b, 0x50, 0xab, 0x26,
|
|
||||||
0xd0, 0xe1, 0x9e, 0x1e, 0xbf, 0x89, 0xb0, 0x55, 0x4e, 0xd6, 0xb6, 0x6a, 0x3b, 0x47, 0xf7, 0xb9,
|
|
||||||
0x15, 0x9a, 0x9c, 0x3e, 0xae, 0x48, 0x96, 0xeb, 0xe1, 0xd3, 0xf7, 0x72, 0x3e, 0xcd, 0xff, 0x94,
|
|
||||||
0xd9, 0xe0, 0xbf, 0xa5, 0x9a, 0x1a, 0x81, 0xff, 0xb5, 0x5a, 0x76, 0x11, 0xbf, 0xfc, 0x56, 0xb9,
|
|
||||||
0x59, 0x1e, 0x9d, 0xf9, 0x05, 0xfd, 0x75, 0x2c, 0x0f, 0x01, 0xd1, 0x8a, 0xd6, 0x01, 0x77, 0x66,
|
|
||||||
0x1e, 0x62, 0x82, 0x92, 0xaf, 0x8c, 0x4a, 0x1e, 0x15, 0xf5, 0xc0, 0x7b, 0xfe, 0xa4, 0x72, 0xc5,
|
|
||||||
0xca, 0x39, 0x0c, 0xbf, 0xf7, 0x4a, 0x6e, 0x8f, 0xbd, 0xb5, 0x5a, 0x33, 0x09, 0x1d, 0x12, 0xd8,
|
|
||||||
0xd9, 0x40, 0x9c, 0x11, 0xa4, 0x24, 0xf4, 0x26, 0x79, 0x0a, 0x5d, 0xfc, 0x0b, 0x99, 0x85, 0xcd,
|
|
||||||
0x30, 0xaa, 0x54, 0xbe, 0x7b, 0x41, 0x59, 0x1e, 0xaf, 0xf0, 0x8f, 0x7a, 0xfc, 0xef, 0x9f, 0xa9,
|
|
||||||
0x11, 0x90, 0xf2, 0x8c, 0xfd, 0xb9, 0xc1, 0xfa, 0x4f, 0x4e, 0xa5, 0x80, 0x7e, 0xc7, 0xf7, 0x3e,
|
|
||||||
0x7f, 0x46, 0xed, 0x4c, 0xb2, 0xcf, 0xb4, 0xf8, 0xf3, 0xc7, 0xd7, 0x2f, 0x7f, 0xfa, 0xed, 0xf3,
|
|
||||||
0x67, 0x22, 0x34, 0xf3, 0x33, 0x81, 0x41, 0x3f, 0xf2, 0x1f, 0x7f, 0xe0, 0xa7, 0x3f, 0x45, 0x51,
|
|
||||||
0xb0, 0x39, 0x60, 0x84, 0xb2, 0x18, 0x4b, 0x8c, 0x8e, 0x77, 0xb7, 0x32, 0x72, 0x71, 0xd5, 0x95,
|
|
||||||
0x14, 0xea, 0x30, 0x5f, 0x44, 0x45, 0x0c, 0xcd, 0x0f, 0x26, 0x49, 0x18, 0x46, 0x38, 0x94, 0x45,
|
|
||||||
0x45, 0x89, 0x15, 0x9e, 0xa6, 0x68, 0xd2, 0xf5, 0x34, 0xcd, 0x4a, 0x6f, 0x52, 0x55, 0xb3, 0x41,
|
|
||||||
0xaf, 0x77, 0x75, 0x75, 0xa5, 0x5c, 0x19, 0x4a, 0x5e, 0x8c, 0x7b, 0x3a, 0x4e, 0x30, 0x3d, 0x50,
|
|
||||||
0x01, 0xad, 0x30, 0x8a, 0xcb, 0x63, 0xa9, 0xd7, 0xfb, 0xc0, 0x9a, 0x10, 0xfa, 0x13, 0xeb, 0x52,
|
|
||||||
0x09, 0xf2, 0x69, 0x2f, 0x46, 0x23, 0x08, 0x4e, 0x6e, 0xa6, 0xa3, 0x3c, 0x25, 0xb5, 0xa4, 0x59,
|
|
||||||
0x21, 0xcf, 0xc8, 0xbe, 0x32, 0xbf, 0x32, 0x90, 0x16, 0x49, 0x74, 0xf5, 0x2a, 0xc7, 0x11, 0x51,
|
|
||||||
0x95, 0x54, 0x49, 0x53, 0x75, 0x93, 0x3d, 0x5a, 0xc7, 0x47, 0xf4, 0xfb, 0x81, 0x14, 0x7a, 0xad,
|
|
||||||
0x9f, 0x4d, 0xc7, 0x56, 0x4c, 0xc9, 0xd6, 0x4c, 0xc5, 0x0c, 0x64, 0x3c, 0x35, 0xc3, 0x91, 0x54,
|
|
||||||
0x59, 0xb7, 0x14, 0x5b, 0xd6, 0x34, 0xc5, 0xb4, 0x35, 0xfe, 0x4d, 0x8f, 0x85, 0x6c, 0xda, 0xaa,
|
|
||||||
0xe2, 0x04, 0xea, 0x0a, 0x8f, 0x21, 0xe8, 0x0c, 0x26, 0xad, 0xb1, 0x4a, 0x36, 0xe4, 0x20, 0x69,
|
|
||||||
0x0d, 0x5a, 0x88, 0xa5, 0x12, 0x5b, 0xea, 0xca, 0x35, 0xf8, 0x66, 0xfd, 0x9f, 0x60, 0xac, 0x47,
|
|
||||||
0x9c, 0xdd, 0xe1, 0xcf, 0xed, 0xeb, 0x58, 0x2d, 0x83, 0x79, 0xc5, 0xea, 0x83, 0x3f, 0xcd, 0x75,
|
|
||||||
0x65, 0xc3, 0x55, 0x5c, 0xd3, 0x94, 0xf5, 0xbe, 0xa6, 0x58, 0x06, 0x36, 0xd4, 0x15, 0xb3, 0x2f,
|
|
||||||
0x03, 0xcf, 0xd2, 0x9d, 0xd5, 0x4b, 0x4c, 0x6a, 0xb6, 0xa3, 0xb8, 0xf6, 0x6a, 0xc4, 0x17, 0x60,
|
|
||||||
0x13, 0xc7, 0x54, 0x0c, 0xd7, 0x92, 0x74, 0x5b, 0x71, 0x2c, 0x70, 0x64, 0x43, 0x05, 0x7d, 0x47,
|
|
||||||
0xea, 0xf7, 0x15, 0xbb, 0x8f, 0x6d, 0x0d, 0x60, 0xb9, 0xa6, 0x64, 0xba, 0x8a, 0x66, 0xc9, 0x80,
|
|
||||||
0xb9, 0x9a, 0x05, 0xa9, 0xb0, 0x51, 0x9f, 0xb8, 0x37, 0xb0, 0x14, 0xca, 0x74, 0x6d, 0xc5, 0xd6,
|
|
||||||
0x4d, 0x59, 0x33, 0x6c, 0xc5, 0x52, 0x35, 0x09, 0xd3, 0x96, 0x25, 0x9b, 0x8a, 0x6a, 0x98, 0x92,
|
|
||||||
0xde, 0x57, 0x1c, 0xd5, 0x92, 0x0c, 0xc5, 0x76, 0x0c, 0x09, 0x9b, 0x39, 0xa4, 0xb0, 0xbe, 0xa2,
|
|
||||||
0x1b, 0x66, 0x29, 0xf3, 0x49, 0x8e, 0x21, 0xf3, 0x49, 0x81, 0x02, 0x19, 0x49, 0x2e, 0xcb, 0x92,
|
|
||||||
0x4c, 0x4d, 0xb1, 0x2d, 0xe2, 0xa3, 0xaf, 0xf4, 0x55, 0x1d, 0x4b, 0xa1, 0x81, 0xcd, 0xd0, 0xd0,
|
|
||||||
0x5c, 0x45, 0xd5, 0x75, 0xb2, 0xaa, 0x03, 0xa2, 0x2a, 0x34, 0x0e, 0x4e, 0x75, 0xf0, 0x64, 0x18,
|
|
||||||
0x40, 0xac, 0x3f, 0x4b, 0xf6, 0x94, 0x1b, 0x70, 0x99, 0x3d, 0x99, 0x25, 0x6d, 0x45, 0x73, 0xfa,
|
|
||||||
0xb2, 0x8b, 0x6d, 0x2d, 0xa8, 0xa6, 0xaf, 0x18, 0x7d, 0x41, 0x45, 0x93, 0x39, 0x11, 0x12, 0x0f,
|
|
||||||
0x62, 0xe9, 0x5c, 0x2e, 0x59, 0xd7, 0x14, 0xdd, 0x86, 0x4e, 0x1d, 0x45, 0x77, 0x1c, 0xc1, 0xbc,
|
|
||||||
0x2c, 0xe4, 0x23, 0x0c, 0x5d, 0xa0, 0x4b, 0x84, 0xe1, 0x0a, 0x74, 0x2e, 0x5d, 0x9f, 0xa3, 0x5b,
|
|
||||||
0x4c, 0xc7, 0x26, 0x6c, 0x6e, 0x28, 0x1a, 0xe3, 0xbc, 0xaf, 0x98, 0x50, 0x3c, 0x14, 0xee, 0xe8,
|
|
||||||
0x5c, 0xa7, 0x06, 0xde, 0xd0, 0xa9, 0xe9, 0xba, 0x92, 0x05, 0xbf, 0xd1, 0x6c, 0xc9, 0xee, 0x2b,
|
|
||||||
0x9a, 0xc6, 0x57, 0xf6, 0x2d, 0xb6, 0x44, 0x87, 0x1a, 0xc4, 0x90, 0x1b, 0xcb, 0xe1, 0x3e, 0x0e,
|
|
||||||
0x0f, 0xe1, 0xbe, 0x41, 0x7b, 0x41, 0x00, 0x55, 0x17, 0x96, 0x97, 0x84, 0xab, 0x70, 0xe7, 0x90,
|
|
||||||
0xd8, 0xcb, 0x16, 0xce, 0x21, 0x35, 0x9d, 0x83, 0x8f, 0x6a, 0xfe, 0xd8, 0xe3, 0x41, 0x76, 0xbc,
|
|
||||||
0x1d, 0x6d, 0x74, 0x1d, 0xb4, 0x43, 0x94, 0xb9, 0xae, 0x03, 0x2f, 0x76, 0xa0, 0x4f, 0x7d, 0x22,
|
|
||||||
0xf7, 0x6d, 0xe7, 0xa9, 0x50, 0x2b, 0xef, 0x0d, 0xad, 0x09, 0xad, 0xe4, 0x01, 0x04, 0x42, 0x9b,
|
|
||||||
0x38, 0xd3, 0x36, 0x71, 0x56, 0xca, 0xb5, 0x99, 0xc7, 0x23, 0x8b, 0xf3, 0x64, 0xd9, 0xc6, 0xff,
|
|
||||||
0x3b, 0x9e, 0x0c, 0xb5, 0xff, 0x18, 0x4f, 0xfa, 0xb7, 0xf2, 0xa4, 0x7f, 0x13, 0x4f, 0x7d, 0x9b,
|
|
||||||
0x22, 0xc9, 0x72, 0x28, 0x41, 0x9a, 0xba, 0x62, 0x98, 0x94, 0x80, 0x68, 0x52, 0x36, 0x90, 0x31,
|
|
||||||
0xc8, 0x9f, 0xe8, 0x9b, 0x1e, 0x65, 0x6d, 0x42, 0x5a, 0xcf, 0x4a, 0x7c, 0x03, 0x06, 0x92, 0x36,
|
|
||||||
0xa0, 0xda, 0xc4, 0x06, 0xed, 0x4f, 0x4e, 0x4d, 0xb7, 0x6c, 0x2e, 0x39, 0x3c, 0x9e, 0x4b, 0xce,
|
|
||||||
0x04, 0x70, 0xac, 0x0d, 0xa7, 0x25, 0x9f, 0xd8, 0x48, 0xb4, 0x79, 0xc8, 0x35, 0x90, 0x5c, 0x9b,
|
|
||||||
0xd8, 0xa8, 0x4d, 0x7e, 0x54, 0x56, 0x51, 0x0c, 0xee, 0x91, 0x55, 0xdb, 0xc8, 0x8a, 0x79, 0x81,
|
|
||||||
0x70, 0xaf, 0xd0, 0xe5, 0xbd, 0x42, 0x23, 0xff, 0xb3, 0x45, 0xee, 0xa3, 0xd2, 0x5b, 0x9a, 0xfe,
|
|
||||||
0x7f, 0x28, 0xbd, 0xd3, 0x57, 0x9f, 0x96, 0xfe, 0x49, 0x4b, 0x6b, 0x3b, 0x5a, 0x7a, 0xed, 0xe3,
|
|
||||||
0xff, 0x23, 0x59, 0x1f, 0xca, 0x63, 0xd3, 0x9c, 0xae, 0x8a, 0x9f, 0xcc, 0x63, 0x96, 0x6e, 0x82,
|
|
||||||
0x69, 0x9a, 0x25, 0xae, 0x55, 0x45, 0xeb, 0xbb, 0xc4, 0x36, 0x92, 0xa6, 0x6b, 0x3b, 0xb2, 0x65,
|
|
||||||
0x22, 0x83, 0xc3, 0xb6, 0x18, 0xaa, 0x2e, 0x6a, 0x8b, 0x65, 0xa0, 0x8a, 0x94, 0xe2, 0x8d, 0xa2,
|
|
||||||
0xa2, 0xa2, 0x88, 0xae, 0x46, 0x02, 0x89, 0x4a, 0x90, 0x66, 0x29, 0x3a, 0x92, 0x35, 0xca, 0x83,
|
|
||||||
0x8e, 0xed, 0x55, 0x8d, 0x68, 0xdb, 0x8a, 0xeb, 0x22, 0x8d, 0x43, 0x33, 0x16, 0x0a, 0x85, 0x61,
|
|
||||||
0xb0, 0x72, 0x6e, 0xa2, 0xea, 0xda, 0xa8, 0x01, 0x06, 0xab, 0xd0, 0x0e, 0x9a, 0x27, 0x8b, 0x6a,
|
|
||||||
0xb2, 0xab, 0x18, 0xba, 0xc5, 0x72, 0xbc, 0xa1, 0x1b, 0x12, 0x0a, 0x9a, 0x6a, 0xa9, 0x54, 0x91,
|
|
||||||
0x4c, 0xf4, 0x0d, 0xa8, 0x25, 0xb6, 0x29, 0x5b, 0x96, 0x62, 0x92, 0x34, 0xa8, 0x25, 0x26, 0xc8,
|
|
||||||
0x80, 0xb4, 0x0e, 0xad, 0xb9, 0x28, 0x2c, 0x28, 0x50, 0x8a, 0x8b, 0xca, 0xad, 0xab, 0x0c, 0x43,
|
|
||||||
0x55, 0x0c, 0xc3, 0xa6, 0x8e, 0xc0, 0x45, 0x9b, 0x81, 0xfa, 0xa5, 0xeb, 0x25, 0x2a, 0x21, 0x55,
|
|
||||||
0x6e, 0x14, 0x09, 0x94, 0x2a, 0x43, 0x51, 0x6d, 0x94, 0x76, 0x07, 0x5c, 0x22, 0x42, 0xc1, 0x96,
|
|
||||||
0x8a, 0x49, 0x34, 0x07, 0x06, 0x5a, 0x1a, 0xd3, 0x41, 0xed, 0x74, 0x25, 0x0d, 0x1a, 0x47, 0x85,
|
|
||||||
0x5e, 0x0f, 0x5d, 0x83, 0x1b, 0x17, 0x45, 0x0a, 0x45, 0xa9, 0x8f, 0x09, 0x88, 0x0b, 0x36, 0x0d,
|
|
||||||
0xbc, 0x1a, 0x4f, 0x54, 0x38, 0x53, 0x33, 0x49, 0xf3, 0xd8, 0xbf, 0xdf, 0x87, 0x2d, 0x2d, 0xec,
|
|
||||||
0xa0, 0xad, 0x76, 0xe0, 0x1b, 0x3a, 0xe0, 0x5a, 0x53, 0xfb, 0xa8, 0xc5, 0x50, 0x01, 0x71, 0xad,
|
|
||||||
0x19, 0xe8, 0x26, 0x4c, 0xdb, 0x15, 0x4c, 0x71, 0x0e, 0xc9, 0x65, 0x34, 0xea, 0x19, 0x00, 0x36,
|
|
||||||
0x99, 0x1c, 0xa6, 0x10, 0x2a, 0xa0, 0x5d, 0x1d, 0xe4, 0x3d, 0xb2, 0x42, 0xdf, 0xa0, 0x42, 0xe9,
|
|
||||||
0x98, 0x50, 0xa2, 0x0a, 0x19, 0x1c, 0xa1, 0x19, 0x5b, 0x28, 0xca, 0x22, 0x25, 0x6a, 0xb6, 0x2d,
|
|
||||||
0x99, 0xf0, 0x21, 0xf4, 0x40, 0x50, 0x81, 0x85, 0xf8, 0x80, 0x78, 0x30, 0xcd, 0x4a, 0xdd, 0x2b,
|
|
||||||
0xf5, 0xbb, 0x2a, 0xea, 0x26, 0x74, 0x01, 0x19, 0x5d, 0x87, 0xfa, 0x33, 0xc5, 0xa0, 0xd2, 0xbe,
|
|
||||||
0x65, 0x48, 0x31, 0xfe, 0xf3, 0x67, 0xa8, 0x19, 0x1d, 0x54, 0x9f, 0xf0, 0x1d, 0x97, 0x92, 0x1d,
|
|
||||||
0xaa, 0x71, 0xdf, 0xd4, 0xc8, 0xb6, 0xae, 0x83, 0x7c, 0x0e, 0x2a, 0x1a, 0xc0, 0x3a, 0x7c, 0x4c,
|
|
||||||
0x45, 0x73, 0xb6, 0x1a, 0x9b, 0x3a, 0xed, 0x4b, 0x4a, 0xd2, 0x6d, 0xf0, 0x06, 0x0b, 0xeb, 0x54,
|
|
||||||
0xa9, 0x2d, 0xf0, 0x48, 0x5e, 0xd1, 0x78, 0x6a, 0x8e, 0xcb, 0x1a, 0x2b, 0x15, 0xc9, 0x1b, 0x9a,
|
|
||||||
0xd4, 0x4c, 0xd1, 0x06, 0x58, 0xab, 0x5d, 0x56, 0xbb, 0xca, 0x16, 0xa6, 0x89, 0x59, 0x97, 0x9a,
|
|
||||||
0x08, 0x34, 0x99, 0xa4, 0x77, 0xb4, 0x67, 0x2e, 0x03, 0x6a, 0x68, 0x5c, 0x2d, 0x90, 0x5c, 0x0d,
|
|
||||||
0xf1, 0x76, 0xa9, 0xf1, 0x42, 0x64, 0xe9, 0xd0, 0x35, 0x56, 0xab, 0xd4, 0x28, 0x22, 0xca, 0xc1,
|
|
||||||
0xba, 0x01, 0xab, 0x21, 0x73, 0x50, 0x49, 0x72, 0xd1, 0xf1, 0xd8, 0x2e, 0x7b, 0xf5, 0xc5, 0x24,
|
|
||||||
0x35, 0x4f, 0xe4, 0xe0, 0xf6, 0x7a, 0xcc, 0x17, 0x51, 0x32, 0x05, 0x8b, 0x9a, 0xa1, 0xc1, 0xba,
|
|
||||||
0x00, 0xaa, 0x30, 0x25, 0xba, 0x99, 0x26, 0x03, 0x3b, 0x04, 0x71, 0x90, 0x8f, 0x77, 0x88, 0x61,
|
|
||||||
0x03, 0xa6, 0x22, 0xb7, 0x52, 0x41, 0xa6, 0x6f, 0x59, 0x01, 0x22, 0x40, 0x53, 0x29, 0x8c, 0x4d,
|
|
||||||
0x84, 0xa1, 0x23, 0xab, 0xe8, 0xd7, 0x74, 0xd9, 0x26, 0x5f, 0x93, 0xa9, 0xf5, 0x92, 0x61, 0x7d,
|
|
||||||
0xb7, 0xcf, 0x32, 0x8b, 0xa3, 0x1a, 0x64, 0x67, 0x8d, 0xf2, 0x37, 0xec, 0x62, 0x52, 0xab, 0x07,
|
|
||||||
0x87, 0x41, 0x50, 0x23, 0xf2, 0x75, 0x8d, 0x50, 0x5c, 0x1d, 0x49, 0x11, 0x51, 0x81, 0x86, 0xdc,
|
|
||||||
0x26, 0xdf, 0xd4, 0x75, 0x02, 0xb8, 0xd4, 0x1d, 0x53, 0x1e, 0x34, 0x4c, 0x72, 0x47, 0x38, 0x33,
|
|
||||||
0xf4, 0xe0, 0xea, 0xf0, 0x3b, 0x32, 0x9e, 0xcb, 0xda, 0x47, 0xf8, 0x99, 0x18, 0xc1, 0xd1, 0x5d,
|
|
||||||
0x97, 0x34, 0x6c, 0xd9, 0x4c, 0x49, 0xc4, 0x00, 0x29, 0x16, 0xad, 0x9d, 0xd9, 0x7c, 0xc2, 0xbf,
|
|
||||||
0x75, 0xca, 0x9b, 0xd8, 0x59, 0x25, 0x3f, 0x85, 0x55, 0xd7, 0xcb, 0xc5, 0x66, 0x78, 0x69, 0x86,
|
|
||||||
0x21, 0x51, 0x9f, 0x4e, 0xdd, 0x1d, 0x45, 0xaa, 0x04, 0x88, 0x2e, 0xd8, 0xd1, 0x05, 0x6f, 0x48,
|
|
||||||
0x3c, 0x1a, 0xa2, 0x8a, 0x7c, 0x4a, 0xa7, 0xdc, 0x6f, 0xaa, 0x8e, 0xec, 0x90, 0xd7, 0x58, 0x5c,
|
|
||||||
0x36, 0x4d, 0x88, 0x4a, 0xd1, 0x66, 0x18, 0x06, 0x6d, 0xeb, 0x3a, 0x2e, 0xa2, 0xcd, 0x85, 0xb3,
|
|
||||||
0xda, 0x54, 0xd2, 0x24, 0x8d, 0x68, 0x30, 0xcd, 0xe0, 0xc5, 0xda, 0x77, 0x1c, 0x52, 0xc8, 0xde,
|
|
||||||
0x06, 0x73, 0xf3, 0x3e, 0xf6, 0x47, 0xd0, 0xd1, 0xd1, 0x40, 0x8c, 0xd0, 0x73, 0x03, 0x56, 0xca,
|
|
||||||
0x2c, 0x72, 0x41, 0xce, 0x90, 0x19, 0xc0, 0x61, 0x00, 0x53, 0x0d, 0x88, 0x48, 0x9f, 0xc5, 0xba,
|
|
||||||
0xde, 0xa7, 0x90, 0x42, 0x8e, 0xd5, 0x49, 0x66, 0xdb, 0x70, 0x64, 0x8d, 0x0b, 0xc4, 0x88, 0xf5,
|
|
||||||
0x25, 0x61, 0x1b, 0x6e, 0x29, 0x49, 0xd8, 0x86, 0x5b, 0x4a, 0x6a, 0xb0, 0x8f, 0x00, 0xe3, 0xc6,
|
|
||||||
0x61, 0x96, 0x92, 0xb8, 0x75, 0x98, 0xa5, 0x24, 0x6e, 0x1d, 0xae, 0x0e, 0x89, 0x99, 0xc7, 0x60,
|
|
||||||
0xa6, 0x62, 0xad, 0x3b, 0x92, 0x1e, 0xd7, 0xa7, 0xc4, 0xb4, 0xbb, 0x1a, 0x70, 0x03, 0x89, 0xb6,
|
|
||||||
0x7b, 0x65, 0x28, 0xa9, 0x66, 0x22, 0x3a, 0xaa, 0x91, 0x91, 0x6c, 0x99, 0xdb, 0x86, 0x19, 0x8a,
|
|
||||||
0x82, 0x68, 0x63, 0x68, 0x99, 0xab, 0x8d, 0xd9, 0x09, 0x01, 0x02, 0xd3, 0xe8, 0xcc, 0x4e, 0x26,
|
|
||||||
0x05, 0x43, 0xcd, 0x6d, 0x98, 0x6d, 0xb8, 0xa1, 0x6c, 0x96, 0x85, 0x28, 0xa2, 0xb9, 0xa5, 0xa4,
|
|
||||||
0x86, 0x1b, 0x6a, 0xc4, 0x9d, 0x4b, 0x11, 0x09, 0x4b, 0xb1, 0xbc, 0x47, 0xd6, 0x21, 0x4b, 0x49,
|
|
||||||
0x2b, 0x75, 0xd9, 0xfc, 0x65, 0x92, 0x9a, 0x69, 0xe3, 0xbe, 0xca, 0x12, 0xe2, 0xda, 0x52, 0xc8,
|
|
||||||
0xb2, 0xcc, 0x04, 0x62, 0x54, 0xc2, 0x34, 0xdc, 0x48, 0x6c, 0x1e, 0xea, 0xe7, 0x16, 0x0c, 0x40,
|
|
||||||
0xce, 0x61, 0x56, 0xd2, 0x28, 0xd7, 0xda, 0xa6, 0xc5, 0xad, 0x64, 0x71, 0x42, 0x2e, 0xb7, 0x92,
|
|
||||||
0x2b, 0x09, 0xbb, 0x30, 0x2b, 0xe9, 0x12, 0xd9, 0xc5, 0x12, 0x46, 0x12, 0x9c, 0x1b, 0xd2, 0x8a,
|
|
||||||
0x73, 0x8d, 0x25, 0x17, 0x66, 0x24, 0x62, 0x13, 0xa5, 0x80, 0x19, 0x49, 0x75, 0xb8, 0x32, 0x24,
|
|
||||||
0xe1, 0xb4, 0x64, 0x18, 0x9d, 0x5b, 0xc9, 0x66, 0xda, 0x44, 0x46, 0x67, 0x76, 0xea, 0xaf, 0x46,
|
|
||||||
0xab, 0x20, 0x5a, 0xd9, 0xa8, 0x6e, 0x9b, 0xe6, 0x93, 0xd9, 0x87, 0xb2, 0x24, 0xb7, 0x0d, 0x33,
|
|
||||||
0x94, 0x58, 0x2e, 0x0c, 0x25, 0x31, 0xe3, 0x38, 0xdc, 0x52, 0x12, 0x37, 0x0e, 0xb3, 0x94, 0xe0,
|
|
||||||
0xc7, 0x14, 0xcc, 0x31, 0xdb, 0xd8, 0xc2, 0x52, 0x92, 0xc9, 0xb3, 0x2a, 0xb7, 0x14, 0x17, 0x70,
|
|
||||||
0x65, 0x28, 0x89, 0x9b, 0x86, 0x07, 0x11, 0xec, 0xe4, 0x42, 0xb3, 0xdc, 0x4e, 0xc2, 0xb1, 0x85,
|
|
||||||
0xa5, 0x64, 0x61, 0x1b, 0x6e, 0x29, 0x11, 0x1e, 0xc2, 0x52, 0x72, 0xc3, 0x52, 0xa5, 0xb0, 0x0f,
|
|
||||||
0x8e, 0xd5, 0xb5, 0x79, 0x9c, 0xa7, 0x79, 0x0c, 0x49, 0x64, 0x29, 0x89, 0x87, 0x90, 0xc4, 0x43,
|
|
||||||
0x48, 0xaa, 0x53, 0x72, 0x45, 0x7a, 0x13, 0xa6, 0x12, 0xe9, 0x8d, 0x9b, 0x4a, 0x6e, 0xb0, 0xce,
|
|
||||||
0xb2, 0x9b, 0xc5, 0x0d, 0x65, 0xc9, 0xc2, 0x36, 0xdc, 0x52, 0x72, 0x4d, 0x19, 0xba, 0x2c, 0x8c,
|
|
||||||
0xc3, 0x2c, 0x25, 0x37, 0x6c, 0x23, 0xd7, 0x94, 0x8b, 0xd1, 0x2a, 0x88, 0x44, 0xc4, 0xd4, 0xb3,
|
|
||||||
0x9d, 0x30, 0x91, 0xfa, 0xef, 0xd2, 0xae, 0xf7, 0x47, 0x6e, 0x9b, 0x47, 0xff, 0x2b, 0xc2, 0x7b,
|
|
||||||
0x5f, 0xfa, 0x02, 0xf5, 0xd6, 0x92, 0x2d, 0x59, 0x2e, 0xd2, 0x00, 0x4d, 0xee, 0xd2, 0x16, 0xb8,
|
|
||||||
0x04, 0x8b, 0x6c, 0x70, 0xcd, 0x7d, 0x3a, 0x4c, 0xbc, 0x93, 0x1f, 0xc8, 0x64, 0x77, 0xb1, 0xde,
|
|
||||||
0xa4, 0x4d, 0xfe, 0xfa, 0xe3, 0xf3, 0x90, 0x9e, 0xb1, 0x3d, 0xe3, 0x8d, 0x9b, 0x7c, 0xd8, 0xf1,
|
|
||||||
0x68, 0x6d, 0x53, 0x12, 0x45, 0x52, 0xe4, 0x43, 0xda, 0xe3, 0xcc, 0xd2, 0xe9, 0xda, 0x98, 0xb5,
|
|
||||||
0x9b, 0x2e, 0xb4, 0x89, 0x34, 0x16, 0x2a, 0xa9, 0x81, 0x1b, 0x16, 0x8a, 0xc3, 0x19, 0xd4, 0xdb,
|
|
||||||
0xd6, 0x46, 0x57, 0xaa, 0xb0, 0xb5, 0xd1, 0x95, 0xda, 0x9b, 0x08, 0x33, 0xe6, 0x81, 0x74, 0xb1,
|
|
||||||
0x52, 0xc9, 0x4c, 0x9c, 0xae, 0x54, 0x31, 0x16, 0xee, 0x46, 0x2d, 0x5c, 0xb6, 0x95, 0x52, 0x0b,
|
|
||||||
0x17, 0xc7, 0x86, 0x6c, 0xd0, 0x96, 0xdc, 0x17, 0xc0, 0x3c, 0xd4, 0xd6, 0x4d, 0xd4, 0x4b, 0x1c,
|
|
||||||
0x29, 0x89, 0xd9, 0xe1, 0x56, 0x1a, 0x98, 0xc2, 0x01, 0xcb, 0x94, 0xe1, 0xab, 0xc9, 0x48, 0xb1,
|
|
||||||
0x4f, 0xb0, 0xf1, 0xe5, 0xa9, 0x84, 0x06, 0xe6, 0xa0, 0x47, 0x20, 0x14, 0x91, 0xa6, 0x47, 0xf6,
|
|
||||||
0x4c, 0xd1, 0xa0, 0x2a, 0x28, 0x26, 0x25, 0xbe, 0x54, 0xeb, 0xc5, 0x79, 0x93, 0xcd, 0x19, 0xc2,
|
|
||||||
0x0a, 0x30, 0xa1, 0x91, 0x55, 0x08, 0x10, 0x1c, 0x89, 0xf8, 0x4b, 0x42, 0x17, 0xb9, 0x21, 0x94,
|
|
||||||
0x10, 0x5a, 0xdd, 0x7b, 0xea, 0x54, 0x44, 0xf1, 0x4f, 0x68, 0x0a, 0xcb, 0x06, 0x97, 0xd7, 0xb2,
|
|
||||||
0x49, 0xc3, 0xbd, 0x6b, 0xa2, 0x35, 0x64, 0x97, 0xf7, 0x39, 0x28, 0x6a, 0x94, 0x5a, 0x71, 0x74,
|
|
||||||
0xe0, 0x10, 0xd6, 0xf4, 0x66, 0xe1, 0x2f, 0x55, 0xd8, 0xb7, 0xf5, 0x7b, 0x03, 0x07, 0x4d, 0xf5,
|
|
||||||
0x09, 0xe8, 0x46, 0x60, 0x67, 0xbc, 0xdd, 0x3b, 0xd0, 0xca, 0x94, 0xfb, 0x86, 0xa6, 0xac, 0x11,
|
|
||||||
0x0e, 0x07, 0xb9, 0xab, 0x02, 0xfd, 0x94, 0x82, 0xb3, 0xd1, 0xd8, 0xd8, 0x6a, 0x78, 0x47, 0x60,
|
|
||||||
0x7e, 0x80, 0x24, 0x61, 0x46, 0xe2, 0xa2, 0xc9, 0x5c, 0xc4, 0x82, 0x5b, 0x4b, 0xa7, 0x2b, 0xf1,
|
|
||||||
0x88, 0x6a, 0xa8, 0x32, 0xc3, 0xdb, 0xec, 0x87, 0xb3, 0x9d, 0xce, 0xbf, 0x30, 0x66, 0xe8, 0xfc,
|
|
||||||
0x0b, 0x72, 0x23, 0x15, 0xd3, 0x1e, 0x95, 0x01, 0x0e, 0xdc, 0x08, 0xca, 0x80, 0x5a, 0x07, 0x3d,
|
|
||||||
0x30, 0x40, 0x1b, 0xc6, 0x04, 0xf5, 0xf1, 0x53, 0x31, 0x66, 0x86, 0xb1, 0x41, 0x0d, 0xbf, 0x30,
|
|
||||||
0x82, 0xf3, 0x2f, 0x8c, 0x19, 0x23, 0x52, 0xc3, 0xfc, 0x0b, 0xe3, 0x86, 0x32, 0xa0, 0x50, 0x6e,
|
|
||||||
0x4c, 0xd7, 0x46, 0x19, 0xe0, 0x94, 0x1b, 0x3a, 0x7f, 0x37, 0x9d, 0xbf, 0x35, 0xfb, 0x81, 0x01,
|
|
||||||
0xc5, 0xc0, 0x0f, 0x95, 0x06, 0xe3, 0x56, 0x67, 0x1c, 0x80, 0x47, 0x8c, 0x25, 0xa5, 0x38, 0x38,
|
|
||||||
0xb2, 0xa3, 0xb6, 0x2e, 0x6d, 0x01, 0x94, 0x01, 0x8e, 0xdc, 0x88, 0x1c, 0x35, 0x83, 0x90, 0xb2,
|
|
||||||
0x09, 0xd6, 0xb0, 0xf5, 0x2c, 0x9d, 0x72, 0xc2, 0x38, 0x30, 0x15, 0x04, 0xfd, 0xde, 0x98, 0x77,
|
|
||||||
0xa5, 0x1c, 0x28, 0x02, 0x3b, 0x33, 0x0e, 0x28, 0x3b, 0xc8, 0x80, 0xca, 0x91, 0x1d, 0xb5, 0x32,
|
|
||||||
0xc0, 0x19, 0x37, 0x6c, 0x34, 0x36, 0x36, 0x32, 0xc0, 0x91, 0x1b, 0x26, 0xe0, 0x8d, 0x9b, 0xb0,
|
|
||||||
0xc3, 0x0d, 0xe2, 0x50, 0x0c, 0xda, 0xa0, 0xca, 0x51, 0x4c, 0x4e, 0x37, 0x1d, 0xe7, 0x6f, 0xba,
|
|
||||||
0xe1, 0x4c, 0x1d, 0x8c, 0x1b, 0xd3, 0x1e, 0x95, 0x01, 0xaa, 0x1c, 0xca, 0x80, 0xba, 0x18, 0x33,
|
|
||||||
0xc0, 0x1a, 0x83, 0x38, 0xe8, 0x9c, 0xdd, 0x98, 0x19, 0xf6, 0xa9, 0x26, 0xac, 0x6c, 0x0b, 0x55,
|
|
||||||
0x07, 0x63, 0x86, 0xaa, 0x83, 0xf1, 0x52, 0xe7, 0x6f, 0xca, 0x61, 0x0c, 0x50, 0xe5, 0x70, 0xd3,
|
|
||||||
0xb5, 0x51, 0x06, 0xa8, 0x72, 0xb8, 0x89, 0x3a, 0x0c, 0xf3, 0xb7, 0xe6, 0xa9, 0x18, 0x1f, 0x16,
|
|
||||||
0x24, 0x25, 0x09, 0x68, 0xba, 0xaf, 0x0b, 0x71, 0xbf, 0xac, 0xe4, 0x0b, 0xf3, 0x5c, 0x94, 0x03,
|
|
||||||
0x35, 0x5d, 0x35, 0x96, 0xa3, 0xfb, 0xba, 0xc5, 0xef, 0x97, 0x76, 0xeb, 0xee, 0xab, 0x1e, 0x57,
|
|
||||||
0xbf, 0xe8, 0x2e, 0xaf, 0x08, 0x20, 0xde, 0x6e, 0x37, 0xb7, 0x6b, 0xe0, 0xcc, 0x09, 0x28, 0x8f,
|
|
||||||
0xad, 0x95, 0x70, 0xfa, 0x59, 0x94, 0x2d, 0xc5, 0x53, 0x46, 0xb0, 0x37, 0x01, 0x16, 0x46, 0x04,
|
|
||||||
0x2d, 0x17, 0x64, 0xf1, 0xa6, 0xc3, 0x19, 0x36, 0x40, 0x20, 0xca, 0x59, 0x76, 0x04, 0xc5, 0xcd,
|
|
||||||
0x83, 0x2c, 0x97, 0x0f, 0x70, 0x6a, 0xbd, 0xc4, 0x1b, 0xe4, 0x5e, 0xaa, 0xc5, 0x0d, 0x96, 0xcd,
|
|
||||||
0x15, 0x9b, 0x25, 0x02, 0x5b, 0x1c, 0x65, 0x97, 0x4a, 0x08, 0x28, 0x02, 0x01, 0x7f, 0x9f, 0xf7,
|
|
||||||
0x56, 0xa4, 0x92, 0xb0, 0x34, 0xcb, 0x6e, 0x20, 0xf7, 0x34, 0x11, 0x71, 0x3c, 0x83, 0x25, 0xd9,
|
|
||||||
0x17, 0x86, 0x66, 0xa8, 0x64, 0x54, 0x99, 0xac, 0xae, 0x75, 0x0f, 0xf0, 0x12, 0x33, 0x47, 0x44,
|
|
||||||
0x98, 0xd2, 0x17, 0x9c, 0x0e, 0xf9, 0xb4, 0xef, 0x10, 0x43, 0x51, 0x43, 0x4c, 0xb9, 0x22, 0x58,
|
|
||||||
0x08, 0xc5, 0xc0, 0x56, 0x1f, 0x11, 0x83, 0x7a, 0x28, 0x48, 0x2b, 0x4e, 0x97, 0xec, 0xaa, 0x21,
|
|
||||||
0x7a, 0xfa, 0x12, 0x0d, 0xf5, 0xb4, 0x16, 0x43, 0x51, 0xc3, 0x41, 0xa9, 0x10, 0xc2, 0x47, 0xf1,
|
|
||||||
0x35, 0x65, 0x5b, 0x4b, 0xe5, 0xb0, 0x13, 0x00, 0x81, 0x89, 0xe2, 0x12, 0x4a, 0x24, 0x6b, 0x26,
|
|
||||||
0x3d, 0x21, 0x04, 0x68, 0x90, 0x29, 0xb0, 0x0b, 0xeb, 0xa4, 0xb8, 0x89, 0x28, 0x45, 0xdd, 0x38,
|
|
||||||
0x09, 0x9d, 0xb3, 0xf8, 0xfb, 0xd6, 0x9d, 0xf6, 0x5e, 0xee, 0x9b, 0x36, 0x8d, 0x52, 0x87, 0x3e,
|
|
||||||
0x4c, 0xc7, 0x8d, 0xa6, 0x23, 0xe7, 0x44, 0x5f, 0x10, 0x7b, 0xa2, 0x67, 0x18, 0x81, 0x98, 0xe9,
|
|
||||||
0x3a, 0x2b, 0x4f, 0x9c, 0xf1, 0x04, 0xa1, 0x3f, 0xf2, 0x1d, 0x49, 0xb4, 0x3a, 0x8a, 0xdf, 0x0f,
|
|
||||||
0xdf, 0x02, 0xae, 0xb3, 0xac, 0x6c, 0x9d, 0x06, 0x66, 0xbb, 0x81, 0xd9, 0x1e, 0x96, 0x00, 0x2e,
|
|
||||||
0x5b, 0x29, 0x5a, 0xca, 0xb4, 0x44, 0x49, 0xd7, 0x01, 0xe8, 0x79, 0x03, 0xb3, 0xa6, 0x2b, 0xe9,
|
|
||||||
0x86, 0x95, 0xac, 0xe0, 0xef, 0x88, 0xed, 0x47, 0xac, 0xa8, 0x51, 0x04, 0x45, 0x41, 0xe5, 0x42,
|
|
||||||
0x1b, 0x5f, 0x9e, 0xda, 0x14, 0xa0, 0x1f, 0x1d, 0x45, 0xa3, 0xcd, 0x50, 0xc7, 0x00, 0x07, 0x0d,
|
|
||||||
0xfe, 0x5b, 0xf2, 0xb5, 0x35, 0xf4, 0x13, 0xf6, 0x25, 0x42, 0x70, 0x38, 0xed, 0x4a, 0x9c, 0x84,
|
|
||||||
0x00, 0x47, 0x42, 0xf6, 0xab, 0x80, 0x34, 0x83, 0xfc, 0xbf, 0x92, 0xe1, 0x56, 0x32, 0x65, 0x38,
|
|
||||||
0x6e, 0x12, 0x4d, 0x67, 0xcf, 0xd0, 0x5d, 0xac, 0x0b, 0xc0, 0x20, 0x31, 0x88, 0x67, 0x29, 0x0a,
|
|
||||||
0x97, 0xc4, 0xc3, 0xa0, 0x3f, 0x2e, 0x7c, 0x81, 0x97, 0x27, 0xb6, 0x32, 0x42, 0x61, 0xda, 0xb3,
|
|
||||||
0x2a, 0x83, 0x74, 0x05, 0x48, 0x04, 0x48, 0x1d, 0x98, 0x67, 0x17, 0x17, 0xc3, 0xc5, 0x12, 0x36,
|
|
||||||
0xc3, 0x45, 0x47, 0x5c, 0x1f, 0x00, 0x1f, 0x6b, 0xc7, 0x32, 0x7f, 0x44, 0x01, 0xf5, 0xbe, 0x3d,
|
|
||||||
0x0c, 0xa4, 0x1c, 0xe6, 0x55, 0x70, 0x3e, 0x49, 0xe7, 0x33, 0xf9, 0xcc, 0x0d, 0x32, 0x30, 0xdc,
|
|
||||||
0x30, 0xc5, 0xbe, 0xc5, 0x84, 0x44, 0x48, 0x03, 0x40, 0xab, 0xad, 0x94, 0xc5, 0x95, 0xb0, 0xbe,
|
|
||||||
0x05, 0x4b, 0x01, 0xf5, 0x89, 0x93, 0x04, 0xe0, 0x51, 0x46, 0x85, 0xb4, 0x8a, 0x10, 0x88, 0x00,
|
|
||||||
0x32, 0x6a, 0x85, 0x6d, 0xd8, 0x92, 0x80, 0xb2, 0x44, 0xa0, 0x01, 0x4f, 0x35, 0x7a, 0x3b, 0x57,
|
|
||||||
0xe8, 0xb9, 0x0e, 0xf9, 0x98, 0x3a, 0x26, 0x24, 0xb4, 0x2a, 0xd9, 0x74, 0x81, 0xc7, 0x78, 0xf4,
|
|
||||||
0x65, 0x7d, 0x58, 0x9f, 0x43, 0x7b, 0x85, 0xc9, 0xe8, 0xef, 0x36, 0xb7, 0x2b, 0x2c, 0x46, 0x23,
|
|
||||||
0x84, 0x91, 0xa1, 0x39, 0xd8, 0x8c, 0x32, 0xd2, 0x66, 0x20, 0xdc, 0xf3, 0x4c, 0x2c, 0x89, 0x6c,
|
|
||||||
0x84, 0x28, 0xde, 0x25, 0xc2, 0x91, 0x9d, 0xe8, 0x64, 0x4b, 0xef, 0x15, 0x09, 0xaa, 0xd6, 0x87,
|
|
||||||
0xa1, 0xed, 0xac, 0x0d, 0x97, 0x06, 0xf4, 0x6a, 0xee, 0xf6, 0xc2, 0x62, 0xef, 0x99, 0x7e, 0x42,
|
|
||||||
0xc2, 0xa2, 0x01, 0x7a, 0x22, 0x44, 0x93, 0x07, 0x16, 0xd1, 0xca, 0x2e, 0x25, 0x42, 0xd3, 0xd0,
|
|
||||||
0xfb, 0x2e, 0xd1, 0x5b, 0x3c, 0x03, 0x5d, 0xe1, 0x23, 0xf0, 0x89, 0x28, 0xf7, 0xb4, 0x3b, 0xd1,
|
|
||||||
0x4a, 0xe6, 0xb6, 0x5a, 0x0c, 0x0c, 0x6c, 0x90, 0x6b, 0x24, 0xe8, 0xd3, 0x63, 0xec, 0x24, 0xf2,
|
|
||||||
0x69, 0x84, 0x8c, 0x7e, 0xb6, 0xdc, 0x70, 0x3c, 0x1a, 0xc0, 0x49, 0x42, 0x43, 0x15, 0x6f, 0x7d,
|
|
||||||
0xdd, 0x7b, 0xd8, 0x9e, 0xa0, 0x08, 0x5b, 0x20, 0x38, 0xc7, 0x8c, 0x57, 0x5d, 0xe5, 0x1d, 0x28,
|
|
||||||
0x63, 0x3a, 0xe8, 0x28, 0x42, 0x6d, 0x03, 0x4e, 0x86, 0x9a, 0xd0, 0x61, 0x57, 0xd3, 0xc9, 0xce,
|
|
||||||
0xc4, 0xf4, 0xb0, 0xb2, 0x44, 0x84, 0x61, 0x6b, 0x84, 0x59, 0x98, 0x0a, 0x5b, 0xbd, 0x87, 0x85,
|
|
||||||
0x0d, 0xe2, 0x9a, 0x40, 0x6d, 0xf5, 0x94, 0xd3, 0x53, 0x3b, 0xa5, 0xe7, 0x8c, 0x9e, 0xb3, 0xde,
|
|
||||||
0x9c, 0xf6, 0xd6, 0xb5, 0x1a, 0xc4, 0x89, 0x93, 0x4d, 0x19, 0x09, 0x35, 0x22, 0xfb, 0x0a, 0xbe,
|
|
||||||
0x19, 0x86, 0xa8, 0xce, 0x75, 0xee, 0x15, 0xe6, 0x02, 0x2b, 0xab, 0x4a, 0xe7, 0xe5, 0x74, 0x5e,
|
|
||||||
0xbb, 0x81, 0x1f, 0xce, 0xf8, 0xe1, 0x94, 0x5d, 0xce, 0xd8, 0xd5, 0x81, 0xd5, 0x40, 0xae, 0x00,
|
|
||||||
0xd4, 0x51, 0xbf, 0xa1, 0x4a, 0xf0, 0xec, 0xc8, 0x63, 0xa7, 0x3c, 0x96, 0x35, 0xaf, 0x3d, 0xe2,
|
|
||||||
0x70, 0x4f, 0x94, 0x21, 0x49, 0x80, 0x22, 0xa6, 0xa4, 0x22, 0x44, 0x22, 0x6a, 0xc7, 0xef, 0xba,
|
|
||||||
0x4b, 0x02, 0x13, 0x47, 0x08, 0x82, 0xe4, 0x4d, 0x86, 0xdf, 0x2f, 0x43, 0xa7, 0xea, 0x41, 0x40,
|
|
||||||
0x48, 0x41, 0x04, 0x04, 0x06, 0xa7, 0x06, 0x72, 0x19, 0x20, 0x43, 0x09, 0x48, 0x40, 0x8c, 0x58,
|
|
||||||
0x89, 0x88, 0x38, 0x47, 0xcc, 0xc9, 0x59, 0xa5, 0xc1, 0x97, 0x5c, 0x02, 0x53, 0x81, 0x05, 0xc3,
|
|
||||||
0xce, 0xd9, 0x20, 0xa2, 0x13, 0x6e, 0x49, 0x20, 0xb5, 0xf3, 0xb0, 0xbf, 0x4c, 0x01, 0xea, 0x31,
|
|
||||||
0xc0, 0x50, 0x56, 0x1e, 0x38, 0xb3, 0x08, 0x0a, 0x44, 0xac, 0xcc, 0x25, 0x28, 0xd5, 0x04, 0x63,
|
|
||||||
0xe1, 0x6f, 0x0a, 0x91, 0x86, 0x1e, 0x74, 0x82, 0x77, 0x8d, 0x90, 0x71, 0x47, 0xc0, 0x50, 0xe4,
|
|
||||||
0x5d, 0x54, 0xab, 0x84, 0x58, 0x0f, 0x6d, 0x67, 0x6d, 0x84, 0x37, 0x89, 0x3d, 0x57, 0xe8, 0xab,
|
|
||||||
0x04, 0xb3, 0x18, 0x57, 0x67, 0xa5, 0xe3, 0x06, 0x3a, 0xd6, 0xbd, 0xd3, 0xee, 0x9d, 0x8e, 0xaa,
|
|
||||||
0xb6, 0x63, 0xea, 0xa2, 0x39, 0xa6, 0xc0, 0x6b, 0x45, 0x12, 0xc4, 0xa9, 0xe4, 0xe2, 0x47, 0x4e,
|
|
||||||
0xc9, 0xd9, 0x94, 0x8c, 0x0f, 0xce, 0xf8, 0xe0, 0x94, 0x4d, 0xc0, 0x08, 0xc8, 0xa6, 0x4e, 0xba,
|
|
||||||
0x0a, 0x88, 0xdd, 0xcb, 0x0c, 0x22, 0x08, 0xaa, 0xc9, 0x4e, 0xe3, 0xad, 0x36, 0xd6, 0x20, 0x8d,
|
|
||||||
0xb7, 0xd7, 0x7d, 0xbf, 0x26, 0x5f, 0x50, 0xab, 0x7b, 0x1a, 0x2b, 0xb1, 0x74, 0xbb, 0x90, 0x45,
|
|
||||||
0x6e, 0x5a, 0xa0, 0xb9, 0x38, 0x42, 0x2e, 0x81, 0x15, 0xf3, 0xd3, 0xe9, 0x77, 0xb8, 0x76, 0x25,
|
|
||||||
0xf6, 0x80, 0x2a, 0x91, 0x95, 0x2d, 0xd1, 0x63, 0xfd, 0xd4, 0x73, 0xd6, 0xe0, 0x79, 0xd9, 0xac,
|
|
||||||
0x77, 0x46, 0x0c, 0xf8, 0xf7, 0x84, 0xf8, 0xf0, 0xff, 0xae, 0x38, 0xf4, 0x72, 0x8a, 0x06, 0xac,
|
|
||||||
0x10, 0x9b, 0x6e, 0x74, 0x9d, 0x1b, 0xc6, 0xe1, 0xf4, 0x9a, 0xdd, 0xb4, 0x93, 0x3c, 0xef, 0xb4,
|
|
||||||
0x1b, 0x91, 0x68, 0x4e, 0x92, 0x10, 0x16, 0x88, 0x88, 0x63, 0xa2, 0x5e, 0xf4, 0x10, 0x6b, 0x56,
|
|
||||||
0xb7, 0xcc, 0x2a, 0x40, 0x50, 0xd8, 0xe8, 0x7d, 0xa5, 0x52, 0xc4, 0xac, 0xb7, 0x9e, 0x29, 0x70,
|
|
||||||
0xa6, 0xdd, 0x4d, 0x7b, 0xcd, 0x6e, 0xde, 0xbb, 0x12, 0x3e, 0x90, 0x17, 0x17, 0x64, 0x44, 0xdf,
|
|
||||||
0x2f, 0xd2, 0xf7, 0x4a, 0xbf, 0x1b, 0xcf, 0xfc, 0xd4, 0x3a, 0x54, 0xbb, 0x19, 0x57, 0xf3, 0x0a,
|
|
||||||
0x11, 0xd9, 0xdc, 0xde, 0x5e, 0xff, 0xc5, 0x22, 0xe1, 0xa2, 0x7b, 0x77, 0xdb, 0xed, 0xb6, 0x2b,
|
|
||||||
0xc4, 0xc5, 0xb0, 0x73, 0xa6, 0x3c, 0x44, 0x65, 0xba, 0x11, 0x86, 0x8e, 0x0c, 0xc7, 0x14, 0x3c,
|
|
||||||
0x77, 0x06, 0x9e, 0x0f, 0xed, 0xde, 0x00, 0x79, 0x47, 0x40, 0x3e, 0xda, 0x69, 0x94, 0x17, 0xe8,
|
|
||||||
0xe5, 0xc3, 0x51, 0xc9, 0x1c, 0xda, 0x03, 0x70, 0x6f, 0xb7, 0x29, 0x95, 0xf6, 0xa8, 0x97, 0xe9,
|
|
||||||
0x6d, 0xa1, 0x98, 0x92, 0x0f, 0xc5, 0x70, 0xdf, 0x24, 0x1d, 0x90, 0xf7, 0xe9, 0x80, 0xfd, 0x65,
|
|
||||||
0x93, 0x49, 0x84, 0x7d, 0x06, 0xc0, 0x6e, 0x1b, 0xe6, 0x30, 0xeb, 0xe5, 0xcb, 0xc4, 0xe5, 0xb6,
|
|
||||||
0x4c, 0x52, 0xa9, 0x89, 0xa3, 0x62, 0x9c, 0x51, 0x2a, 0xf8, 0xd9, 0xdb, 0xff, 0x8a, 0xd1, 0xff,
|
|
||||||
0xf4, 0x53, 0x1c, 0x00, 0xbb, 0x59, 0xdb, 0x6e, 0x7c, 0xa1, 0x92, 0xe8, 0x97, 0x32, 0x54, 0xa7,
|
|
||||||
0xc2, 0x29, 0x2f, 0xc3, 0x22, 0x7a, 0xea, 0x09, 0x01, 0xee, 0x82, 0xf8, 0x87, 0xc2, 0x2b, 0x7c,
|
|
||||||
0x52, 0xac, 0xa2, 0xa9, 0xf7, 0x48, 0xf1, 0xf2, 0xa0, 0x11, 0xa5, 0x3b, 0xa8, 0xbe, 0x09, 0xde,
|
|
||||||
0x5c, 0x6b, 0xc4, 0xb8, 0x22, 0xcf, 0x03, 0xc7, 0x34, 0x21, 0x5f, 0x98, 0xde, 0xc6, 0xc0, 0x0c,
|
|
||||||
0x52, 0x37, 0xd4, 0x05, 0xdc, 0x5b, 0x72, 0x30, 0x2f, 0x30, 0x7a, 0x5b, 0xd8, 0xed, 0x3b, 0x23,
|
|
||||||
0xe7, 0x8c, 0x7c, 0x77, 0x18, 0x49, 0x3c, 0x3d, 0x92, 0xa2, 0xe6, 0x28, 0xf9, 0x59, 0x50, 0xc9,
|
|
||||||
0x1a, 0xea, 0x55, 0x82, 0x11, 0x87, 0x32, 0xb2, 0xd1, 0x17, 0x63, 0x2d, 0xb3, 0x53, 0x45, 0x43,
|
|
||||||
0xd6, 0x14, 0x63, 0xde, 0xc8, 0x3e, 0x60, 0x56, 0x48, 0xbe, 0xb0, 0xab, 0xa0, 0xda, 0xe6, 0xff,
|
|
||||||
0x81, 0x72, 0xb1, 0xe4, 0x7d, 0xbd, 0x76, 0x65, 0xf8, 0xec, 0x88, 0x07, 0x4c, 0xbb, 0x8a, 0x89,
|
|
||||||
0x7a, 0x2d, 0xe5, 0xa6, 0xf6, 0xea, 0x55, 0x4c, 0xf5, 0x6b, 0xa6, 0x00, 0x75, 0x31, 0xd3, 0xaf,
|
|
||||||
0x99, 0x02, 0x25, 0x37, 0xd5, 0xaf, 0x99, 0xfa, 0xe5, 0x99, 0x5a, 0x86, 0x99, 0xfa, 0x06, 0x37,
|
|
||||||
0xd5, 0xaf, 0x99, 0xf2, 0x07, 0x37, 0xd3, 0xaf, 0x99, 0x02, 0xe5, 0x62, 0xaa, 0x5f, 0xc5, 0xbd,
|
|
||||||
0xfa, 0x35, 0xd3, 0x91, 0x13, 0xca, 0xd4, 0x1f, 0xab, 0x8d, 0xe9, 0xd7, 0x54, 0x37, 0x4f, 0x64,
|
|
||||||
0x7b, 0xfb, 0x13, 0xfa, 0xba, 0xac, 0x5f, 0x4d, 0x4e, 0x94, 0xae, 0x41, 0xbf, 0xa6, 0x42, 0x34,
|
|
||||||
0xd2, 0xb0, 0xf1, 0xd6, 0x96, 0xf7, 0xdb, 0xe3, 0x68, 0x73, 0x6d, 0x8a, 0xd3, 0x1a, 0x36, 0x57,
|
|
||||||
0xb0, 0x41, 0x45, 0x66, 0xa5, 0x37, 0x6e, 0x54, 0x0e, 0x74, 0x28, 0x4b, 0x18, 0x97, 0xd4, 0xa8,
|
|
||||||
0x86, 0x0d, 0x0a, 0x56, 0xcc, 0x35, 0x6c, 0x34, 0x94, 0x78, 0x7a, 0x28, 0x6e, 0xa4, 0x62, 0x6e,
|
|
||||||
0xac, 0x62, 0x6e, 0xa2, 0x62, 0xf3, 0x7d, 0xec, 0xa0, 0x61, 0x63, 0xde, 0x0c, 0xfa, 0xe5, 0xbe,
|
|
||||||
0x49, 0xbf, 0x6e, 0xaf, 0xbb, 0xf7, 0xdb, 0x35, 0x48, 0x48, 0x42, 0x1c, 0xe8, 0xb4, 0xb8, 0xb1,
|
|
||||||
0x68, 0x44, 0xc6, 0x58, 0x10, 0x81, 0x64, 0x40, 0x6c, 0x98, 0x65, 0xf4, 0xcc, 0x10, 0xe5, 0xfe,
|
|
||||||
0xd0, 0x74, 0xf6, 0x2f, 0x1c, 0x9d, 0xfe, 0xdb, 0x0d, 0xff, 0x3e, 0x34, 0x87, 0x2b, 0xbe, 0x58,
|
|
||||||
0x17, 0x2c, 0x09, 0x9a, 0x14, 0xa5, 0x1c, 0x15, 0xde, 0xf4, 0xf3, 0x72, 0x9b, 0x7b, 0x6a, 0x50,
|
|
||||||
0x8e, 0x6a, 0x97, 0xf8, 0x71, 0x4a, 0x02, 0xb1, 0xaa, 0x48, 0x46, 0xb1, 0xe6, 0x23, 0xb1, 0xdc,
|
|
||||||
0xae, 0x64, 0xf8, 0xc9, 0xda, 0x09, 0xc4, 0x58, 0xf4, 0x25, 0x92, 0xfa, 0x12, 0x08, 0x3a, 0x25,
|
|
||||||
0x90, 0xd2, 0x4f, 0x89, 0x02, 0x62, 0xd4, 0xc8, 0x33, 0x48, 0x0c, 0xd6, 0x46, 0x3a, 0x60, 0xe2,
|
|
||||||
0x79, 0x36, 0x99, 0x91, 0x54, 0x40, 0x0a, 0xa1, 0xce, 0x14, 0x11, 0x10, 0xaa, 0x82, 0x96, 0xfc,
|
|
||||||
0x05, 0x14, 0x25, 0xc2, 0xc2, 0x0c, 0xed, 0xe6, 0x2c, 0x03, 0x62, 0x42, 0xe6, 0xa7, 0x45, 0x4d,
|
|
||||||
0x05, 0xca, 0x4d, 0x00, 0x72, 0xc4, 0x94, 0x5c, 0x15, 0xb5, 0x44, 0xa4, 0x21, 0x0c, 0x35, 0x1c,
|
|
||||||
0xc4, 0xb1, 0xf6, 0xe2, 0xf8, 0xd4, 0x2c, 0xd3, 0xac, 0x44, 0x62, 0x44, 0x52, 0x5b, 0xad, 0x02,
|
|
||||||
0xd5, 0x54, 0x4a, 0xc3, 0xa8, 0xbb, 0x00, 0xde, 0xe1, 0x91, 0xbe, 0x13, 0xbb, 0x90, 0x25, 0x38,
|
|
||||||
0xac, 0x82, 0xd6, 0xe2, 0xa0, 0x12, 0x25, 0x53, 0xca, 0x32, 0xca, 0x01, 0x99, 0xc6, 0x10, 0xd7,
|
|
||||||
0xdb, 0xe3, 0x3b, 0x12, 0x05, 0x32, 0x01, 0x94, 0x33, 0xe0, 0xfb, 0x97, 0xa7, 0xa1, 0x46, 0x91,
|
|
||||||
0x08, 0x02, 0x77, 0xe9, 0x2f, 0x22, 0xc8, 0x8e, 0x38, 0x5a, 0x56, 0xbf, 0xd5, 0x34, 0x6b, 0x5d,
|
|
||||||
0x88, 0x2a, 0x87, 0x1c, 0x50, 0x2e, 0x12, 0x2a, 0xa6, 0x6e, 0x91, 0xf4, 0xa8, 0x25, 0xbc, 0x20,
|
|
||||||
0xe2, 0x15, 0x10, 0xfb, 0x95, 0x1a, 0x41, 0xc8, 0x8a, 0x47, 0x66, 0x3d, 0x10, 0xeb, 0x35, 0xc0,
|
|
||||||
0x19, 0xab, 0xc8, 0xac, 0x28, 0x22, 0x3f, 0x00, 0x14, 0x08, 0x68, 0xe0, 0xe1, 0x83, 0x19, 0x09,
|
|
||||||
0xe1, 0x83, 0xc4, 0x3a, 0x15, 0xbd, 0xd9, 0x58, 0x83, 0xa5, 0x45, 0xd5, 0x10, 0xc0, 0x6e, 0x4a,
|
|
||||||
0x62, 0x6f, 0x29, 0x31, 0x72, 0x14, 0x76, 0x34, 0x48, 0x1e, 0xd6, 0x5a, 0x08, 0xaa, 0x68, 0x9a,
|
|
||||||
0x0c, 0xbd, 0xc1, 0x4a, 0x56, 0x34, 0xe9, 0x67, 0x29, 0x07, 0x45, 0x42, 0xa4, 0x03, 0x59, 0x15,
|
|
||||||
0x98, 0x4a, 0xc4, 0x0c, 0x69, 0x38, 0x20, 0xa9, 0x04, 0xfc, 0xa7, 0x84, 0x7a, 0x22, 0xeb, 0x83,
|
|
||||||
0xec, 0x10, 0x1b, 0xcb, 0xf5, 0x7c, 0x48, 0x65, 0xa3, 0xde, 0xb4, 0x56, 0x63, 0x22, 0x73, 0x8d,
|
|
||||||
0x09, 0x4c, 0x89, 0x80, 0x08, 0xa5, 0xd9, 0x4a, 0xc8, 0x2a, 0x43, 0x44, 0xa4, 0x9e, 0x03, 0x95,
|
|
||||||
0xb6, 0x4a, 0x9a, 0xe5, 0x96, 0xd9, 0x10, 0x80, 0xcf, 0x84, 0xa1, 0x83, 0xc7, 0xad, 0x59, 0x17,
|
|
||||||
0x2b, 0x33, 0xbe, 0x64, 0xc4, 0x1c, 0xd4, 0x35, 0x2d, 0x59, 0x76, 0x1a, 0x10, 0x02, 0x23, 0x94,
|
|
||||||
0x67, 0x22, 0x04, 0x85, 0xb9, 0x59, 0xa2, 0x43, 0x40, 0x6b, 0x72, 0x0e, 0x55, 0xa1, 0x05, 0xea,
|
|
||||||
0x42, 0x50, 0x34, 0x5a, 0xb2, 0x36, 0x18, 0x89, 0x31, 0x44, 0xd5, 0xb2, 0x46, 0x28, 0x0a, 0x40,
|
|
||||||
0x08, 0xa6, 0x25, 0xc1, 0x2c, 0xf7, 0x42, 0xe0, 0x9c, 0x6c, 0x3f, 0x03, 0x12, 0xc4, 0x8a, 0x97,
|
|
||||||
0x92, 0xc1, 0x1b, 0x10, 0xb2, 0x44, 0x59, 0x06, 0x7e, 0x26, 0x26, 0x0e, 0x40, 0x98, 0xc3, 0x90,
|
|
||||||
0x5b, 0x08, 0x56, 0x59, 0xa1, 0x2e, 0x86, 0x20, 0x13, 0xb2, 0x37, 0xd0, 0x22, 0xa6, 0x0d, 0x91,
|
|
||||||
0x8c, 0x47, 0xb0, 0x85, 0x81, 0x66, 0x8f, 0xb0, 0x10, 0x80, 0x31, 0xf0, 0x7a, 0x56, 0x30, 0x30,
|
|
||||||
0xc9, 0xcb, 0x59, 0xb6, 0x67, 0x4d, 0x84, 0x57, 0x0f, 0x48, 0x08, 0xc9, 0xc4, 0x36, 0x58, 0x43,
|
|
||||||
0xa6, 0xa4, 0x38, 0x65, 0x65, 0x88, 0xba, 0x16, 0xdb, 0x96, 0x09, 0x7a, 0x87, 0xf0, 0xbb, 0x44,
|
|
||||||
0x88, 0x8f, 0x42, 0x8e, 0x9a, 0xa0, 0xba, 0x57, 0x80, 0xa8, 0x25, 0x93, 0x6b, 0x44, 0xe2, 0x0d,
|
|
||||||
0x52, 0x93, 0xb4, 0x1f, 0xc4, 0x4e, 0x6a, 0x24, 0x79, 0x1a, 0x4d, 0x4d, 0x06, 0x56, 0x40, 0xf9,
|
|
||||||
0xa8, 0x1a, 0x29, 0x8a, 0x48, 0x4c, 0x2c, 0x31, 0x1c, 0xaf, 0x29, 0xef, 0x4e, 0x26, 0x0e, 0x68,
|
|
||||||
0x5e, 0x84, 0x94, 0x29, 0x2d, 0x19, 0x9a, 0xc8, 0x3a, 0xb8, 0x83, 0x12, 0xdb, 0xc0, 0x14, 0xa2,
|
|
||||||
0x1d, 0x50, 0x17, 0x26, 0x01, 0x2d, 0x30, 0xc2, 0x6a, 0xb8, 0x24, 0xe8, 0x1d, 0x2c, 0x93, 0xae,
|
|
||||||
0x59, 0x3c, 0x85, 0x04, 0x29, 0x76, 0x0d, 0xa4, 0xbf, 0x59, 0xd6, 0xab, 0xdd, 0x06, 0x1b, 0x85,
|
|
||||||
0x67, 0x4a, 0x44, 0x4b, 0x2a, 0x1a, 0x31, 0x21, 0x32, 0xfa, 0x94, 0x13, 0xe6, 0xc2, 0x2c, 0x40,
|
|
||||||
0x83, 0x2c, 0x00, 0x26, 0x56, 0x21, 0x2d, 0x9e, 0x45, 0x41, 0xf8, 0x09, 0xe1, 0x40, 0x71, 0x16,
|
|
||||||
0x70, 0x12, 0x14, 0xc4, 0xc9, 0x90, 0x2d, 0x85, 0x53, 0x62, 0x87, 0x89, 0xc8, 0x98, 0x66, 0x26,
|
|
||||||
0x4c, 0x9b, 0x86, 0x99, 0xc7, 0x8a, 0xe5, 0x54, 0x0d, 0xba, 0xd5, 0x96, 0x42, 0x98, 0xa5, 0x53,
|
|
||||||
0x05, 0x11, 0x45, 0x6a, 0xb8, 0x2b, 0xd5, 0xac, 0x52, 0x68, 0x4a, 0xa2, 0x98, 0xc8, 0xa6, 0xc9,
|
|
||||||
0x10, 0x5b, 0x97, 0x09, 0xf6, 0xd4, 0x80, 0xa4, 0xf7, 0x4b, 0x3e, 0x88, 0x40, 0x9d, 0x88, 0x50,
|
|
||||||
0x57, 0x0d, 0xfd, 0x1d, 0xd1, 0xd3, 0x04, 0x6b, 0x19, 0x35, 0xdb, 0x61, 0xc2, 0xa4, 0xc2, 0xc5,
|
|
||||||
0xfc, 0x9f, 0x08, 0x7a, 0x1d, 0x81, 0x92, 0x03, 0x66, 0x41, 0xe5, 0x47, 0x5b, 0x42, 0x34, 0x07,
|
|
||||||
0x09, 0x55, 0x81, 0xad, 0x34, 0x62, 0x07, 0x1a, 0x85, 0x2a, 0x57, 0x59, 0x5f, 0xe4, 0xce, 0x25,
|
|
||||||
0x36, 0x03, 0xc4, 0xa2, 0x32, 0x1f, 0x34, 0x2f, 0x9a, 0x6a, 0x9a, 0x87, 0xd8, 0x70, 0xb5, 0x80,
|
|
||||||
0xe3, 0x42, 0x38, 0x80, 0x07, 0x00, 0x4c, 0x51, 0x55, 0xaa, 0xf6, 0xaa, 0x25, 0x8a, 0x82, 0xb1,
|
|
||||||
0xc2, 0x10, 0x25, 0xd8, 0xaa, 0xc4, 0x7a, 0xf7, 0x00, 0xca, 0xb2, 0x3e, 0xd6, 0x34, 0x9d, 0xfd,
|
|
||||||
0xa4, 0xc5, 0xb6, 0x5a, 0x62, 0xf8, 0xd4, 0xc7, 0x96, 0xc1, 0xac, 0xd8, 0x7a, 0x58, 0xd6, 0x4e,
|
|
||||||
0x22, 0x7f, 0xd4, 0x89, 0xc1, 0x02, 0xa9, 0xc9, 0xca, 0x35, 0x41, 0x54, 0xfa, 0x80, 0x65, 0xa3,
|
|
||||||
0xa8, 0x04, 0x4c, 0x62, 0xc5, 0x44, 0x63, 0x90, 0xc9, 0x47, 0xcd, 0xe5, 0x00, 0x53, 0x07, 0xfe,
|
|
||||||
0xe1, 0x3d, 0xc1, 0xbd, 0x98, 0x68, 0xcb, 0xbd, 0x30, 0x25, 0x8a, 0xd8, 0xc4, 0x96, 0x75, 0x67,
|
|
||||||
0x95, 0x22, 0x37, 0x60, 0x5f, 0x22, 0x90, 0x95, 0x65, 0xfe, 0xa8, 0x15, 0xaf, 0x08, 0xb5, 0xa7,
|
|
||||||
0x06, 0xd9, 0xe2, 0x80, 0xe2, 0x2b, 0x97, 0x85, 0x05, 0xb2, 0xdd, 0x74, 0x32, 0x89, 0x46, 0x5c,
|
|
||||||
0x3e, 0x2c, 0x52, 0x04, 0x93, 0xe8, 0x88, 0x78, 0xee, 0x8b, 0xb8, 0xc3, 0x2b, 0x01, 0xd4, 0x0e,
|
|
||||||
0xc8, 0x78, 0xf0, 0x48, 0x00, 0x4b, 0xe3, 0xa1, 0x19, 0x4c, 0x81, 0x57, 0xaa, 0x0a, 0x18, 0x06,
|
|
||||||
0x76, 0x6a, 0x61, 0x72, 0xcb, 0x8a, 0x22, 0x40, 0xca, 0x99, 0x85, 0x40, 0xa8, 0x64, 0xac, 0xc0,
|
|
||||||
0x64, 0x14, 0x0b, 0xb7, 0x9c, 0x1d, 0x00, 0x7d, 0xcc, 0xb6, 0xf2, 0xf1, 0xcb, 0xd3, 0xa6, 0x61,
|
|
||||||
0x71, 0x95, 0x8b, 0x98, 0x21, 0x80, 0x21, 0xc0, 0xaf, 0x62, 0x14, 0xc5, 0x1f, 0x6f, 0xa1, 0x03,
|
|
||||||
0xc0, 0x14, 0x29, 0x13, 0x91, 0xdb, 0x1f, 0x30, 0x65, 0x28, 0xda, 0xd0, 0x2e, 0xc9, 0x5f, 0x64,
|
|
||||||
0x8d, 0x64, 0x7d, 0x3d, 0xf4, 0xbb, 0x82, 0xbd, 0x42, 0x61, 0x01, 0x0b, 0x01, 0x09, 0x61, 0x37,
|
|
||||||
0x70, 0x1d, 0x2a, 0xae, 0xa9, 0xe8, 0x32, 0xac, 0xb9, 0x4c, 0x26, 0xf9, 0x0c, 0xc4, 0x17, 0x69,
|
|
||||||
0xe6, 0xc8, 0x2c, 0x8d, 0x30, 0x06, 0x1d, 0xf0, 0x13, 0x95, 0x4a, 0xb8, 0x5a, 0xb4, 0x42, 0x77,
|
|
||||||
0x15, 0x5c, 0xc0, 0xab, 0xb9, 0x13, 0xb4, 0x40, 0xf7, 0x51, 0xec, 0x1f, 0x87, 0x5e, 0xa4, 0xcf,
|
|
||||||
0x46, 0x48, 0x1d, 0x5a, 0xa8, 0xdd, 0x2a, 0x15, 0xf6, 0x44, 0x94, 0x6e, 0x02, 0x96, 0x98, 0x2f,
|
|
||||||
0xd6, 0xc1, 0x37, 0xa3, 0xc9, 0x04, 0xe6, 0xd3, 0x3d, 0x76, 0x33, 0xe8, 0xa7, 0x58, 0x83, 0x88,
|
|
||||||
0x82, 0x2a, 0x20, 0xf9, 0xa8, 0x2f, 0x92, 0x1d, 0x23, 0xc3, 0x51, 0x2f, 0x03, 0xf5, 0x3b, 0x12,
|
|
||||||
0xd7, 0xe4, 0xc6, 0x2a, 0x3e, 0x4a, 0x8d, 0x4d, 0x5a, 0x76, 0x77, 0x85, 0xe1, 0xf4, 0x9a, 0xfd,
|
|
||||||
0x3d, 0x6b, 0xd0, 0xea, 0xcf, 0x57, 0xdd, 0x57, 0xbc, 0x3a, 0xb9, 0x92, 0xef, 0xdd, 0xd2, 0xf0,
|
|
||||||
0x56, 0x42, 0x09, 0x9a, 0xe4, 0x1a, 0xcc, 0x6c, 0xcd, 0xe5, 0xfe, 0x0a, 0x22, 0x25, 0xab, 0x9f,
|
|
||||||
0x2b, 0x4a, 0xb3, 0x1c, 0x50, 0x5e, 0x87, 0xe4, 0x55, 0x09, 0xe4, 0x94, 0x1b, 0x51, 0x8b, 0xc7,
|
|
||||||
0x0c, 0x4a, 0x14, 0x75, 0x31, 0x37, 0x20, 0x02, 0x2b, 0x52, 0x24, 0xba, 0xc3, 0x1c, 0xbc, 0x6c,
|
|
||||||
0x45, 0x7a, 0x10, 0xbf, 0x29, 0x97, 0x9a, 0x33, 0x61, 0xaa, 0x89, 0xc8, 0x0b, 0x08, 0x69, 0x0b,
|
|
||||||
0x7a, 0x1b, 0xb8, 0x9d, 0xc2, 0x0c, 0x0b, 0x4f, 0x60, 0x56, 0x90, 0x31, 0x4f, 0x70, 0x11, 0x81,
|
|
||||||
0x3d, 0x66, 0x56, 0x70, 0x26, 0xcd, 0x44, 0x59, 0x38, 0x7a, 0xa6, 0x4f, 0x9d, 0xa0, 0x72, 0x0d,
|
|
||||||
0x46, 0x2e, 0xb1, 0x96, 0x24, 0xb6, 0x8d, 0x5e, 0x90, 0x9d, 0x5e, 0x3d, 0x5c, 0x81, 0xab, 0xf5,
|
|
||||||
0x7c, 0x61, 0x57, 0x83, 0x38, 0x86, 0xd0, 0x00, 0x16, 0xe6, 0x93, 0x27, 0xf4, 0x0c, 0x30, 0x84,
|
|
||||||
0x84, 0x87, 0x5c, 0x98, 0x8c, 0xd9, 0xb7, 0x7d, 0xab, 0x11, 0x1d, 0x0a, 0x30, 0x83, 0x96, 0x95,
|
|
||||||
0x61, 0x73, 0xa4, 0xcf, 0xa6, 0x35, 0xa9, 0x15, 0x6c, 0xb9, 0x6f, 0xc9, 0xb2, 0x28, 0x53, 0xd5,
|
|
||||||
0xc3, 0x0a, 0x26, 0x4f, 0x40, 0xc3, 0x53, 0xc1, 0x44, 0xdc, 0x8d, 0xb3, 0xa6, 0xdf, 0x09, 0x90,
|
|
||||||
0xed, 0x46, 0x59, 0xd4, 0x25, 0xb0, 0x2c, 0xee, 0xc1, 0xb2, 0xb9, 0x1f, 0x64, 0x02, 0x15, 0x34,
|
|
||||||
0x06, 0x4f, 0x2c, 0x5e, 0x16, 0x4b, 0xca, 0x74, 0x29, 0x6b, 0xfc, 0xe0, 0x1d, 0x83, 0xf3, 0x15,
|
|
||||||
0xac, 0x89, 0x2d, 0x13, 0x22, 0x53, 0x5d, 0x19, 0x72, 0x1e, 0xce, 0x46, 0x85, 0x80, 0x80, 0xac,
|
|
||||||
0x87, 0x6c, 0x90, 0xf5, 0x4e, 0x59, 0x8d, 0x42, 0x5d, 0xcd, 0x83, 0x0d, 0x6d, 0x65, 0x3d, 0x01,
|
|
||||||
0xbc, 0xa8, 0x1d, 0x18, 0xeb, 0x0b, 0x63, 0x7d, 0x41, 0xd6, 0x07, 0xbf, 0x53, 0x96, 0x3b, 0xe3,
|
|
||||||
0xbc, 0xf8, 0x8f, 0x23, 0x80, 0xb2, 0x1d, 0x03, 0x94, 0xed, 0x32, 0x40, 0xd9, 0x8d, 0x71, 0xcf,
|
|
||||||
0xf1, 0xaa, 0x8d, 0x00, 0xc4, 0x31, 0x0b, 0xbf, 0x0e, 0xc9, 0xee, 0xc6, 0xd9, 0xf0, 0x15, 0xe8,
|
|
||||||
0x6a, 0x6f, 0xed, 0x76, 0xf0, 0x1e, 0x95, 0x0a, 0x55, 0xd0, 0xf4, 0xb1, 0x83, 0x1e, 0x3a, 0xd5,
|
|
||||||
0x43, 0xee, 0x73, 0x2d, 0x4a, 0x09, 0xa8, 0x87, 0xc1, 0x99, 0x22, 0x3a, 0x55, 0x44, 0x3e, 0x57,
|
|
||||||
0xc4, 0x4a, 0xf3, 0x46, 0xb7, 0x5a, 0x6a, 0x62, 0xed, 0x54, 0xf7, 0x9c, 0x6a, 0x62, 0x18, 0x9a,
|
|
||||||
0x83, 0x2a, 0x3a, 0x55, 0xc5, 0x42, 0x35, 0xd1, 0x99, 0x26, 0x16, 0xa6, 0x89, 0xd4, 0xad, 0xac,
|
|
||||||
0xcb, 0xed, 0xa1, 0x5b, 0x78, 0x36, 0x4a, 0x97, 0x5b, 0x57, 0x98, 0xeb, 0xbd, 0x26, 0x36, 0xe5,
|
|
||||||
0xfb, 0x73, 0x3e, 0x6c, 0x6e, 0xdf, 0xaf, 0x47, 0x7e, 0x14, 0xdc, 0xb0, 0xb2, 0xfd, 0x75, 0x05,
|
|
||||||
0xcc, 0x75, 0x3f, 0x2b, 0x5a, 0xae, 0x67, 0xc0, 0x50, 0x42, 0xe9, 0x3e, 0x69, 0x55, 0x03, 0x22,
|
|
||||||
0x34, 0x05, 0x2f, 0xf7, 0x17, 0xf6, 0x4a, 0xa0, 0x9a, 0x23, 0x42, 0x43, 0xbb, 0xdb, 0x0f, 0xc9,
|
|
||||||
0xdd, 0x0f, 0xe1, 0xf6, 0xab, 0x20, 0xdc, 0xda, 0x4d, 0x41, 0x9e, 0xfd, 0xe9, 0x01, 0xf0, 0x72,
|
|
||||||
0x5a, 0x93, 0x3d, 0x23, 0x32, 0xc7, 0xb3, 0xbe, 0x1c, 0xb8, 0x06, 0x11, 0xfc, 0x76, 0xd8, 0x74,
|
|
||||||
0x11, 0xa5, 0x5d, 0x04, 0x69, 0x4f, 0x45, 0x52, 0xf0, 0x3d, 0x9a, 0x9a, 0x43, 0x49, 0x8c, 0x73,
|
|
||||||
0xca, 0x23, 0xa8, 0xf1, 0x90, 0x30, 0x18, 0x17, 0xb1, 0x4c, 0xad, 0xe9, 0x49, 0xed, 0x3c, 0x91,
|
|
||||||
0xfa, 0x28, 0x66, 0x9a, 0x84, 0xc2, 0x1a, 0x1a, 0x4c, 0x3b, 0x56, 0x56, 0xce, 0xa0, 0xc7, 0xdc,
|
|
||||||
0x1d, 0xeb, 0xe6, 0x98, 0xc2, 0x14, 0xeb, 0xcd, 0x27, 0x11, 0xd6, 0xb8, 0xa3, 0x6d, 0xaa, 0x87,
|
|
||||||
0x47, 0xad, 0x2c, 0x5f, 0x52, 0x8c, 0xf2, 0x25, 0xc5, 0x38, 0x5f, 0xb2, 0x1a, 0x25, 0xbd, 0xbc,
|
|
||||||
0xfe, 0xeb, 0xea, 0x9f, 0x82, 0xa4, 0x49, 0x42, 0x4e, 0x3c, 0x08, 0x98, 0x67, 0x29, 0x88, 0x59,
|
|
||||||
0x1d, 0xff, 0x4c, 0x76, 0x72, 0x5f, 0x4c, 0x35, 0x61, 0xae, 0x32, 0x4b, 0xaa, 0x74, 0x50, 0x35,
|
|
||||||
0x03, 0x47, 0x27, 0x10, 0x6b, 0x9e, 0x41, 0xac, 0x61, 0x06, 0xb1, 0x86, 0x29, 0xc4, 0x5a, 0xcf,
|
|
||||||
0x20, 0xd6, 0x30, 0x83, 0x58, 0xd3, 0xd1, 0xff, 0xa7, 0x10, 0x6b, 0x33, 0x85, 0x58, 0xf7, 0xa9,
|
|
||||||
0x0a, 0x24, 0x67, 0x45, 0x9a, 0x99, 0xca, 0x13, 0xdd, 0x9f, 0x3c, 0xce, 0x72, 0x0c, 0x84, 0xf6,
|
|
||||||
0x4b, 0xf8, 0x67, 0x37, 0x3c, 0x09, 0xb3, 0x88, 0x83, 0xf6, 0x8b, 0xea, 0x71, 0xb2, 0xa0, 0xab,
|
|
||||||
0xac, 0xb9, 0x21, 0xe5, 0x8a, 0x45, 0x62, 0x47, 0x19, 0x08, 0x95, 0xeb, 0x78, 0x3a, 0xb1, 0x35,
|
|
||||||
0xd2, 0x8a, 0x05, 0x04, 0xf5, 0x08, 0xc8, 0xfc, 0xb4, 0x07, 0x48, 0x87, 0xe7, 0xa0, 0x8f, 0x9e,
|
|
||||||
0x94, 0xd4, 0x47, 0x13, 0x47, 0xb0, 0xe9, 0xe8, 0x01, 0xc5, 0x4f, 0x13, 0x80, 0xd4, 0xb3, 0x64,
|
|
||||||
0x89, 0xf4, 0xd7, 0xa0, 0xb9, 0xe3, 0x1c, 0x84, 0x21, 0xa3, 0x84, 0x49, 0x8b, 0x31, 0x4c, 0xda,
|
|
||||||
0xdb, 0x06, 0x5d, 0x99, 0xae, 0x70, 0xbf, 0xe1, 0x19, 0xe5, 0x8d, 0x3b, 0xf0, 0x06, 0xee, 0x85,
|
|
||||||
0x33, 0x74, 0xd4, 0x53, 0x0f, 0x3d, 0x9e, 0xa2, 0x3d, 0xa9, 0x5a, 0x3f, 0xe9, 0x43, 0xe8, 0x0f,
|
|
||||||
0xf8, 0x48, 0xfa, 0x83, 0xcb, 0x77, 0x9f, 0xa0, 0x65, 0x77, 0xaf, 0x1e, 0xd9, 0x63, 0xf2, 0x78,
|
|
||||||
0x35, 0x10, 0x5e, 0xa6, 0x65, 0x4f, 0xc6, 0xe3, 0xdc, 0x9b, 0x57, 0xee, 0xfa, 0xaa, 0xdb, 0xbd,
|
|
||||||
0xeb, 0xde, 0xff, 0xc2, 0x57, 0xba, 0x3e, 0x7c, 0xf0, 0xb1, 0xdf, 0xba, 0xbf, 0xf1, 0xb3, 0x62,
|
|
||||||
0x3f, 0xf3, 0x07, 0xc3, 0xfe, 0x63, 0xfe, 0xbc, 0xba, 0xf4, 0x27, 0x97, 0x3c, 0x7c, 0x60, 0x8f,
|
|
||||||
0xbd, 0x1b, 0xa1, 0x0f, 0x97, 0x63, 0x42, 0x7c, 0x15, 0xea, 0x69, 0x52, 0x78, 0x18, 0xf7, 0x34,
|
|
||||||
0x89, 0x9b, 0xfe, 0x40, 0xe2, 0xf1, 0xff, 0xfc, 0x10, 0x16, 0x08, 0xb0, 0xfe, 0xed, 0x34, 0x85,
|
|
||||||
0xd7, 0x7f, 0x4f, 0x28, 0x54, 0x0b, 0x14, 0x50, 0x0e, 0x73, 0x9a, 0xc0, 0xd5, 0x6e, 0x42, 0xa0,
|
|
||||||
0x5e, 0x20, 0x80, 0x07, 0xf1, 0x16, 0x08, 0xf4, 0x63, 0x36, 0x3c, 0x5b, 0x62, 0x02, 0x42, 0x9c,
|
|
||||||
0xd3, 0x04, 0xfa, 0xbb, 0x31, 0x81, 0x8b, 0x25, 0x02, 0xdd, 0xf5, 0x9b, 0xc9, 0xfd, 0xb2, 0xf2,
|
|
||||||
0xef, 0x3e, 0xed, 0x57, 0xbc, 0xbb, 0x1c, 0x56, 0x7c, 0x78, 0x7d, 0xda, 0xc3, 0x07, 0x78, 0xe5,
|
|
||||||
0x0f, 0x79, 0x24, 0xc7, 0xff, 0xeb, 0xf4, 0x67, 0xe5, 0x1e, 0xbf, 0x96, 0x8e, 0x5f, 0xdd, 0xee,
|
|
||||||
0xef, 0xeb, 0x77, 0xbf, 0xda, 0x7d, 0x3d, 0xa4, 0x89, 0x6f, 0x8b, 0x70, 0x87, 0xb7, 0x45, 0x38,
|
|
||||||
0xfe, 0x32, 0xdc, 0x2f, 0x8f, 0x98, 0xd2, 0xba, 0xda, 0xf6, 0xfd, 0x70, 0xf1, 0x65, 0xaf, 0xf4,
|
|
||||||
0x2e, 0x7e, 0xb5, 0x37, 0xd9, 0x95, 0xee, 0xc3, 0xbb, 0x2b, 0x7c, 0x6e, 0xfe, 0xc6, 0x0b, 0xf7,
|
|
||||||
0x5d, 0x7f, 0xb7, 0xbd, 0xf9, 0xc5, 0x63, 0x62, 0xfa, 0x1b, 0x59, 0x78, 0xe5, 0xfc, 0x6c, 0xcc,
|
|
||||||
0x78, 0xab, 0xf9, 0x68, 0x20, 0xcf, 0x57, 0x0c, 0xe4, 0x5f, 0xcf, 0xb7, 0x97, 0x8e, 0xbf, 0x72,
|
|
||||||
0xf1, 0xaf, 0xa3, 0x91, 0x3c, 0xff, 0x8e, 0x91, 0xec, 0x7e, 0x5b, 0xd3, 0xf9, 0x6f, 0x78, 0xc1,
|
|
||||||
0xd7, 0x52, 0xf7, 0xbf, 0x7d, 0x4f, 0xf7, 0x8f, 0xd6, 0x74, 0xff, 0x48, 0xc8, 0x2f, 0xf5, 0xfe,
|
|
||||||
0xe8, 0x1b, 0x7a, 0x9f, 0x8e, 0xe1, 0x6d, 0x3f, 0x1a, 0xcf, 0xef, 0x2b, 0xc6, 0xf3, 0xbb, 0x8c,
|
|
||||||
0x66, 0x3e, 0x8c, 0xdf, 0x4f, 0x0c, 0xc3, 0xeb, 0x20, 0xca, 0xb3, 0x32, 0xc4, 0xd1, 0x40, 0xec,
|
|
||||||
0x87, 0x1d, 0x8e, 0x58, 0x71, 0xb1, 0xa2, 0xeb, 0x8b, 0xcd, 0xdd, 0xc7, 0xdb, 0x0d, 0xdf, 0xa3,
|
|
||||||
0x38, 0x1f, 0xc1, 0xc5, 0x37, 0x8f, 0x60, 0x36, 0x8e, 0x3f, 0xd7, 0x2c, 0xc9, 0x9f, 0x78, 0x0f,
|
|
||||||
0xda, 0xd2, 0x9a, 0xfc, 0xf9, 0xed, 0x12, 0x71, 0xb7, 0x7b, 0x39, 0x32, 0xe0, 0x62, 0xdf, 0xff,
|
|
||||||
0xeb, 0xf5, 0xeb, 0x6d, 0x77, 0xe7, 0xce, 0x37, 0x57, 0xdb, 0x1d, 0xf5, 0x57, 0xfe, 0x0e, 0x46,
|
|
||||||
0xf0, 0xc3, 0xed, 0xde, 0x82, 0xf0, 0x25, 0xda, 0x45, 0xdb, 0x2e, 0x59, 0x11, 0x54, 0x08, 0x2d,
|
|
||||||
0x98, 0xd2, 0xeb, 0x39, 0x15, 0xbf, 0x40, 0xe4, 0xa8, 0x86, 0x64, 0x81, 0xe0, 0x87, 0xd7, 0x53,
|
|
||||||
0x82, 0xf7, 0xd3, 0x1b, 0xa7, 0xcd, 0x97, 0x46, 0x38, 0x23, 0xb8, 0x38, 0x4d, 0x4d, 0x14, 0x4e,
|
|
||||||
0xed, 0xe5, 0x81, 0x6b, 0x7c, 0x1d, 0x97, 0x2e, 0xd2, 0x8b, 0x97, 0xa3, 0x75, 0x78, 0x89, 0x75,
|
|
||||||
0xb0, 0x77, 0x6e, 0x8e, 0x5f, 0x2d, 0x63, 0xff, 0xc2, 0x26, 0xcb, 0x5b, 0x0f, 0xb4, 0x2e, 0xb6,
|
|
||||||
0x77, 0xae, 0xdf, 0x76, 0xd7, 0x57, 0x97, 0x9b, 0xdb, 0xcf, 0x4e, 0x7f, 0xad, 0xf3, 0xee, 0x5a,
|
|
||||||
0x2c, 0x2c, 0xdf, 0x50, 0xa6, 0x02, 0x63, 0xdf, 0xf7, 0x9b, 0xcc, 0xc5, 0x0f, 0xe5, 0xbf, 0x1f,
|
|
||||||
0x52, 0x70, 0x1e, 0xfc, 0xa4, 0xe7, 0x1e, 0x7e, 0xed, 0x06, 0x61, 0xdc, 0x23, 0xbc, 0xcc, 0x6e,
|
|
||||||
0xf5, 0x0d, 0xb2, 0x93, 0x3e, 0xe7, 0x2f, 0x1c, 0xae, 0xbe, 0x43, 0x76, 0xce, 0xf3, 0xdb, 0x77,
|
|
||||||
0x12, 0xbf, 0x7e, 0x5e, 0x7d, 0x8b, 0xec, 0x95, 0x17, 0x7f, 0x6d, 0x6e, 0xdc, 0xf9, 0x4f, 0x17,
|
|
||||||
0x87, 0x7b, 0x84, 0x01, 0x5f, 0xb9, 0x2d, 0xca, 0x6d, 0xc2, 0x36, 0xeb, 0x0d, 0xec, 0x9a, 0x0d,
|
|
||||||
0x75, 0x50, 0x82, 0xd7, 0x37, 0x2f, 0x75, 0xb3, 0x7a, 0xb2, 0xe9, 0xef, 0xf0, 0x6b, 0xa5, 0xe7,
|
|
||||||
0x9b, 0xdd, 0xf6, 0x4e, 0xd8, 0x76, 0x72, 0x25, 0x9f, 0x9c, 0x8f, 0x56, 0xf2, 0x7c, 0xf5, 0x4a,
|
|
||||||
0xce, 0xb4, 0xfe, 0xe5, 0x1a, 0xad, 0x37, 0x65, 0xbc, 0xb8, 0xd9, 0x6e, 0x2f, 0x8f, 0xd5, 0xfe,
|
|
||||||
0xe5, 0x5a, 0xb5, 0x7f, 0x79, 0xc2, 0xfa, 0xfd, 0xf1, 0x0f, 0xfa, 0xc7, 0xaf, 0x6a, 0x5e, 0xf5,
|
|
||||||
0xef, 0xee, 0x3e, 0x1f, 0x8d, 0xe1, 0x8f, 0x6f, 0x19, 0xc3, 0xcc, 0x00, 0x9d, 0x4f, 0x0d, 0xd0,
|
|
||||||
0x93, 0xcd, 0xa7, 0xeb, 0x5b, 0x18, 0xbb, 0xf3, 0xdb, 0x6d, 0xbf, 0xbd, 0xeb, 0x8f, 0x8c, 0xd0,
|
|
||||||
0x4d, 0xbf, 0xdb, 0xaf, 0x32, 0x5f, 0xe5, 0xce, 0xf7, 0x96, 0x2f, 0x99, 0xa1, 0x19, 0x58, 0xb2,
|
|
||||||
0xe4, 0x1e, 0xde, 0x8c, 0xf4, 0xdd, 0xde, 0x97, 0xff, 0xbd, 0x56, 0xe9, 0xa6, 0xbf, 0x3a, 0x26,
|
|
||||||
0xfa, 0xbd, 0x96, 0xe9, 0x46, 0x3c, 0xa3, 0xc9, 0xe4, 0xf9, 0x6b, 0x4f, 0xf7, 0xd1, 0x1c, 0x85,
|
|
||||||
0xbf, 0x33, 0x92, 0x60, 0xac, 0xae, 0x3c, 0x09, 0xff, 0x61, 0xe2, 0xfd, 0xc4, 0x8d, 0x5e, 0xd1,
|
|
||||||
0x67, 0xcb, 0xeb, 0xb9, 0xbc, 0xde, 0x96, 0xd7, 0x56, 0xf7, 0x60, 0x9d, 0x1e, 0x63, 0x3c, 0x6e,
|
|
||||||
0xcf, 0x6b, 0xa8, 0xda, 0xe6, 0xe6, 0x66, 0xf7, 0x79, 0x22, 0x59, 0x3c, 0x2d, 0xfe, 0xa2, 0xb3,
|
|
||||||
0x17, 0x40, 0x9b, 0x9f, 0xf8, 0xf8, 0xa1, 0x9a, 0xb3, 0x1f, 0x57, 0x5c, 0xfc, 0x44, 0x2e, 0xde,
|
|
||||||
0x52, 0x26, 0x7b, 0x27, 0xaa, 0x7c, 0xfa, 0x0e, 0x5e, 0xf9, 0x48, 0xae, 0x7c, 0xb5, 0x77, 0x26,
|
|
||||||
0xcf, 0x0e, 0x23, 0xfd, 0x0c, 0x18, 0xe0, 0xee, 0xed, 0xed, 0xf5, 0xc7, 0x37, 0x6f, 0xdd, 0x8d,
|
|
||||||
0x8a, 0x98, 0x3b, 0xb0, 0xa1, 0xfb, 0xec, 0x95, 0xc0, 0xb9, 0x5f, 0xcd, 0x06, 0x1a, 0xe2, 0x11,
|
|
||||||
0x85, 0x60, 0x14, 0xc2, 0x09, 0x0a, 0xf1, 0x24, 0x85, 0x1f, 0xdd, 0xfb, 0xed, 0xf6, 0xc6, 0x6d,
|
|
||||||
0x37, 0xdd, 0x5b, 0x87, 0xdd, 0x71, 0x4c, 0xed, 0x85, 0x51, 0x7b, 0x71, 0x6a, 0x3c, 0x21, 0xaa,
|
|
||||||
0xe2, 0x45, 0xd5, 0xbc, 0x14, 0x11, 0xec, 0x19, 0xd1, 0x0f, 0xfd, 0xcf, 0xf7, 0x30, 0xe8, 0xf1,
|
|
||||||
0xff, 0xee, 0xe5, 0x88, 0x2f, 0xeb, 0x1e, 0x6d, 0x5b, 0xf7, 0x58, 0xd5, 0xe7, 0x72, 0xe1, 0xaf,
|
|
||||||
0x5c, 0xd9, 0x57, 0xd7, 0xd7, 0x77, 0xf8, 0xbd, 0xe8, 0xd7, 0xef, 0xde, 0x1c, 0xec, 0x29, 0x48,
|
|
||||||
0xcc, 0xb4, 0xfb, 0xd9, 0x54, 0xbb, 0xf1, 0xeb, 0xba, 0x97, 0xee, 0xbf, 0xb1, 0x30, 0x47, 0x8a,
|
|
||||||
0x7d, 0x35, 0x89, 0x4f, 0xf0, 0xce, 0xff, 0x7f, 0x18, 0x31, 0xee, 0x29, 0xfe, 0x76, 0xbb, 0xb9,
|
|
||||||
0xfc, 0xb8, 0xd9, 0xc9, 0x30, 0x2f, 0xdf, 0x7d, 0x70, 0xd0, 0x80, 0x15, 0xc2, 0xf5, 0xec, 0xb1,
|
|
||||||
0xde, 0xec, 0x7b, 0xd9, 0x6a, 0xf9, 0x8e, 0x45, 0x47, 0xe1, 0xb8, 0x1c, 0x3c, 0xc0, 0x1f, 0x10,
|
|
||||||
0xe2, 0x47, 0x61, 0xf7, 0xbf, 0x7f, 0x74, 0x41, 0xa4, 0x8f, 0x67, 0x25, 0xde, 0x7b, 0x23, 0x9b,
|
|
||||||
0xcc, 0x58, 0xd6, 0xf6, 0x36, 0xf6, 0xd9, 0x0a, 0x1b, 0xfb, 0x9f, 0x4b, 0xfe, 0xe5, 0x33, 0x5b,
|
|
||||||
0xe3, 0x54, 0x4e, 0x44, 0xe6, 0xa0, 0x7c, 0x33, 0x83, 0xfe, 0x62, 0x8d, 0x41, 0x7f, 0xa1, 0xa3,
|
|
||||||
0x3d, 0x84, 0x59, 0xc7, 0xbb, 0xca, 0x8b, 0x7b, 0x2d, 0xfa, 0xc4, 0x86, 0xab, 0x09, 0xf9, 0x09,
|
|
||||||
0x61, 0xdf, 0xfe, 0x3f, 0xfa, 0x52, 0x5a, 0x0d, 0x37, 0x5f, 0x3b, 0xfc, 0x18, 0xc5, 0xe6, 0xd5,
|
|
||||||
0xf5, 0xc7, 0xbb, 0x9f, 0x5f, 0xed, 0x36, 0x57, 0xef, 0xe5, 0x2a, 0x3d, 0x2f, 0x5f, 0xf0, 0x56,
|
|
||||||
0x3e, 0xbc, 0xa2, 0x0f, 0x3f, 0x54, 0xfe, 0xff, 0x20, 0x24, 0xfe, 0x2a, 0xbe, 0x7c, 0x00, 0x00,
|
|
||||||
};
|
|
1223
wled00/html_mobile.h
1223
wled00/html_mobile.h
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
//USER HTML HERE (/u subpage)
|
//USER HTML HERE (/u subpage)
|
||||||
const char PAGE_usermod[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_usermod[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><body>No usermod installed or it doesn't specify a custom web page.</body></html>)=====";
|
<html><body>No usermod custom web page set.</body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
//server message
|
//server message
|
||||||
@ -12,25 +12,75 @@ const char PAGE_msg[] PROGMEM = R"=====(<!DOCTYPE html>
|
|||||||
<html><head><meta content='width=device-width' name='viewport'>
|
<html><head><meta content='width=device-width' name='viewport'>
|
||||||
<title>WLED Message</title>
|
<title>WLED Message</title>
|
||||||
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
|
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
|
||||||
%CSS%.bt{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%%;margin:0}</style></head>
|
<style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head>
|
||||||
<body><h2>%MSG%</body></html>)=====";
|
<body><h2>%MSG%</body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
//firmware update page
|
//firmware update page
|
||||||
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta content='width=device-width' name='viewport'><title>WLED Update</title><script>function B(){window.history.back()}</script>
|
<html><head><meta content='width=device-width' name='viewport'><title>WLED Update</title><script>function B(){window.history.back()}</script>
|
||||||
%CSS%.bt{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%%}</style></head>
|
<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.8.6<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>)=====";
|
<body><h2>WLED Software Update</h2>Installed version: 0.9.0-b1<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
//new user welcome page
|
//new user welcome page
|
||||||
#ifndef WLED_DISABLE_MOBILE_UI
|
|
||||||
const char PAGE_welcome[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset=utf-8><meta content='width=device-width' name=viewport><meta name=theme-color content=#333333><title>WLED Setup</title> <style>body{font-family:Verdana,Helvetica,sans-serif;text-align:center;background-color:#333;margin:0;color:#fff}button{outline:0;cursor:pointer}.btn{padding:8px;margin:10px;width:230px;text-transform:uppercase;font-family:helvetica;font-size:19px;background-color:#222;color:white;border:0 solid white;border-radius:5px}svg{fill:#fff}</style></head>
|
const char PAGE_welcome[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset=utf-8><meta content='width=device-width' name=viewport><meta name=theme-color content=#333333><title>WLED Setup</title> <style>body{font-family:Verdana,Helvetica,sans-serif;text-align:center;background-color:#333;margin:0;color:#fff}button{outline:0;cursor:pointer}.btn{padding:8px;margin:10px;width:230px;text-transform:uppercase;font-family:helvetica;font-size:19px;background-color:#222;color:white;border:0 solid white;border-radius:5px}svg{fill:#fff}</style></head>
|
||||||
<body> <svg style=position:absolute;width:0;height:0;overflow:hidden version=1.1 xmlns=http://www.w3.org/2000/svg> <defs> <symbol id=lnr-smile viewBox="0 0 1024 1024"><path d="M486.4 1024c-129.922 0-252.067-50.594-343.936-142.464s-142.464-214.014-142.464-343.936c0-129.923 50.595-252.067 142.464-343.936s214.013-142.464 343.936-142.464c129.922 0 252.067 50.595 343.936 142.464s142.464 214.014 142.464 343.936-50.594 252.067-142.464 343.936c-91.869 91.87-214.014 142.464-343.936 142.464zM486.4 102.4c-239.97 0-435.2 195.23-435.2 435.2s195.23 435.2 435.2 435.2 435.2-195.23 435.2-435.2-195.23-435.2-435.2-435.2z"></path><path d="M332.8 409.6c-42.347 0-76.8-34.453-76.8-76.8s34.453-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.453 76.8-76.8 76.8zM332.8 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M640 409.6c-42.349 0-76.8-34.453-76.8-76.8s34.451-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.451 76.8-76.8 76.8zM640 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M486.4 870.4c-183.506 0-332.8-149.294-332.8-332.8 0-14.139 11.462-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 155.275 126.325 281.6 281.6 281.6s281.6-126.325 281.6-281.6c0-14.139 11.461-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 183.506-149.294 332.8-332.8 332.8z"></path></symbol> </defs></svg> <br><br>
|
<body> <svg style=position:absolute;width:0;height:0;overflow:hidden version=1.1 xmlns=http://www.w3.org/2000/svg> <defs> <symbol id=lnr-smile viewBox="0 0 1024 1024"><path d="M486.4 1024c-129.922 0-252.067-50.594-343.936-142.464s-142.464-214.014-142.464-343.936c0-129.923 50.595-252.067 142.464-343.936s214.013-142.464 343.936-142.464c129.922 0 252.067 50.595 343.936 142.464s142.464 214.014 142.464 343.936-50.594 252.067-142.464 343.936c-91.869 91.87-214.014 142.464-343.936 142.464zM486.4 102.4c-239.97 0-435.2 195.23-435.2 435.2s195.23 435.2 435.2 435.2 435.2-195.23 435.2-435.2-195.23-435.2-435.2-435.2z"></path><path d="M332.8 409.6c-42.347 0-76.8-34.453-76.8-76.8s34.453-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.453 76.8-76.8 76.8zM332.8 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M640 409.6c-42.349 0-76.8-34.453-76.8-76.8s34.451-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.451 76.8-76.8 76.8zM640 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M486.4 870.4c-183.506 0-332.8-149.294-332.8-332.8 0-14.139 11.462-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 155.275 126.325 281.6 281.6 281.6s281.6-126.325 281.6-281.6c0-14.139 11.461-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 183.506-149.294 332.8-332.8 332.8z"></path></symbol> </defs></svg> <br><br>
|
||||||
<svg><use xlink:href=#lnr-smile></use></svg><h1>Welcome to WLED!</h1><h3>Thank you for installing my application!</h3> If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br> <b>Next steps:</b><br><br> Connect the module to your local WiFi here!<br> <button class=btn onclick="window.location.href='/settings/wifi'">WiFi settings</button><br> <i>Just trying this out in AP mode?</i><br> <button class=btn onclick="window.location.href='/sliders'">To the controls!</button></body></html>)=====";
|
<svg><use xlink:href=#lnr-smile></use></svg><h1>Welcome to WLED!</h1><h3>Thank you for installing my application!</h3> If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br> <b>Next steps:</b><br><br> Connect the module to your local WiFi here!<br> <button class=btn onclick="window.location.href='/settings/wifi'">WiFi settings</button><br> <i>Just trying this out in AP mode?</i><br> <button class=btn onclick="window.location.href='/sliders'">To the controls!</button></body></html>)=====";
|
||||||
#else
|
|
||||||
const char PAGE_welcome[] PROGMEM = "";
|
|
||||||
#endif
|
//liveview
|
||||||
|
const char PAGE_liveview[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
|
<html><head>
|
||||||
|
<meta name=viewport content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||||
|
<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();
|
||||||
|
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>)=====";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//common CSS of settings pages
|
//common CSS of settings pages
|
||||||
const char PAGE_settingsCss[] PROGMEM = R"=====(body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:4em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}td{padding:2px;}</style>)=====";
|
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}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:0.5ch solid #333}td{padding:2px;}</style>)=====";
|
||||||
|
|
||||||
|
|
||||||
//settings menu
|
//settings menu
|
||||||
const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><title>WLED Settings</title>%CSS%body{text-align:center;background:var(--cCol);height:100%%;margin:0;background-attachment:fixed}html{--h:11.55vh}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),Helvetica,sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:8vmin;height:var(--h);width:95%%;margin-top:2.4vh}</style>
|
<html><head><title>WLED Settings</title><style>body{text-align:center;background:#222;height:100%;margin:0}html{--h:11.55vh}button{background:#333;color:#fff;font-family:Verdana,Helvetica,sans-serif;border:.3ch solid #333;display:inline-block;font-size:8vmin;height:var(--h);width:95%;margin-top:2.4vh}</style>
|
||||||
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script></head>
|
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script></head>
|
||||||
<body onload=BB()>
|
<body onload=BB()>
|
||||||
<form action=/><button type=submit id=b>Back</button></form>
|
<form action=/><button type=submit id=b>Back</button></form>
|
||||||
@ -23,7 +23,7 @@ const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html>
|
|||||||
|
|
||||||
//wifi settings
|
//wifi settings
|
||||||
const char PAGE_settings_wifi[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_wifi[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta name="viewport" content="width=500">
|
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8">
|
||||||
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d=document;
|
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d=document;
|
||||||
%CSS%%SCSS%</head><body onload="GetV()">
|
%CSS%%SCSS%</head><body onload="GetV()">
|
||||||
<form id="form_s" name="Sf" method="post">
|
<form id="form_s" name="Sf" method="post">
|
||||||
@ -71,97 +71,95 @@ AP IP: <span class="sip"> Not active </span><hr>
|
|||||||
|
|
||||||
//LED settings
|
//LED settings
|
||||||
const char PAGE_settings_leds[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_leds[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta name="viewport" content="width=500">
|
<html><head>
|
||||||
<title>LED Settings</title><script>var f=0,p=0;function H()
|
<meta charset=utf-8>
|
||||||
{window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}
|
<meta name=viewport content="width=500">
|
||||||
function B(){window.open("/settings","_self");}function S(){GetV();setTimeout(function(){fillfx(0);},200);setTimeout(function(){fillfx(1);},400);UI();}
|
<title>LED Settings</title>
|
||||||
function UI(){var myC=document.querySelectorAll('.wc'),l=myC.length;for(i=0;i<l;i++){myC[i].style.display=(document.getElementById('rgbw').checked)?'inline':'none';}
|
<script>var d=document,laprev=55;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings")}function B(){window.open("/settings","_self")}function S(){GetV();setABL()}function enABL(){var a=d.getElementById("able").checked;d.Sf.LA.value=(a)?laprev:0;d.getElementById("abl").style.display=(a)?"inline":"none";d.getElementById("psu2").style.display=(a)?"inline":"none";if(d.Sf.LA.value>0){setABL()}}function enLA(){var a=d.Sf.LAsel.value;d.Sf.LA.value=a;d.getElementById("LAdis").style.display=(a==50)?"inline":"none";UI()}function setABL(){d.getElementById("able").checked=true;d.Sf.LAsel.value=50;switch(parseInt(d.Sf.LA.value)){case 0:d.getElementById("able").checked=false;enABL();break;case 30:d.Sf.LAsel.value=30;break;case 35:d.Sf.LAsel.value=35;break;case 55:d.Sf.LAsel.value=55;break;default:d.getElementById("LAdis").style.display="inline"}UI()}function UI(){var b=d.querySelectorAll(".wc"),a=b.length;for(i=0;i<a;i++){b[i].style.display=(d.getElementById("rgbw").checked)?"inline":"none"}d.getElementById("ledwarning").style.display=(d.Sf.LC.value>1000)?"inline":"none";d.getElementById("ampwarning").style.display=(d.Sf.MA.value>7200)?"inline":"none";if(d.Sf.LA.value>0){laprev=d.Sf.LA.value}var j=Math.ceil((100+d.Sf.LC.value*laprev)/500)/2;j=(j>5)?Math.ceil(j):j;var g="";var e=(d.Sf.LAsel.value==30);if(j<1.02&&!e){g="ESP 5V pin with 1A USB supply"}else{g+=e?"12V ":"5V ";g+=j;g+="A supply connected to LEDs"}var h=Math.ceil((100+d.Sf.LC.value*laprev)/1500)/2;h=(h>5)?Math.ceil(h):h;var c="(for most effects, ~";c+=h;c+="A is enough)<br>";d.getElementById("psu").innerHTML=g;d.getElementById("psu2").innerHTML=c}function GetV(){var d=document;
|
||||||
var val=Math.ceil((100+document.Sf.LC.value*55)/500)/2;val=(val>5)?Math.ceil(val):val;var s="";if(val<1.02){s="ESP 5V pin with 1A USB supply";}else{s="External 5V ";s+=val;s+="A supply connected to LEDs";}document.getElementById('psu').innerHTML=s;}
|
%CSS%%SCSS%</head><body onload=S()>
|
||||||
function fillfx(pl){e="<option>Error loading list!</option>";el=pl?Sf.FP:Sf.FX;fetch(pl?'/json/pal':'/json/eff').then(res=>{if(!res.ok){el.innerHTML=e;}
|
<form id=form_s name=Sf method=post>
|
||||||
return res.json();}).then(json=>{var x="";for(i in json){x+="<option value=\""+i+"\">"+json[i]+" ("+i+")</option>";}
|
<div class=helpB><button type=button onclick=H()>?</button></div>
|
||||||
el.innerHTML=x;el.selectedIndex=pl?p:f;}).catch(function(){el.innerHTML=e;})}function GetV(){var d=document;%CSS%%SCSS%</head>
|
<button type=button onclick=B()>Back</button><button type=submit>Save</button><hr>
|
||||||
<body onload="S()">
|
|
||||||
<form id="form_s" name="Sf" method="post">
|
|
||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
|
||||||
<h2>LED setup</h2>
|
<h2>LED setup</h2>
|
||||||
LED count: <input name="LC" type="number" min="1" max="1500" oninput=UI() required><br>
|
LED count: <input name=LC type=number min=1 max=1500 oninput=UI() required><br>
|
||||||
|
<div id=ledwarning style=color:orange;display:none>
|
||||||
|
⚠ You might run into stability or lag issues.<br>
|
||||||
|
Use less than 1000 LEDs per ESP for the best experience!<br>
|
||||||
|
</div>
|
||||||
<i>Recommended power supply for brightest white:</i><br>
|
<i>Recommended power supply for brightest white:</i><br>
|
||||||
<b><span id="psu">?</span></b><br><br>
|
<b><span id=psu>?</span></b><br>
|
||||||
Maximum Current: <input name="MA" type="number" min="250" max="65000" required> mA<br>
|
<span id=psu2><br></span>
|
||||||
|
<br>
|
||||||
|
Enable automatic brightness limiter: <input type=checkbox name=ABen onchange=enABL() id=able><br>
|
||||||
|
<div id=abl>
|
||||||
|
Maximum Current: <input name=MA type=number min=250 max=65000 oninput=UI() required> mA<br>
|
||||||
|
<div id=ampwarning style=color:orange;display:none>
|
||||||
|
⚠ Your power supply provides high current.<br>
|
||||||
|
To improve the safety of your setup,<br>
|
||||||
|
please use thick cables,<br>
|
||||||
|
multiple power injection points and a fuse!<br>
|
||||||
|
</div>
|
||||||
<i>Automatically limits brightness to stay close to the limit.<br>
|
<i>Automatically limits brightness to stay close to the limit.<br>
|
||||||
Keep at <1A if powering LEDs directly from the ESP 5V pin!<br>
|
Keep at <1A if powering LEDs directly from the ESP 5V pin!<br>
|
||||||
If you are using an external 5V supply, enter its rating.<br>
|
If you are using an external power supply, enter its rating.<br>
|
||||||
"65000" completely diasbles the power calculation.<br>
|
(Current estimated usage: <span class=pow>unknown</span>)</i><br><br>
|
||||||
(Current estimated usage: <span class="pow">unknown</span>)</i><br><br>
|
LED voltage (Max. current for a single LED):<br>
|
||||||
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW" onchange=UI() id="rgbw"><br>
|
<select name=LAsel onchange=enLA()>
|
||||||
Color order:
|
<option value=55 selected>5V default (55mA)</option>
|
||||||
<select name="CO">
|
<option value=35>5V efficient (35mA)</option>
|
||||||
<option value="0">GRB</option>
|
<option value=30>12V (30mA)</option>
|
||||||
<option value="1">RGB</option>
|
<option value=50>Custom</option>
|
||||||
<option value="2">BRG</option>
|
|
||||||
<option value="3">RBG</option></select>
|
|
||||||
<h3>Defaults</h3>
|
|
||||||
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>
|
|
||||||
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br><br>
|
|
||||||
Set current color, brightness and effects as boot default: <input type="checkbox" name="IS"><br>
|
|
||||||
Set current preset cycle setting as boot default: <input type="checkbox" name="PC">
|
|
||||||
<br>- <i>or</i> -<br>
|
|
||||||
Apply preset <input name="BP" type="number" min="0" max="25" required> at boot (0 uses defaults)
|
|
||||||
<br>- <i>or</i> -<br>
|
|
||||||
Default RGB<span class="wc">W</span> color:<br>
|
|
||||||
<input name="CR" type="number" min="0" max="255" required>
|
|
||||||
<input name="CG" type="number" min="0" max="255" required>
|
|
||||||
<input name="CB" type="number" min="0" max="255" required>
|
|
||||||
<span class="wc"><input name="CW" type="number" min="0" max="255" required><br>
|
|
||||||
Auto-calculate white from RGB instead: <input type="checkbox" name="AW"></span><br>
|
|
||||||
Default secondary RGB<span class="wc">W</span>:<br>
|
|
||||||
<input name="SR" type="number" min="0" max="255" required>
|
|
||||||
<input name="SG" type="number" min="0" max="255" required>
|
|
||||||
<input name="SB" type="number" min="0" max="255" required>
|
|
||||||
<span class="wc"><input name="SW" type="number" min="0" max="255" required></span><br>
|
|
||||||
Default effect ID:<br>
|
|
||||||
<select name="FX">
|
|
||||||
<option>Loading...</option>
|
|
||||||
</select>
|
|
||||||
<br>Default color palette:<br>
|
|
||||||
<select name="FP">
|
|
||||||
<option>Loading...</option>
|
|
||||||
</select><br>
|
</select><br>
|
||||||
Default effect speed: <input name="SX" type="number" min="0" max="255" required><br>
|
<span id=LAdis style=display:none>Custom max. current per LED: <input name=LA type=number min=0 max=255 id=la oninput=UI() required> mA<br></span>
|
||||||
Default effect intensity: <input name="IX" type="number" min="0" max="255" required><br><br>
|
<i>Keep at default if you are unsure about your type of LEDs.</i><br>
|
||||||
Use Gamma correction for color: <input type="checkbox" name="GC"> (strongly recommended)<br>
|
</div>
|
||||||
Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br><br>
|
<br>
|
||||||
Brightness factor: <input name="BF" type="number" min="0" max="255" required> %%
|
LEDs are 4-channel type (RGBW): <input type=checkbox name=EW onchange=UI() id=rgbw><br>
|
||||||
|
<span class=wc>
|
||||||
|
Auto-calculate white channel from RGB: <input type=checkbox name=AW><br></span>
|
||||||
|
Color order:
|
||||||
|
<select name=CO>
|
||||||
|
<option value=0>GRB</option>
|
||||||
|
<option value=1>RGB</option>
|
||||||
|
<option value=2>BRG</option>
|
||||||
|
<option value=3>RBG</option>
|
||||||
|
</select>
|
||||||
|
<h3>Defaults</h3>
|
||||||
|
Turn LEDs on after power up/reset: <input type=checkbox name=BO><br>
|
||||||
|
Default brightness: <input name=CA type=number min=0 max=255 required> (0-255)<br><br>
|
||||||
|
Apply preset <input name=BP type=number min=0 max=16 required> at boot (0 uses defaults)
|
||||||
|
<br>- <i>or</i> -<br>
|
||||||
|
Set current preset cycle setting as boot default: <input type=checkbox name=PC><br><br>
|
||||||
|
Use Gamma correction for color: <input type=checkbox name=GC> (strongly recommended)<br>
|
||||||
|
Use Gamma correction for brightness: <input type=checkbox name=GB> (not recommended)<br><br>
|
||||||
|
Brightness factor: <input name=BF type=number min=1 max=255 required> %
|
||||||
<h3>Transitions</h3>
|
<h3>Transitions</h3>
|
||||||
Crossfade: <input type="checkbox" name="TF"><br>
|
Crossfade: <input type=checkbox name=TF><br>
|
||||||
Transition Time: <input name="TD" maxlength="5" size="2"> ms<br>
|
Transition Time: <input name=TD maxlength=5 size=2> ms<br>
|
||||||
Enable transition for secondary color: <input type="checkbox" name="T2"><br>
|
Enable Palette transitions: <input type=checkbox name=PF>
|
||||||
Enable Palette transitions: <input type="checkbox" name="PF">
|
|
||||||
<h3>Timed light</h3>
|
<h3>Timed light</h3>
|
||||||
Default Duration: <input name="TL" type="number" min="1" max="255" required> min<br>
|
Default Duration: <input name=TL type=number min=1 max=255 required> min<br>
|
||||||
Default Target brightness: <input name="TB" type="number" min="0" max="255" required><br>
|
Default Target brightness: <input name=TB type=number min=0 max=255 required><br>
|
||||||
Fade down: <input type="checkbox" name="TW"><br>
|
Fade down: <input type=checkbox name=TW><br>
|
||||||
<h3>Advanced</h3>
|
<h3>Advanced</h3>
|
||||||
Palette blending:
|
Palette blending:
|
||||||
<select name="PB">
|
<select name=PB>
|
||||||
<option value="0">Linear (wrap if moving)</option>
|
<option value=0>Linear (wrap if moving)</option>
|
||||||
<option value="1">Linear (always wrap)</option>
|
<option value=1>Linear (always wrap)</option>
|
||||||
<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>
|
||||||
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
|
Reverse LED order (rotate 180): <input type=checkbox name=RV><br>
|
||||||
Skip first LED: <input type="checkbox" name="SL"><hr>
|
Skip first LED: <input type=checkbox name=SL><br>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
Disable repeating N LEDs: <input type=number min=0 max=255 name=DL><br>
|
||||||
</form>
|
(Turns off N LEDs between each lit one, spacing out effects)<hr>
|
||||||
</body>
|
<button type=button onclick=B()>Back</button><button type=submit>Save</button>
|
||||||
</html>)=====";
|
</form></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
//User Interface settings
|
//User Interface settings
|
||||||
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta name="viewport" content="width=500">
|
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>UI Settings</title><script>
|
||||||
<title>UI Settings</title><script>
|
|
||||||
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d=document;
|
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d=document;
|
||||||
%CSS%%SCSS%</head>
|
%CSS%%SCSS%</head>
|
||||||
<body onload="S()">
|
<body onload="S()">
|
||||||
@ -169,44 +167,8 @@ function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}fun
|
|||||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||||
<h2>Web Setup</h2>
|
<h2>Web Setup</h2>
|
||||||
User Interface Mode:
|
Server description: <input name="DS" maxlength="32"><br>
|
||||||
<select name="UI">
|
Sync button toggles both send and receive: <input type="checkbox" name="ST"><br><br>
|
||||||
<option value="0" selected>Auto</option>
|
|
||||||
<option value="1">Classic</option>
|
|
||||||
<option value="2">Mobile</option>
|
|
||||||
</select><br>
|
|
||||||
Server description: <input name="DS" maxlength="32"><br><br>
|
|
||||||
<i>The following options are for the classic UI!</i><br>
|
|
||||||
Use HSB sliders instead of RGB by default: <input type="checkbox" name="MD"><br>
|
|
||||||
Color Theme:
|
|
||||||
<select name="TH" onchange="Ct()">
|
|
||||||
<option value="0" selected>Night</option>
|
|
||||||
<option value="1">Modern</option>
|
|
||||||
<option value="2">Bright</option>
|
|
||||||
<option value="3">Wine</option>
|
|
||||||
<option value="4">Electric</option>
|
|
||||||
<option value="5">Mint</option>
|
|
||||||
<option value="6">Amber</option>
|
|
||||||
<option value="7">Dark</option>
|
|
||||||
<option value="8">Air</option>
|
|
||||||
<option value="9">Nixie</option>
|
|
||||||
<option value="10">Terminal</option>
|
|
||||||
<option value="11">C64</option>
|
|
||||||
<option value="12">Easter</option>
|
|
||||||
<option value="13">Christmas</option>
|
|
||||||
<option value="14">The End</option>
|
|
||||||
<option value="15" id="co">Custom</option>
|
|
||||||
</select><br>
|
|
||||||
<div id="cth">
|
|
||||||
Please specify your custom hex colors (e.g. FF0000 for red)<br>
|
|
||||||
Custom accent color: <input maxlength=9 name="C0"><br>
|
|
||||||
Custom background: <input maxlength=9 name="C1"><br>
|
|
||||||
Custom panel color: <input maxlength=9 name="C2"><br>
|
|
||||||
Custom icon color: <input maxlength=9 name="C3"><br>
|
|
||||||
Custom shadow: <input maxlength=9 name="C4"><br>
|
|
||||||
Custom text color: <input maxlength=9 name="C5"><br></div>
|
|
||||||
Use font: <input maxlength=32 name="CF"><br>
|
|
||||||
Make sure the font you use is installed on your system!<br>
|
|
||||||
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
@ -215,7 +177,7 @@ Make sure the font you use is installed on your system!<br>
|
|||||||
|
|
||||||
//sync settings
|
//sync settings
|
||||||
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta name="viewport" content="width=500"><title>Sync Settings</title>
|
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title>
|
||||||
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d=document;
|
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d=document;
|
||||||
%CSS%%SCSS%</head>
|
%CSS%%SCSS%</head>
|
||||||
<body onload="GetV()">
|
<body onload="GetV()">
|
||||||
@ -257,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>
|
Device Auth token: <input name="BK" maxlength="33"><br>
|
||||||
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
||||||
<h3>MQTT</h3>
|
<h3>MQTT</h3>
|
||||||
|
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||||
Broker: <input name="MS" maxlength="32">
|
Broker: <input name="MS" maxlength="32">
|
||||||
Port: <input name="MQPORT" type="number" min="1" max="65535" required><br>
|
Port: <input name="MQPORT" type="number" min="1" max="65535" required><br>
|
||||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||||
@ -287,7 +250,7 @@ Hue status: <span class="hms"> Internal ESP Error! </span><hr>
|
|||||||
|
|
||||||
//time and macro settings
|
//time and macro settings
|
||||||
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta name="viewport" content="width=500"><title>Time Settings</title>
|
<html><head><meta name="viewport" content="width=500"><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(s){return d.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}
|
<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(s){return d.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}
|
||||||
function BTa(){var ih="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Macro</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++){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=\"16\"></td>";for (j=1;j<8;j++) ih+="<td><input id=\"W"+i+j+"\" type=\"checkbox\"></td>";}gId("TMT").innerHTML=ih;}
|
function BTa(){var ih="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Macro</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++){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=\"16\"></td>";for (j=1;j<8;j++) ih+="<td><input id=\"W"+i+j+"\" type=\"checkbox\"></td>";}gId("TMT").innerHTML=ih;}
|
||||||
function FC(){for(j=0;j<8;j++){for(i=0;i<8;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1;}}
|
function FC(){for(j=0;j<8;j++){for(i=0;i<8;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1;}}
|
||||||
@ -299,6 +262,7 @@ function Wd(){a=[0,0,0,0,0,0,0,0];for(i=0;i<8;i++){m=1;for(j=0;j<8;j++){a[i]+=gI
|
|||||||
<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>
|
||||||
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">
|
||||||
@ -325,7 +289,7 @@ Clock Overlay:
|
|||||||
<select name="OL" onchange="Cs()">
|
<select name="OL" onchange="Cs()">
|
||||||
<option value="0" id="cn" selected>None</option>
|
<option value="0" id="cn" selected>None</option>
|
||||||
<option value="1" id="ca">Analog Clock</option>
|
<option value="1" id="ca">Analog Clock</option>
|
||||||
<option value="2">Single Digit Clock</option>
|
<option value="2" disabled>-</option>
|
||||||
<option value="3" id="cc">Cronixie Clock</option>
|
<option value="3" id="cc">Cronixie Clock</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<div id="coc">
|
<div id="coc">
|
||||||
@ -380,7 +344,7 @@ Time-Controlled macros:<br>
|
|||||||
|
|
||||||
//security settings and about
|
//security settings and about
|
||||||
const char PAGE_settings_sec[] PROGMEM = R"=====(<!DOCTYPE html>
|
const char PAGE_settings_sec[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||||
<html><head><meta name="viewport" content="width=500">
|
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8">
|
||||||
<title>Misc Settings</title>
|
<title>Misc Settings</title>
|
||||||
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d=document;
|
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d=document;
|
||||||
%CSS%%SCSS%</head>
|
%CSS%%SCSS%</head>
|
||||||
@ -403,7 +367,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
|
|||||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||||
<h3>About</h3>
|
<h3>About</h3>
|
||||||
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.6<br><br>
|
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.9.0-b1<br><br>
|
||||||
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||||
(c) 2016-2019 Christian Schwinne <br>
|
(c) 2016-2019 Christian Schwinne <br>
|
||||||
|
1459
wled00/html_ui.h
Normal file
1459
wled00/html_ui.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -564,6 +564,14 @@ DEFINE_GRADIENT_PALETTE( Sakura_gp ) {
|
|||||||
130, 223, 45, 72,
|
130, 223, 45, 72,
|
||||||
195, 255, 82,103,
|
195, 255, 82,103,
|
||||||
255, 223, 13, 17};
|
255, 223, 13, 17};
|
||||||
|
|
||||||
|
DEFINE_GRADIENT_PALETTE( Aurora_gp ) {
|
||||||
|
0, 1, 5, 45, //deep blue
|
||||||
|
64, 0,200, 23,
|
||||||
|
128, 0,255, 0, //green
|
||||||
|
170, 0,243, 45,
|
||||||
|
200, 0,135, 7,
|
||||||
|
255, 1, 5, 45};//deep blue
|
||||||
|
|
||||||
|
|
||||||
// Single array of defined cpt-city color palettes.
|
// Single array of defined cpt-city color palettes.
|
||||||
@ -614,6 +622,7 @@ const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
|
|||||||
Orangery_gp, //47-34 Orangery
|
Orangery_gp, //47-34 Orangery
|
||||||
C9_gp, //48-35 C9
|
C9_gp, //48-35 C9
|
||||||
Sakura_gp, //49-36 Sakura
|
Sakura_gp, //49-36 Sakura
|
||||||
|
Aurora_gp, //50-37 Aurora
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* E131.cpp
|
|
||||||
*
|
|
||||||
* Project: E131 - E.131 (sACN) library for Arduino
|
|
||||||
* Copyright (c) 2015 Shelby Merrick
|
|
||||||
* http://www.forkineye.com
|
|
||||||
*
|
|
||||||
* This program is provided free for you to use in any way that you wish,
|
|
||||||
* subject to the laws and regulations where you are using it. Due diligence
|
|
||||||
* is strongly suggested before using this code. Please give credit where due.
|
|
||||||
*
|
|
||||||
* The Author makes no warranty of any kind, express or implied, with regard
|
|
||||||
* to this program or the documentation contained in this document. The
|
|
||||||
* Author shall not be liable in any event for incidental or consequential
|
|
||||||
* damages in connection with, or arising out of, the furnishing, performance
|
|
||||||
* or use of these programs.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "E131.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* E1.17 ACN Packet Identifier */
|
|
||||||
const byte E131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
/* Constructor */
|
|
||||||
E131::E131() {
|
|
||||||
#ifdef NO_DOUBLE_BUFFER
|
|
||||||
memset(pbuff1.raw, 0, sizeof(pbuff1.raw));
|
|
||||||
packet = &pbuff1;
|
|
||||||
pwbuff = packet;
|
|
||||||
#else
|
|
||||||
memset(pbuff1.raw, 0, sizeof(pbuff1.raw));
|
|
||||||
memset(pbuff2.raw, 0, sizeof(pbuff2.raw));
|
|
||||||
packet = &pbuff1;
|
|
||||||
pwbuff = &pbuff2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stats.num_packets = 0;
|
|
||||||
stats.packet_errors = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void E131::initUnicast() {
|
|
||||||
udp.begin(E131_DEFAULT_PORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void E131::initMulticast(uint16_t universe, uint8_t n) {
|
|
||||||
IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff),
|
|
||||||
((universe >> 0) & 0xff));
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
ip4_addr_t ifaddr;
|
|
||||||
ip4_addr_t multicast_addr;
|
|
||||||
|
|
||||||
ifaddr.addr = static_cast<uint32_t>(WiFi.localIP());
|
|
||||||
for (uint8_t i = 1; i < n; i++) {
|
|
||||||
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
|
|
||||||
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)
|
|
||||||
& 0xff)));
|
|
||||||
igmp_joingroup(&ifaddr, &multicast_addr);
|
|
||||||
}
|
|
||||||
udp.beginMulticast(address, E131_DEFAULT_PORT);
|
|
||||||
#else
|
|
||||||
ip_addr_t ifaddr;
|
|
||||||
ip_addr_t multicast_addr;
|
|
||||||
|
|
||||||
ifaddr.addr = static_cast<uint32_t>(WiFi.localIP());
|
|
||||||
for (uint8_t i = 1; i < n; i++) {
|
|
||||||
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
|
|
||||||
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)
|
|
||||||
& 0xff)));
|
|
||||||
igmp_joingroup(&ifaddr, &multicast_addr);
|
|
||||||
}
|
|
||||||
udp.beginMulticast(WiFi.localIP(), address, E131_DEFAULT_PORT);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void E131::begin(e131_listen_t type, uint16_t universe, uint8_t n) {
|
|
||||||
if (type == E131_UNICAST)
|
|
||||||
initUnicast();
|
|
||||||
if (type == E131_MULTICAST)
|
|
||||||
initMulticast(universe, n);
|
|
||||||
}
|
|
@ -1,196 +0,0 @@
|
|||||||
/*
|
|
||||||
* E131.h
|
|
||||||
*
|
|
||||||
* Project: E131 - E.131 (sACN) library for Arduino
|
|
||||||
* Copyright (c) 2015 Shelby Merrick
|
|
||||||
* http://www.forkineye.com
|
|
||||||
*
|
|
||||||
* This program is provided free for you to use in any way that you wish,
|
|
||||||
* subject to the laws and regulations where you are using it. Due diligence
|
|
||||||
* is strongly suggested before using this code. Please give credit where due.
|
|
||||||
*
|
|
||||||
* The Author makes no warranty of any kind, express or implied, with regard
|
|
||||||
* to this program or the documentation contained in this document. The
|
|
||||||
* Author shall not be liable in any event for incidental or consequential
|
|
||||||
* damages in connection with, or arising out of, the furnishing, performance
|
|
||||||
* or use of these programs.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef E131_H_
|
|
||||||
#define E131_H_
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
/* Network interface detection. WiFi for ESP8266 and Ethernet for AVR */
|
|
||||||
#if defined (ARDUINO_ARCH_ESP8266)
|
|
||||||
# include <ESP8266WiFi.h>
|
|
||||||
# define NO_DOUBLE_BUFFER
|
|
||||||
#elif defined (ARDUINO_ARCH_ESP32)
|
|
||||||
# include <WiFi.h>
|
|
||||||
#endif
|
|
||||||
# include <WiFiUdp.h>
|
|
||||||
# include <lwip/ip_addr.h>
|
|
||||||
# include <lwip/igmp.h>
|
|
||||||
# define _UDP WiFiUDP
|
|
||||||
|
|
||||||
/* Defaults */
|
|
||||||
#define E131_DEFAULT_PORT 5568
|
|
||||||
|
|
||||||
/* E1.31 Packet Offsets */
|
|
||||||
#define E131_ROOT_PREAMBLE_SIZE 0
|
|
||||||
#define E131_ROOT_POSTAMBLE_SIZE 2
|
|
||||||
#define E131_ROOT_ID 4
|
|
||||||
#define E131_ROOT_FLENGTH 16
|
|
||||||
#define E131_ROOT_VECTOR 18
|
|
||||||
#define E131_ROOT_CID 22
|
|
||||||
|
|
||||||
#define E131_FRAME_FLENGTH 38
|
|
||||||
#define E131_FRAME_VECTOR 40
|
|
||||||
#define E131_FRAME_SOURCE 44
|
|
||||||
#define E131_FRAME_PRIORITY 108
|
|
||||||
#define E131_FRAME_RESERVED 109
|
|
||||||
#define E131_FRAME_SEQ 111
|
|
||||||
#define E131_FRAME_OPT 112
|
|
||||||
#define E131_FRAME_UNIVERSE 113
|
|
||||||
|
|
||||||
#define E131_DMP_FLENGTH 115
|
|
||||||
#define E131_DMP_VECTOR 117
|
|
||||||
#define E131_DMP_TYPE 118
|
|
||||||
#define E131_DMP_ADDR_FIRST 119
|
|
||||||
#define E131_DMP_ADDR_INC 121
|
|
||||||
#define E131_DMP_COUNT 123
|
|
||||||
#define E131_DMP_DATA 125
|
|
||||||
|
|
||||||
/* E1.31 Packet Structure */
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/* Root Layer */
|
|
||||||
uint16_t preamble_size;
|
|
||||||
uint16_t postamble_size;
|
|
||||||
uint8_t acn_id[12];
|
|
||||||
uint16_t root_flength;
|
|
||||||
uint32_t root_vector;
|
|
||||||
uint8_t cid[16];
|
|
||||||
|
|
||||||
/* Frame Layer */
|
|
||||||
uint16_t frame_flength;
|
|
||||||
uint32_t frame_vector;
|
|
||||||
uint8_t source_name[64];
|
|
||||||
uint8_t priority;
|
|
||||||
uint16_t reserved;
|
|
||||||
uint8_t sequence_number;
|
|
||||||
uint8_t options;
|
|
||||||
uint16_t universe;
|
|
||||||
|
|
||||||
/* DMP Layer */
|
|
||||||
uint16_t dmp_flength;
|
|
||||||
uint8_t dmp_vector;
|
|
||||||
uint8_t type;
|
|
||||||
uint16_t first_address;
|
|
||||||
uint16_t address_increment;
|
|
||||||
uint16_t property_value_count;
|
|
||||||
uint8_t property_values[513];
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
uint8_t raw[638];
|
|
||||||
} e131_packet_t;
|
|
||||||
|
|
||||||
/* Error Types */
|
|
||||||
typedef enum {
|
|
||||||
ERROR_NONE,
|
|
||||||
ERROR_IGNORE,
|
|
||||||
ERROR_ACN_ID,
|
|
||||||
ERROR_PACKET_SIZE,
|
|
||||||
ERROR_VECTOR_ROOT,
|
|
||||||
ERROR_VECTOR_FRAME,
|
|
||||||
ERROR_VECTOR_DMP
|
|
||||||
} e131_error_t;
|
|
||||||
|
|
||||||
/* E1.31 Listener Types */
|
|
||||||
typedef enum {
|
|
||||||
E131_UNICAST,
|
|
||||||
E131_MULTICAST
|
|
||||||
} e131_listen_t;
|
|
||||||
|
|
||||||
/* Status structure */
|
|
||||||
typedef struct {
|
|
||||||
uint32_t num_packets;
|
|
||||||
uint32_t packet_errors;
|
|
||||||
IPAddress last_clientIP;
|
|
||||||
uint16_t last_clientPort;
|
|
||||||
} e131_stats_t;
|
|
||||||
|
|
||||||
class E131 {
|
|
||||||
private:
|
|
||||||
/* Constants for packet validation */
|
|
||||||
static const uint8_t ACN_ID[];
|
|
||||||
static const uint32_t VECTOR_ROOT = 4;
|
|
||||||
static const uint32_t VECTOR_FRAME = 2;
|
|
||||||
static const uint8_t VECTOR_DMP = 2;
|
|
||||||
|
|
||||||
e131_packet_t pbuff1; /* Packet buffer */
|
|
||||||
#ifndef NO_DOUBLE_BUFFER
|
|
||||||
e131_packet_t pbuff2; /* Double buffer */
|
|
||||||
#endif
|
|
||||||
e131_packet_t *pwbuff; /* Pointer to working packet buffer */
|
|
||||||
_UDP udp; /* UDP handle */
|
|
||||||
|
|
||||||
/* Internal Initializers */
|
|
||||||
void initUnicast();
|
|
||||||
void initMulticast(uint16_t universe, uint8_t n = 1);
|
|
||||||
|
|
||||||
public:
|
|
||||||
uint8_t *data; /* Pointer to DMX channel data */
|
|
||||||
uint16_t universe; /* DMX Universe of last valid packet */
|
|
||||||
e131_packet_t *packet; /* Pointer to last valid packet */
|
|
||||||
e131_stats_t stats; /* Statistics tracker */
|
|
||||||
|
|
||||||
E131();
|
|
||||||
|
|
||||||
/* Generic UDP listener, no physical or IP configuration */
|
|
||||||
void begin(e131_listen_t type, uint16_t universe = 1, uint8_t n = 1);
|
|
||||||
|
|
||||||
/* Main packet parser */
|
|
||||||
inline uint16_t parsePacket() {
|
|
||||||
e131_error_t error;
|
|
||||||
uint16_t retval = 0;
|
|
||||||
|
|
||||||
int size = udp.parsePacket();
|
|
||||||
if (size) {
|
|
||||||
udp.readBytes(pwbuff->raw, size);
|
|
||||||
error = validate();
|
|
||||||
if (!error) {
|
|
||||||
#ifndef NO_DOUBLE_BUFFER
|
|
||||||
e131_packet_t *swap = packet;
|
|
||||||
packet = pwbuff;
|
|
||||||
pwbuff = swap;
|
|
||||||
#endif
|
|
||||||
universe = htons(packet->universe);
|
|
||||||
data = packet->property_values + 1;
|
|
||||||
retval = htons(packet->property_value_count) - 1;
|
|
||||||
stats.num_packets++;
|
|
||||||
stats.last_clientIP = udp.remoteIP();
|
|
||||||
stats.last_clientPort = udp.remotePort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Packet validater */
|
|
||||||
inline e131_error_t validate() {
|
|
||||||
if (memcmp(pwbuff->acn_id, ACN_ID, sizeof(pwbuff->acn_id)))
|
|
||||||
return ERROR_ACN_ID;
|
|
||||||
if (htonl(pwbuff->root_vector) != VECTOR_ROOT)
|
|
||||||
return ERROR_VECTOR_ROOT;
|
|
||||||
if (htonl(pwbuff->frame_vector) != VECTOR_FRAME)
|
|
||||||
return ERROR_VECTOR_FRAME;
|
|
||||||
if (pwbuff->dmp_vector != VECTOR_DMP)
|
|
||||||
return ERROR_VECTOR_DMP;
|
|
||||||
if (pwbuff->property_values[0] != 0)
|
|
||||||
return ERROR_IGNORE;
|
|
||||||
return ERROR_NONE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* E131_H_ */
|
|
116
wled00/src/dependencies/e131/ESPAsyncE131.cpp
Normal file
116
wled00/src/dependencies/e131/ESPAsyncE131.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* ESPAsyncE131.cpp
|
||||||
|
*
|
||||||
|
* Project: ESPAsyncE131 - Asynchronous E.131 (sACN) library for Arduino ESP8266 and ESP32
|
||||||
|
* Copyright (c) 2019 Shelby Merrick
|
||||||
|
* http://www.forkineye.com
|
||||||
|
*
|
||||||
|
* This program is provided free for you to use in any way that you wish,
|
||||||
|
* subject to the laws and regulations where you are using it. Due diligence
|
||||||
|
* is strongly suggested before using this code. Please give credit where due.
|
||||||
|
*
|
||||||
|
* The Author makes no warranty of any kind, express or implied, with regard
|
||||||
|
* to this program or the documentation contained in this document. The
|
||||||
|
* Author shall not be liable in any event for incidental or consequential
|
||||||
|
* damages in connection with, or arising out of, the furnishing, performance
|
||||||
|
* or use of these programs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ESPAsyncE131.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// E1.17 ACN Packet Identifier
|
||||||
|
const byte ESPAsyncE131::ACN_ID[12] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
ESPAsyncE131::ESPAsyncE131(e131_packet_callback_function callback) {
|
||||||
|
_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Public begin() members
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool ESPAsyncE131::begin(e131_listen_t type, uint16_t universe, uint8_t n) {
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (type == E131_UNICAST)
|
||||||
|
success = initUnicast();
|
||||||
|
if (type == E131_MULTICAST)
|
||||||
|
success = initMulticast(universe, n);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Private init() members
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool ESPAsyncE131::initUnicast() {
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (udp.listen(E131_DEFAULT_PORT)) {
|
||||||
|
udp.onPacket(std::bind(&ESPAsyncE131::parsePacket, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESPAsyncE131::initMulticast(uint16_t universe, uint8_t n) {
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
IPAddress address = IPAddress(239, 255, ((universe >> 8) & 0xff),
|
||||||
|
((universe >> 0) & 0xff));
|
||||||
|
|
||||||
|
if (udp.listenMulticast(address, E131_DEFAULT_PORT)) {
|
||||||
|
ip4_addr_t ifaddr;
|
||||||
|
ip4_addr_t multicast_addr;
|
||||||
|
|
||||||
|
ifaddr.addr = static_cast<uint32_t>(WiFi.localIP());
|
||||||
|
for (uint8_t i = 1; i < n; i++) {
|
||||||
|
multicast_addr.addr = static_cast<uint32_t>(IPAddress(239, 255,
|
||||||
|
(((universe + i) >> 8) & 0xff), (((universe + i) >> 0)
|
||||||
|
& 0xff)));
|
||||||
|
igmp_joingroup(&ifaddr, &multicast_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
udp.onPacket(std::bind(&ESPAsyncE131::parsePacket, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Packet parsing - Private
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ESPAsyncE131::parsePacket(AsyncUDPPacket _packet) {
|
||||||
|
e131_error_t error = ERROR_NONE;
|
||||||
|
|
||||||
|
sbuff = reinterpret_cast<e131_packet_t *>(_packet.data());
|
||||||
|
if (memcmp(sbuff->acn_id, ESPAsyncE131::ACN_ID, sizeof(sbuff->acn_id)))
|
||||||
|
error = ERROR_ACN_ID;
|
||||||
|
if (htonl(sbuff->root_vector) != ESPAsyncE131::VECTOR_ROOT)
|
||||||
|
error = ERROR_VECTOR_ROOT;
|
||||||
|
if (htonl(sbuff->frame_vector) != ESPAsyncE131::VECTOR_FRAME)
|
||||||
|
error = ERROR_VECTOR_FRAME;
|
||||||
|
if (sbuff->dmp_vector != ESPAsyncE131::VECTOR_DMP)
|
||||||
|
error = ERROR_VECTOR_DMP;
|
||||||
|
if (sbuff->property_values[0] != 0)
|
||||||
|
error = ERROR_IGNORE;
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
_callback(sbuff, _packet.remoteIP());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
151
wled00/src/dependencies/e131/ESPAsyncE131.h
Normal file
151
wled00/src/dependencies/e131/ESPAsyncE131.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* ESPAsyncE131.h
|
||||||
|
*
|
||||||
|
* Project: ESPAsyncE131 - Asynchronous E.131 (sACN) library for Arduino ESP8266 and ESP32
|
||||||
|
* Copyright (c) 2019 Shelby Merrick
|
||||||
|
* http://www.forkineye.com
|
||||||
|
*
|
||||||
|
* This program is provided free for you to use in any way that you wish,
|
||||||
|
* subject to the laws and regulations where you are using it. Due diligence
|
||||||
|
* is strongly suggested before using this code. Please give credit where due.
|
||||||
|
*
|
||||||
|
* The Author makes no warranty of any kind, express or implied, with regard
|
||||||
|
* to this program or the documentation contained in this document. The
|
||||||
|
* Author shall not be liable in any event for incidental or consequential
|
||||||
|
* damages in connection with, or arising out of, the furnishing, performance
|
||||||
|
* or use of these programs.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESPASYNCE131_H_
|
||||||
|
#define ESPASYNCE131_H_
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <AsyncUDP.h>
|
||||||
|
#elif defined (ESP8266)
|
||||||
|
#include <ESPAsyncUDP.h>
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266WiFiMulti.h>
|
||||||
|
#else
|
||||||
|
#error Platform not supported
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
#include <lwip/igmp.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#if LWIP_VERSION_MAJOR == 1
|
||||||
|
typedef struct ip_addr ip4_addr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
#define E131_DEFAULT_PORT 5568
|
||||||
|
|
||||||
|
// E1.31 Packet Offsets
|
||||||
|
#define E131_ROOT_PREAMBLE_SIZE 0
|
||||||
|
#define E131_ROOT_POSTAMBLE_SIZE 2
|
||||||
|
#define E131_ROOT_ID 4
|
||||||
|
#define E131_ROOT_FLENGTH 16
|
||||||
|
#define E131_ROOT_VECTOR 18
|
||||||
|
#define E131_ROOT_CID 22
|
||||||
|
|
||||||
|
#define E131_FRAME_FLENGTH 38
|
||||||
|
#define E131_FRAME_VECTOR 40
|
||||||
|
#define E131_FRAME_SOURCE 44
|
||||||
|
#define E131_FRAME_PRIORITY 108
|
||||||
|
#define E131_FRAME_RESERVED 109
|
||||||
|
#define E131_FRAME_SEQ 111
|
||||||
|
#define E131_FRAME_OPT 112
|
||||||
|
#define E131_FRAME_UNIVERSE 113
|
||||||
|
|
||||||
|
#define E131_DMP_FLENGTH 115
|
||||||
|
#define E131_DMP_VECTOR 117
|
||||||
|
#define E131_DMP_TYPE 118
|
||||||
|
#define E131_DMP_ADDR_FIRST 119
|
||||||
|
#define E131_DMP_ADDR_INC 121
|
||||||
|
#define E131_DMP_COUNT 123
|
||||||
|
#define E131_DMP_DATA 125
|
||||||
|
|
||||||
|
// E1.31 Packet Structure
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
// Root Layer
|
||||||
|
uint16_t preamble_size;
|
||||||
|
uint16_t postamble_size;
|
||||||
|
uint8_t acn_id[12];
|
||||||
|
uint16_t root_flength;
|
||||||
|
uint32_t root_vector;
|
||||||
|
uint8_t cid[16];
|
||||||
|
|
||||||
|
// Frame Layer
|
||||||
|
uint16_t frame_flength;
|
||||||
|
uint32_t frame_vector;
|
||||||
|
uint8_t source_name[64];
|
||||||
|
uint8_t priority;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint8_t sequence_number;
|
||||||
|
uint8_t options;
|
||||||
|
uint16_t universe;
|
||||||
|
|
||||||
|
// DMP Layer
|
||||||
|
uint16_t dmp_flength;
|
||||||
|
uint8_t dmp_vector;
|
||||||
|
uint8_t type;
|
||||||
|
uint16_t first_address;
|
||||||
|
uint16_t address_increment;
|
||||||
|
uint16_t property_value_count;
|
||||||
|
uint8_t property_values[513];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
uint8_t raw[638];
|
||||||
|
} e131_packet_t;
|
||||||
|
|
||||||
|
// Error Types
|
||||||
|
typedef enum {
|
||||||
|
ERROR_NONE,
|
||||||
|
ERROR_IGNORE,
|
||||||
|
ERROR_ACN_ID,
|
||||||
|
ERROR_PACKET_SIZE,
|
||||||
|
ERROR_VECTOR_ROOT,
|
||||||
|
ERROR_VECTOR_FRAME,
|
||||||
|
ERROR_VECTOR_DMP
|
||||||
|
} e131_error_t;
|
||||||
|
|
||||||
|
// E1.31 Listener Types
|
||||||
|
typedef enum {
|
||||||
|
E131_UNICAST,
|
||||||
|
E131_MULTICAST
|
||||||
|
} e131_listen_t;
|
||||||
|
|
||||||
|
// new packet callback
|
||||||
|
typedef void (*e131_packet_callback_function) (e131_packet_t* p, IPAddress clientIP);
|
||||||
|
|
||||||
|
class ESPAsyncE131 {
|
||||||
|
private:
|
||||||
|
// Constants for packet validation
|
||||||
|
static const uint8_t ACN_ID[];
|
||||||
|
static const uint32_t VECTOR_ROOT = 4;
|
||||||
|
static const uint32_t VECTOR_FRAME = 2;
|
||||||
|
static const uint8_t VECTOR_DMP = 2;
|
||||||
|
|
||||||
|
e131_packet_t *sbuff; // Pointer to scratch packet buffer
|
||||||
|
AsyncUDP udp; // AsyncUDP
|
||||||
|
|
||||||
|
// Internal Initializers
|
||||||
|
bool initUnicast();
|
||||||
|
bool initMulticast(uint16_t universe, uint8_t n = 1);
|
||||||
|
|
||||||
|
// Packet parser callback
|
||||||
|
void parsePacket(AsyncUDPPacket _packet);
|
||||||
|
|
||||||
|
e131_packet_callback_function _callback = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ESPAsyncE131(e131_packet_callback_function callback);
|
||||||
|
|
||||||
|
// Generic UDP listener, no physical or IP configuration
|
||||||
|
bool begin(e131_listen_t type, uint16_t universe = 1, uint8_t n = 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ESPASYNCE131_H_
|
@ -443,7 +443,7 @@ public:
|
|||||||
if (req.indexOf("api") <0) return false; //return if not an API call
|
if (req.indexOf("api") <0) return false; //return if not an API call
|
||||||
EA_DEBUGLN("ok");
|
EA_DEBUGLN("ok");
|
||||||
|
|
||||||
if (body.indexOf("devicetype") > 0) //client wants a hue api username, we dont care and give static
|
if (body.indexOf("devicetype") > 0) //client wants a hue api username, we don't care and give static
|
||||||
{
|
{
|
||||||
EA_DEBUGLN("devType");
|
EA_DEBUGLN("devType");
|
||||||
body = "";
|
body = "";
|
||||||
@ -453,7 +453,7 @@ public:
|
|||||||
|
|
||||||
if (req.indexOf("state") > 0) //client wants to control light
|
if (req.indexOf("state") > 0) //client wants to control light
|
||||||
{
|
{
|
||||||
server->send(200, "application/json", "[{\"success\":true}]"); //short valid response
|
server->send(200, "application/json", "[{\"success\":{\"/lights/1/state/\": true}}]");
|
||||||
|
|
||||||
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
|
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
|
||||||
EA_DEBUG("ls"); EA_DEBUGLN(devId);
|
EA_DEBUG("ls"); EA_DEBUGLN(devId);
|
||||||
@ -550,7 +550,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//we dont care about other api commands at this time and send empty JSON
|
//we don't care about other api commands at this time and send empty JSON
|
||||||
server->send(200, "application/json", "{}");
|
server->send(200, "application/json", "{}");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -584,4 +584,4 @@ public:
|
|||||||
~Espalexa(){delete devices;} //note: Espalexa is NOT meant to be destructed
|
~Espalexa(){delete devices;} //note: Espalexa is NOT meant to be destructed
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -15,7 +15,7 @@
|
|||||||
#include "ArduinoJson-v6.h"
|
#include "ArduinoJson-v6.h"
|
||||||
#include <Print.h>
|
#include <Print.h>
|
||||||
|
|
||||||
#define DYNAMYC_JSON_DOCUMENT_SIZE 4096
|
#define DYNAMIC_JSON_DOCUMENT_SIZE 8192
|
||||||
|
|
||||||
constexpr const char* JSON_MIMETYPE = "application/json";
|
constexpr const char* JSON_MIMETYPE = "application/json";
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMYC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_contentType = JSON_MIMETYPE;
|
_contentType = JSON_MIMETYPE;
|
||||||
if(isArray)
|
if(isArray)
|
||||||
@ -90,7 +90,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<void(AsyncWebServerRequest *request, JsonObject json)> ArJsonRequestHandlerFunction;
|
typedef std::function<void(AsyncWebServerRequest *request)> ArJsonRequestHandlerFunction;
|
||||||
|
|
||||||
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
||||||
private:
|
private:
|
||||||
@ -103,7 +103,7 @@ protected:
|
|||||||
int _maxContentLength;
|
int _maxContentLength;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMYC_JSON_DOCUMENT_SIZE)
|
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE)
|
||||||
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
|
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {}
|
||||||
|
|
||||||
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
||||||
@ -127,15 +127,8 @@ public:
|
|||||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||||
if(_onRequest) {
|
if(_onRequest) {
|
||||||
if (request->_tempObject != NULL) {
|
if (request->_tempObject != NULL) {
|
||||||
|
_onRequest(request);
|
||||||
DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize);
|
return;
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
|
|
||||||
if(!error) {
|
|
||||||
JsonObject json = jsonBuffer.as<JsonObject>();
|
|
||||||
|
|
||||||
_onRequest(request, json);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
request->send(_contentLength > _maxContentLength ? 413 : 400);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
#include "TimeLib.h"
|
|
@ -12,7 +12,7 @@
|
|||||||
#include "Timezone.h"
|
#include "Timezone.h"
|
||||||
|
|
||||||
//THIS LINE WAS ADDED FOR COMPATIBILY WITH THE WLED DEPENDENCY STRUCTURE. REMOVE IF YOU USE IT OUTSIDE OF WLED!
|
//THIS LINE WAS ADDED FOR COMPATIBILY WITH THE WLED DEPENDENCY STRUCTURE. REMOVE IF YOU USE IT OUTSIDE OF WLED!
|
||||||
#include "../time/Time.h"
|
#include "../time/TimeLib.h"
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include <WProgram.h>
|
#include <WProgram.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../time/Time.h" //http://www.arduino.cc/playground/Code/Time
|
#include "../time/TimeLib.h" //http://www.arduino.cc/playground/Code/Time
|
||||||
|
|
||||||
//convenient constants for dstRules
|
//convenient constants for dstRules
|
||||||
enum week_t {Last, First, Second, Third, Fourth};
|
enum week_t {Last, First, Second, Third, Fourth};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
https://github.com/kitesurfer1404/WS2812FX/
|
https://github.com/kitesurfer1404/WS2812FX/
|
||||||
|
|
||||||
The WS2812FX implementation was heavily altered and differs from its master branch.
|
The WS2812FX implementation was heavily altered and differs from its master branch.
|
||||||
Due to regural changes to the library code it is kept in the source dir for now.
|
Due to regular changes to the library code it is kept in the source dir for now.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* @title WLED project sketch
|
* @title WLED project sketch
|
||||||
* @version 0.8.6
|
* @version 0.9.0-b1
|
||||||
* @author Christian Schwinne
|
* @author Christian Schwinne
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -14,16 +14,16 @@
|
|||||||
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
|
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
|
||||||
|
|
||||||
//You are required to disable over-the-air updates:
|
//You are required to disable over-the-air updates:
|
||||||
//#define WLED_DISABLE_OTA
|
//#define WLED_DISABLE_OTA //saves 14kb
|
||||||
|
|
||||||
//You need to choose 1-2 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_DISABLE_MOBILE_UI
|
|
||||||
|
|
||||||
|
//You need to choose some of these features to disable:
|
||||||
|
//#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_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet
|
||||||
//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version
|
//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version
|
||||||
@ -60,7 +60,6 @@
|
|||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
#endif
|
#endif
|
||||||
#include <SPIFFSEditor.h>
|
#include <SPIFFSEditor.h>
|
||||||
#include "src/dependencies/time/Time.h"
|
|
||||||
#include "src/dependencies/time/TimeLib.h"
|
#include "src/dependencies/time/TimeLib.h"
|
||||||
#include "src/dependencies/timezone/Timezone.h"
|
#include "src/dependencies/timezone/Timezone.h"
|
||||||
#ifndef WLED_DISABLE_ALEXA
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
@ -73,12 +72,11 @@
|
|||||||
#ifndef WLED_DISABLE_BLYNK
|
#ifndef WLED_DISABLE_BLYNK
|
||||||
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
|
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
|
||||||
#endif
|
#endif
|
||||||
#include "src/dependencies/e131/E131.h"
|
#include "src/dependencies/e131/ESPAsyncE131.h"
|
||||||
#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h"
|
#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h"
|
||||||
#include "src/dependencies/json/AsyncJson-v6.h"
|
#include "src/dependencies/json/AsyncJson-v6.h"
|
||||||
#include "src/dependencies/json/ArduinoJson-v6.h"
|
#include "src/dependencies/json/ArduinoJson-v6.h"
|
||||||
#include "html_classic.h"
|
#include "html_ui.h"
|
||||||
#include "html_mobile.h"
|
|
||||||
#include "html_settings.h"
|
#include "html_settings.h"
|
||||||
#include "html_other.h"
|
#include "html_other.h"
|
||||||
#include "FX.h"
|
#include "FX.h"
|
||||||
@ -106,8 +104,8 @@
|
|||||||
|
|
||||||
|
|
||||||
//version code in format yymmddb (b = daily build)
|
//version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 1911031
|
#define VERSION 1912182
|
||||||
char versionString[] = "0.8.6";
|
char versionString[] = "0.9.0-b1";
|
||||||
|
|
||||||
|
|
||||||
//AP and OTA default passwords (for maximum change them!)
|
//AP and OTA default passwords (for maximum change them!)
|
||||||
@ -120,7 +118,7 @@ char otaPass[33] = "wledota";
|
|||||||
|
|
||||||
byte auxDefaultState = 0; //0: input 1: high 2: low
|
byte auxDefaultState = 0; //0: input 1: high 2: low
|
||||||
byte auxTriggeredState = 0; //0: input 1: high 2: low
|
byte auxTriggeredState = 0; //0: input 1: high 2: low
|
||||||
char ntpServerName[] = "0.wled.pool.ntp.org"; //NTP server to use
|
char ntpServerName[33] = "0.wled.pool.ntp.org";//NTP server to use
|
||||||
|
|
||||||
|
|
||||||
//WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
//WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
||||||
@ -145,13 +143,9 @@ bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White
|
|||||||
bool turnOnAtBoot = true; //turn on LEDs at power-up
|
bool turnOnAtBoot = true; //turn on LEDs at power-up
|
||||||
byte bootPreset = 0; //save preset to load after power-up
|
byte bootPreset = 0; //save preset to load after power-up
|
||||||
|
|
||||||
byte colS[]{255, 159, 0, 0}; //default RGB(W) color
|
byte col[]{255, 160, 0, 0}; //default RGB(W) color
|
||||||
byte colSecS[]{0, 0, 0, 0}; //default RGB(W) secondary color
|
byte colSec[]{0, 0, 0, 0}; //default RGB(W) secondary color
|
||||||
byte briS = 127; //default brightness
|
byte briS = 128; //default brightness
|
||||||
byte effectDefault = 0;
|
|
||||||
byte effectSpeedDefault = 75;
|
|
||||||
byte effectIntensityDefault = 128; //intensity is supported on some effects as an additional parameter (e.g. for blink you can change the duty cycle)
|
|
||||||
byte effectPaletteDefault = 0; //palette is supported on the FastLED effects, otherwise it has no effect
|
|
||||||
|
|
||||||
byte nightlightTargetBri = 0; //brightness after nightlight is over
|
byte nightlightTargetBri = 0; //brightness after nightlight is over
|
||||||
byte nightlightDelayMins = 60;
|
byte nightlightDelayMins = 60;
|
||||||
@ -160,19 +154,14 @@ bool fadeTransition = true; //enable crossfading color transit
|
|||||||
bool enableSecTransition = true; //also enable transition for secondary color
|
bool enableSecTransition = true; //also enable transition for secondary color
|
||||||
uint16_t transitionDelay = 750; //default crossfade duration in ms
|
uint16_t transitionDelay = 750; //default crossfade duration in ms
|
||||||
|
|
||||||
//bool strip.reverseMode = false; //flip entire LED strip (reverses all effect directions) --> edit in WS2812FX.h
|
|
||||||
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
|
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
|
||||||
|
uint8_t 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)
|
byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)
|
||||||
|
|
||||||
|
|
||||||
//User Interface CONFIG
|
//User Interface CONFIG
|
||||||
char serverDescription[33] = "WLED"; //Name of module
|
char serverDescription[33] = "WLED"; //Name of module
|
||||||
byte currentTheme = 7; //UI theme index for settings and classic UI
|
bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise
|
||||||
byte uiConfiguration = 2; //0: automatic (depends on user-agent) 1: classic UI 2: mobile UI
|
|
||||||
bool useHSB = true; //classic UI: use HSB sliders instead of RGB by default
|
|
||||||
char cssFont[33] = "Verdana"; //font to use in classic UI
|
|
||||||
|
|
||||||
bool useHSBDefault = useHSB;
|
|
||||||
|
|
||||||
|
|
||||||
//Sync CONFIG
|
//Sync CONFIG
|
||||||
@ -203,10 +192,10 @@ bool receiveDirect = true; //receive UDP realtime
|
|||||||
bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source
|
bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source
|
||||||
bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black
|
bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black
|
||||||
|
|
||||||
bool e131Enabled = true; //settings for E1.31 (sACN) protocol
|
uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol
|
||||||
uint16_t e131Universe = 1;
|
|
||||||
bool e131Multicast = false;
|
bool e131Multicast = false;
|
||||||
|
|
||||||
|
bool mqttEnabled = false;
|
||||||
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
|
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
|
||||||
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
|
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
|
||||||
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
|
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
|
||||||
@ -242,7 +231,7 @@ char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled1
|
|||||||
bool cronixieBacklight = true; //Allow digits to be back-illuminated
|
bool cronixieBacklight = true; //Allow digits to be back-illuminated
|
||||||
|
|
||||||
bool countdownMode = false; //Clock will count down towards date
|
bool countdownMode = false; //Clock will count down towards date
|
||||||
byte countdownYear = 19, countdownMonth = 1; //Countdown target date, year is last two digits
|
byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits
|
||||||
byte countdownDay = 1, countdownHour = 0;
|
byte countdownDay = 1, countdownHour = 0;
|
||||||
byte countdownMin = 0, countdownSec = 0;
|
byte countdownMin = 0, countdownSec = 0;
|
||||||
|
|
||||||
@ -272,11 +261,9 @@ bool interfacesInited = false;
|
|||||||
bool wasConnected = false;
|
bool wasConnected = false;
|
||||||
|
|
||||||
//color
|
//color
|
||||||
byte col[]{255, 159, 0, 0}; //target RGB(W) color
|
|
||||||
byte colOld[]{0, 0, 0, 0}; //color before transition
|
byte colOld[]{0, 0, 0, 0}; //color before transition
|
||||||
byte colT[]{0, 0, 0, 0}; //current color
|
byte colT[]{0, 0, 0, 0}; //current color
|
||||||
byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs
|
byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs
|
||||||
byte colSec[]{0, 0, 0, 0};
|
|
||||||
byte colSecT[]{0, 0, 0, 0};
|
byte colSecT[]{0, 0, 0, 0};
|
||||||
byte colSecOld[]{0, 0, 0, 0};
|
byte colSecOld[]{0, 0, 0, 0};
|
||||||
byte colSecIT[]{0, 0, 0, 0};
|
byte colSecIT[]{0, 0, 0, 0};
|
||||||
@ -306,7 +293,7 @@ byte bri = briS;
|
|||||||
byte briOld = 0;
|
byte briOld = 0;
|
||||||
byte briT = 0;
|
byte briT = 0;
|
||||||
byte briIT = 0;
|
byte briIT = 0;
|
||||||
byte briLast = 127; //brightness before turned off. Used for toggle function
|
byte briLast = 128; //brightness before turned off. Used for toggle function
|
||||||
|
|
||||||
//button
|
//button
|
||||||
bool buttonPressedBefore = false;
|
bool buttonPressedBefore = false;
|
||||||
@ -322,16 +309,15 @@ byte notificationSentCallMode = 0;
|
|||||||
bool notificationTwoRequired = false;
|
bool notificationTwoRequired = false;
|
||||||
|
|
||||||
//effects
|
//effects
|
||||||
byte effectCurrent = effectDefault;
|
byte effectCurrent = 0;
|
||||||
byte effectSpeed = effectSpeedDefault;
|
byte effectSpeed = 128;
|
||||||
byte effectIntensity = effectIntensityDefault;
|
byte effectIntensity = 128;
|
||||||
byte effectPalette = effectPaletteDefault;
|
byte effectPalette = 0;
|
||||||
|
|
||||||
//network
|
//network
|
||||||
bool udpConnected = false, udpRgbConnected = false;
|
bool udpConnected = false, udpRgbConnected = false;
|
||||||
|
|
||||||
//ui style
|
//ui style
|
||||||
char cssCol[6][9]={"","","","","",""};
|
|
||||||
bool showWelcomePage = false;
|
bool showWelcomePage = false;
|
||||||
|
|
||||||
//hue
|
//hue
|
||||||
@ -350,11 +336,6 @@ byte overlayCurrent = overlayDefault;
|
|||||||
byte overlaySpeed = 200;
|
byte overlaySpeed = 200;
|
||||||
unsigned long overlayRefreshMs = 200;
|
unsigned long overlayRefreshMs = 200;
|
||||||
unsigned long overlayRefreshedTime;
|
unsigned long overlayRefreshedTime;
|
||||||
int overlayArr[6];
|
|
||||||
uint16_t overlayDur[6];
|
|
||||||
uint16_t overlayPauseDur[6];
|
|
||||||
int nixieClockI = -1;
|
|
||||||
bool nixiePause = false;
|
|
||||||
|
|
||||||
//cronixie
|
//cronixie
|
||||||
byte dP[]{0,0,0,0,0,0};
|
byte dP[]{0,0,0,0,0,0};
|
||||||
@ -392,6 +373,7 @@ unsigned long realtimeTimeout = 0;
|
|||||||
long lastMqttReconnectAttempt = 0;
|
long lastMqttReconnectAttempt = 0;
|
||||||
long lastInterfaceUpdate = 0;
|
long lastInterfaceUpdate = 0;
|
||||||
byte interfaceUpdateCallMode = 0;
|
byte interfaceUpdateCallMode = 0;
|
||||||
|
char mqttStatusTopic[40] = ""; //this must be global because of async handlers
|
||||||
|
|
||||||
#if AUXPIN >= 0
|
#if AUXPIN >= 0
|
||||||
//auxiliary debug pin
|
//auxiliary debug pin
|
||||||
@ -427,22 +409,35 @@ uint16_t ntpLocalPort = 2390;
|
|||||||
char* obuf;
|
char* obuf;
|
||||||
uint16_t olen = 0;
|
uint16_t olen = 0;
|
||||||
|
|
||||||
|
uint16_t savedPresets = 0;
|
||||||
|
int8_t currentPreset = -1;
|
||||||
|
bool isPreset = false;
|
||||||
|
|
||||||
|
byte errorFlag = 0;
|
||||||
|
|
||||||
String messageHead, messageSub;
|
String messageHead, messageSub;
|
||||||
byte optionType;
|
byte optionType;
|
||||||
|
|
||||||
bool doReboot = false; //flag to initiate reboot from async handlers
|
bool doReboot = false; //flag to initiate reboot from async handlers
|
||||||
bool doPublishMqtt = false;
|
bool doPublishMqtt = false;
|
||||||
bool doSendHADiscovery = true;
|
|
||||||
|
|
||||||
//server library objects
|
//server library objects
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
AsyncClient* hueClient = NULL;
|
AsyncClient* hueClient = NULL;
|
||||||
AsyncMqttClient* mqtt = NULL;
|
AsyncMqttClient* mqtt = NULL;
|
||||||
|
|
||||||
|
//function prototypes
|
||||||
|
void colorFromUint32(uint32_t,bool=false);
|
||||||
|
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);
|
||||||
|
void handleE131Packet(e131_packet_t*, IPAddress);
|
||||||
|
|
||||||
|
#define E131_MAX_UNIVERSE_COUNT 9
|
||||||
|
|
||||||
//udp interface objects
|
//udp interface objects
|
||||||
WiFiUDP notifierUdp, rgbUdp;
|
WiFiUDP notifierUdp, rgbUdp;
|
||||||
WiFiUDP ntpUdp;
|
WiFiUDP ntpUdp;
|
||||||
E131* e131;
|
ESPAsyncE131 e131(handleE131Packet);
|
||||||
|
bool e131NewData = false;
|
||||||
|
|
||||||
//led fx library object
|
//led fx library object
|
||||||
WS2812FX strip = WS2812FX();
|
WS2812FX strip = WS2812FX();
|
||||||
@ -474,11 +469,6 @@ WS2812FX strip = WS2812FX();
|
|||||||
#include "SPIFFSEditor.h"
|
#include "SPIFFSEditor.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//function prototypes
|
|
||||||
void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte);
|
|
||||||
|
|
||||||
|
|
||||||
//turns all LEDs off and restarts ESP
|
//turns all LEDs off and restarts ESP
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
@ -495,7 +485,7 @@ void reset()
|
|||||||
|
|
||||||
|
|
||||||
//append new c string to temp buffer efficiently
|
//append new c string to temp buffer efficiently
|
||||||
bool oappend(char* txt)
|
bool oappend(const char* txt)
|
||||||
{
|
{
|
||||||
uint16_t len = strlen(txt);
|
uint16_t len = strlen(txt);
|
||||||
if (olen + len >= OMAX) return false; //buffer full
|
if (olen + len >= OMAX) return false; //buffer full
|
||||||
@ -535,7 +525,6 @@ void loop() {
|
|||||||
handleAlexa();
|
handleAlexa();
|
||||||
|
|
||||||
handleOverlays();
|
handleOverlays();
|
||||||
if (doSendHADiscovery) sendHADiscoveryMQTT();
|
|
||||||
yield();
|
yield();
|
||||||
if (doReboot) reset();
|
if (doReboot) reset();
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -62,9 +62,6 @@
|
|||||||
<ClInclude Include="palettes.h">
|
<ClInclude Include="palettes.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="WS2812FX.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient.h">
|
<ClInclude Include="src\dependencies\async-mqtt-client\AsyncMqttClient.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -179,9 +176,6 @@
|
|||||||
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkWiFiCommon.h">
|
<ClInclude Include="src\dependencies\blynk\Blynk\BlynkWiFiCommon.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="src\dependencies\e131\E131.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="src\dependencies\espalexa\Espalexa.h">
|
<ClInclude Include="src\dependencies\espalexa\Espalexa.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -203,14 +197,14 @@
|
|||||||
<ClInclude Include="src\dependencies\timezone\Timezone.h">
|
<ClInclude Include="src\dependencies\timezone\Timezone.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FX.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\dependencies\e131\ESPAsyncE131.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="WS2812FX.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="WS2812FX_fcn.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient.cpp">
|
<ClCompile Include="src\dependencies\async-mqtt-client\AsyncMqttClient.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -253,9 +247,6 @@
|
|||||||
<ClCompile Include="src\dependencies\blynk\Blynk\utility.cpp">
|
<ClCompile Include="src\dependencies\blynk\Blynk\utility.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\dependencies\e131\E131.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\dependencies\espalexa\EspalexaDevice.cpp">
|
<ClCompile Include="src\dependencies\espalexa\EspalexaDevice.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -268,5 +259,14 @@
|
|||||||
<ClCompile Include="src\dependencies\timezone\Timezone.cpp">
|
<ClCompile Include="src\dependencies\timezone\Timezone.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="FX.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="FX_fcn.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\dependencies\e131\ESPAsyncE131.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -6,7 +6,7 @@
|
|||||||
#define EEPSIZE 2560
|
#define EEPSIZE 2560
|
||||||
|
|
||||||
//eeprom Version code, enables default settings instead of 0 init on update
|
//eeprom Version code, enables default settings instead of 0 init on update
|
||||||
#define EEPVER 11
|
#define EEPVER 14
|
||||||
//0 -> old version, default
|
//0 -> old version, default
|
||||||
//1 -> 0.4p 1711272 and up
|
//1 -> 0.4p 1711272 and up
|
||||||
//2 -> 0.4p 1711302 and up
|
//2 -> 0.4p 1711302 and up
|
||||||
@ -19,7 +19,14 @@
|
|||||||
//9 -> 0.8.0
|
//9 -> 0.8.0
|
||||||
//10-> 0.8.2
|
//10-> 0.8.2
|
||||||
//11-> 0.8.5-dev #mqttauth @TimothyBrown
|
//11-> 0.8.5-dev #mqttauth @TimothyBrown
|
||||||
|
//12-> 0.8.7-dev
|
||||||
|
//13-> 0.9.0-dev
|
||||||
|
//14-> 0.9.0-b1
|
||||||
|
|
||||||
|
void commit()
|
||||||
|
{
|
||||||
|
if (!EEPROM.commit()) errorFlag = 2;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Erase all configuration data
|
* Erase all configuration data
|
||||||
@ -30,7 +37,7 @@ void clearEEPROM()
|
|||||||
{
|
{
|
||||||
EEPROM.write(i, 0);
|
EEPROM.write(i, 0);
|
||||||
}
|
}
|
||||||
EEPROM.commit();
|
commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,9 +97,6 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(242+i, staticSubnet[i]);
|
EEPROM.write(242+i, staticSubnet[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
EEPROM.write(246, colS[0]);
|
|
||||||
EEPROM.write(247, colS[1]);
|
|
||||||
EEPROM.write(248, colS[2]);
|
|
||||||
EEPROM.write(249, briS);
|
EEPROM.write(249, briS);
|
||||||
|
|
||||||
EEPROM.write(250, receiveNotificationBrightness);
|
EEPROM.write(250, receiveNotificationBrightness);
|
||||||
@ -111,10 +115,6 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(291, (udpPort >> 8) & 0xFF);
|
EEPROM.write(291, (udpPort >> 8) & 0xFF);
|
||||||
writeStringToEEPROM(292, serverDescription, 32);
|
writeStringToEEPROM(292, serverDescription, 32);
|
||||||
|
|
||||||
EEPROM.write(324, effectDefault);
|
|
||||||
EEPROM.write(325, effectSpeedDefault);
|
|
||||||
EEPROM.write(326, effectIntensityDefault);
|
|
||||||
|
|
||||||
EEPROM.write(327, ntpEnabled);
|
EEPROM.write(327, ntpEnabled);
|
||||||
EEPROM.write(328, currentTimezone);
|
EEPROM.write(328, currentTimezone);
|
||||||
EEPROM.write(329, useAMPM);
|
EEPROM.write(329, useAMPM);
|
||||||
@ -129,20 +129,14 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(367, (arlsOffset>=0));
|
EEPROM.write(367, (arlsOffset>=0));
|
||||||
EEPROM.write(368, abs(arlsOffset));
|
EEPROM.write(368, abs(arlsOffset));
|
||||||
EEPROM.write(369, turnOnAtBoot);
|
EEPROM.write(369, turnOnAtBoot);
|
||||||
EEPROM.write(370, useHSBDefault);
|
|
||||||
EEPROM.write(371, colS[3]); //white default
|
|
||||||
EEPROM.write(372, useRGBW);
|
EEPROM.write(372, useRGBW);
|
||||||
EEPROM.write(373, effectPaletteDefault);
|
|
||||||
EEPROM.write(374, strip.paletteFade);
|
EEPROM.write(374, strip.paletteFade);
|
||||||
//EEPROM.write(375, apWaitTimeSecs);
|
EEPROM.write(375, strip.milliampsPerLed); //was apWaitTimeSecs up to 0.8.5
|
||||||
EEPROM.write(376, apBehavior);
|
EEPROM.write(376, apBehavior);
|
||||||
|
|
||||||
EEPROM.write(377, EEPVER); //eeprom was updated to latest
|
EEPROM.write(377, EEPVER); //eeprom was updated to latest
|
||||||
|
|
||||||
EEPROM.write(378, colSecS[0]);
|
|
||||||
EEPROM.write(379, colSecS[1]);
|
|
||||||
EEPROM.write(380, colSecS[2]);
|
|
||||||
EEPROM.write(381, colSecS[3]);
|
|
||||||
EEPROM.write(382, strip.paletteBlend);
|
EEPROM.write(382, strip.paletteBlend);
|
||||||
EEPROM.write(383, strip.colorOrder);
|
EEPROM.write(383, strip.colorOrder);
|
||||||
|
|
||||||
@ -159,20 +153,13 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
|
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
|
||||||
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
||||||
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
||||||
//397 was initLedsLast
|
EEPROM.write(397, syncToggleReceive);
|
||||||
EEPROM.write(398, (ledCount >> 8) & 0xFF);
|
EEPROM.write(398, (ledCount >> 8) & 0xFF);
|
||||||
EEPROM.write(399, !enableSecTransition);
|
EEPROM.write(399, !enableSecTransition);
|
||||||
|
|
||||||
//favorite setting (preset) memory (25 slots/ each 20byte)
|
//favorite setting (preset) memory (25 slots/ each 20byte)
|
||||||
//400 - 899 reserved
|
//400 - 940 reserved
|
||||||
|
writeStringToEEPROM(990, ntpServerName, 32);
|
||||||
for (int k=0;k<6;k++){
|
|
||||||
int in = 900+k*8;
|
|
||||||
writeStringToEEPROM(in, cssCol[k], 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
EEPROM.write(948,currentTheme);
|
|
||||||
writeStringToEEPROM(950, cssFont, 32);
|
|
||||||
|
|
||||||
EEPROM.write(2048, huePollingEnabled);
|
EEPROM.write(2048, huePollingEnabled);
|
||||||
//EEPROM.write(2049, hueUpdatingEnabled);
|
//EEPROM.write(2049, hueUpdatingEnabled);
|
||||||
@ -227,7 +214,6 @@ void saveSettingsToEEPROM()
|
|||||||
|
|
||||||
EEPROM.write(2200, !receiveDirect);
|
EEPROM.write(2200, !receiveDirect);
|
||||||
EEPROM.write(2201, notifyMacro); //was enableRealtime
|
EEPROM.write(2201, notifyMacro); //was enableRealtime
|
||||||
EEPROM.write(2202, uiConfiguration);
|
|
||||||
EEPROM.write(2203, autoRGBtoRGBW);
|
EEPROM.write(2203, autoRGBtoRGBW);
|
||||||
EEPROM.write(2204, skipFirstLed);
|
EEPROM.write(2204, skipFirstLed);
|
||||||
|
|
||||||
@ -244,6 +230,8 @@ void saveSettingsToEEPROM()
|
|||||||
saveCurrPresetCycConf = false;
|
saveCurrPresetCycConf = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EEPROM.write(2213, disableNLeds);
|
||||||
|
|
||||||
writeStringToEEPROM(2220, blynkApiKey, 35);
|
writeStringToEEPROM(2220, blynkApiKey, 35);
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
@ -254,6 +242,7 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(2290 + i, timerMacro[i] );
|
EEPROM.write(2290 + i, timerMacro[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EEPROM.write(2299, mqttEnabled);
|
||||||
writeStringToEEPROM(2300, mqttServer, 32);
|
writeStringToEEPROM(2300, mqttServer, 32);
|
||||||
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
|
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
|
||||||
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
||||||
@ -263,7 +252,7 @@ void saveSettingsToEEPROM()
|
|||||||
EEPROM.write(2522, mqttPort & 0xFF);
|
EEPROM.write(2522, mqttPort & 0xFF);
|
||||||
EEPROM.write(2523, (mqttPort >> 8) & 0xFF);
|
EEPROM.write(2523, (mqttPort >> 8) & 0xFF);
|
||||||
|
|
||||||
EEPROM.commit();
|
commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -317,9 +306,6 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
staticSubnet[2] = EEPROM.read(244);
|
staticSubnet[2] = EEPROM.read(244);
|
||||||
staticSubnet[3] = EEPROM.read(245);
|
staticSubnet[3] = EEPROM.read(245);
|
||||||
|
|
||||||
colS[0] = EEPROM.read(246); col[0] = colS[0];
|
|
||||||
colS[1] = EEPROM.read(247); col[1] = colS[1];
|
|
||||||
colS[2] = EEPROM.read(248); col[2] = colS[2];
|
|
||||||
briS = EEPROM.read(249); bri = briS;
|
briS = EEPROM.read(249); bri = briS;
|
||||||
if (!EEPROM.read(369) && first)
|
if (!EEPROM.read(369) && first)
|
||||||
{
|
{
|
||||||
@ -340,8 +326,6 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
|
|
||||||
readStringFromEEPROM(292, serverDescription, 32);
|
readStringFromEEPROM(292, serverDescription, 32);
|
||||||
|
|
||||||
effectDefault = EEPROM.read(324); effectCurrent = effectDefault;
|
|
||||||
effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault;
|
|
||||||
ntpEnabled = EEPROM.read(327);
|
ntpEnabled = EEPROM.read(327);
|
||||||
currentTimezone = EEPROM.read(328);
|
currentTimezone = EEPROM.read(328);
|
||||||
useAMPM = EEPROM.read(329);
|
useAMPM = EEPROM.read(329);
|
||||||
@ -358,36 +342,19 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
arlsOffset = EEPROM.read(368);
|
arlsOffset = EEPROM.read(368);
|
||||||
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
|
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
|
||||||
turnOnAtBoot = EEPROM.read(369);
|
turnOnAtBoot = EEPROM.read(369);
|
||||||
useHSBDefault = EEPROM.read(370);
|
|
||||||
colS[3] = EEPROM.read(371); col[3] = colS[3];
|
|
||||||
useRGBW = EEPROM.read(372);
|
useRGBW = EEPROM.read(372);
|
||||||
effectPaletteDefault = EEPROM.read(373); effectPalette = effectPaletteDefault;
|
|
||||||
//374 - strip.paletteFade
|
//374 - strip.paletteFade
|
||||||
|
|
||||||
if (lastEEPROMversion > 0) {
|
apBehavior = EEPROM.read(376);
|
||||||
//apWaitTimeSecs = EEPROM.read(375);
|
|
||||||
apBehavior = EEPROM.read(376);
|
|
||||||
}
|
|
||||||
//377 = lastEEPROMversion
|
//377 = lastEEPROMversion
|
||||||
if (lastEEPROMversion > 1) {
|
|
||||||
for (byte i=0; i<4; i++)
|
|
||||||
{
|
|
||||||
colSecS[i] = EEPROM.read(378+i); colSec[i] = colSecS[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lastEEPROMversion > 3) {
|
if (lastEEPROMversion > 3) {
|
||||||
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
|
|
||||||
aOtaEnabled = EEPROM.read(390);
|
aOtaEnabled = EEPROM.read(390);
|
||||||
receiveNotificationColor = EEPROM.read(391);
|
receiveNotificationColor = EEPROM.read(391);
|
||||||
receiveNotificationEffects = EEPROM.read(392);
|
receiveNotificationEffects = EEPROM.read(392);
|
||||||
|
|
||||||
readStringFromEEPROM(950, cssFont, 32);
|
|
||||||
} else //keep receiving notification behavior from pre0.5.0 after update
|
|
||||||
{
|
|
||||||
receiveNotificationColor = receiveNotificationBrightness;
|
|
||||||
receiveNotificationEffects = receiveNotificationBrightness;
|
|
||||||
}
|
}
|
||||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||||
|
|
||||||
if (lastEEPROMversion > 4) {
|
if (lastEEPROMversion > 4) {
|
||||||
huePollingEnabled = EEPROM.read(2048);
|
huePollingEnabled = EEPROM.read(2048);
|
||||||
//hueUpdatingEnabled = EEPROM.read(2049);
|
//hueUpdatingEnabled = EEPROM.read(2049);
|
||||||
@ -485,14 +452,29 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
mqttPort = EEPROM.read(2522) + ((EEPROM.read(2523) << 8) & 0xFF00);
|
mqttPort = EEPROM.read(2522) + ((EEPROM.read(2523) << 8) & 0xFF00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastEEPROMversion > 11)
|
||||||
|
{
|
||||||
|
strip.milliampsPerLed = EEPROM.read(375);
|
||||||
|
} else if (strip.ablMilliampsMax == 65000) //65000 indicates disabled ABL in <0.8.7
|
||||||
|
{
|
||||||
|
strip.ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
|
||||||
|
strip.milliampsPerLed = 0; //disable ABL
|
||||||
|
}
|
||||||
|
if (lastEEPROMversion > 12)
|
||||||
|
{
|
||||||
|
readStringFromEEPROM(990, ntpServerName, 32);
|
||||||
|
}
|
||||||
|
if (lastEEPROMversion > 13)
|
||||||
|
{
|
||||||
|
mqttEnabled = EEPROM.read(2299);
|
||||||
|
syncToggleReceive = EEPROM.read(397);
|
||||||
|
} else {
|
||||||
|
mqttEnabled = true;
|
||||||
|
syncToggleReceive = false;
|
||||||
|
}
|
||||||
|
|
||||||
receiveDirect = !EEPROM.read(2200);
|
receiveDirect = !EEPROM.read(2200);
|
||||||
notifyMacro = EEPROM.read(2201);
|
notifyMacro = EEPROM.read(2201);
|
||||||
uiConfiguration = EEPROM.read(2202);
|
|
||||||
|
|
||||||
#ifdef WLED_DISABLE_MOBILE_UI
|
|
||||||
uiConfiguration = 1;
|
|
||||||
//force default UI since mobile is unavailable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
autoRGBtoRGBW = EEPROM.read(2203);
|
autoRGBtoRGBW = EEPROM.read(2203);
|
||||||
skipFirstLed = EEPROM.read(2204);
|
skipFirstLed = EEPROM.read(2204);
|
||||||
@ -508,6 +490,8 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
presetApplyFx = EEPROM.read(2212);
|
presetApplyFx = EEPROM.read(2212);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disableNLeds = EEPROM.read(2213);
|
||||||
|
|
||||||
bootPreset = EEPROM.read(389);
|
bootPreset = EEPROM.read(389);
|
||||||
wifiLock = EEPROM.read(393);
|
wifiLock = EEPROM.read(393);
|
||||||
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
|
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
|
||||||
@ -517,29 +501,45 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
//favorite setting (preset) memory (25 slots/ each 20byte)
|
//favorite setting (preset) memory (25 slots/ each 20byte)
|
||||||
//400 - 899 reserved
|
//400 - 899 reserved
|
||||||
|
|
||||||
currentTheme = EEPROM.read(948);
|
|
||||||
for (int k=0;k<6;k++){
|
|
||||||
int in=900+k*8;
|
|
||||||
readStringFromEEPROM(in, cssCol[k], 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
//custom macro memory (16 slots/ each 64byte)
|
//custom macro memory (16 slots/ each 64byte)
|
||||||
//1024-2047 reserved
|
//1024-2047 reserved
|
||||||
|
|
||||||
readStringFromEEPROM(2220, blynkApiKey, 35);
|
readStringFromEEPROM(2220, blynkApiKey, 35);
|
||||||
|
if (strlen(blynkApiKey) < 25) blynkApiKey[0] = 0;
|
||||||
|
|
||||||
//user MOD memory
|
//user MOD memory
|
||||||
//2944 - 3071 reserved
|
//2944 - 3071 reserved
|
||||||
|
|
||||||
useHSB = useHSBDefault;
|
|
||||||
|
|
||||||
overlayCurrent = overlayDefault;
|
overlayCurrent = overlayDefault;
|
||||||
|
|
||||||
|
savedToPresets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//PRESET PROTOCOL 20 bytes
|
//PRESET PROTOCOL 20 bytes
|
||||||
//0: preset purpose byte 0:invalid 1:valid preset 1.0
|
//0: preset purpose byte 0:invalid 1:valid preset 2:segment preset 2.0
|
||||||
//1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17: fp 18-19:Zeros
|
//1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17: fp 18-19:Zeros
|
||||||
|
//determines which presets already contain save data
|
||||||
|
void savedToPresets()
|
||||||
|
{
|
||||||
|
for (byte index = 1; index < 16; index++)
|
||||||
|
{
|
||||||
|
uint16_t i = 380 + index*20;
|
||||||
|
|
||||||
|
if (EEPROM.read(i) == 1) {
|
||||||
|
savedPresets |= 0x01 << (index-1);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
savedPresets &= ~(0x01 << (index-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (EEPROM.read(700) == 2) {
|
||||||
|
savedPresets |= 0x01 << 15;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
savedPresets &= ~(0x01 << 15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool loadFX = true)
|
bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool loadFX = true)
|
||||||
{
|
{
|
||||||
@ -548,46 +548,70 @@ bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool load
|
|||||||
loadSettingsFromEEPROM(false);//load boot defaults
|
loadSettingsFromEEPROM(false);//load boot defaults
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (index > 25 || index < 1) return false;
|
if (index > 16 || index < 1) return false;
|
||||||
uint16_t i = 380 + index*20;
|
uint16_t i = 380 + index*20;
|
||||||
if (EEPROM.read(i) == 0) return false;
|
if (index < 16) {
|
||||||
if (loadBri) bri = EEPROM.read(i+1);
|
if (EEPROM.read(i) != 1) return false;
|
||||||
if (loadCol)
|
strip.applyToAllSelected = true;
|
||||||
{
|
if (loadBri) bri = EEPROM.read(i+1);
|
||||||
for (byte j=0; j<4; j++)
|
if (loadCol)
|
||||||
{
|
{
|
||||||
col[j] = EEPROM.read(i+j+2);
|
for (byte j=0; j<4; j++)
|
||||||
colSec[j] = EEPROM.read(i+j+6);
|
{
|
||||||
|
col[j] = EEPROM.read(i+j+2);
|
||||||
|
colSec[j] = EEPROM.read(i+j+6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (loadFX)
|
||||||
|
{
|
||||||
|
effectCurrent = EEPROM.read(i+10);
|
||||||
|
effectSpeed = EEPROM.read(i+11);
|
||||||
|
effectIntensity = EEPROM.read(i+16);
|
||||||
|
effectPalette = EEPROM.read(i+17);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (EEPROM.read(i) != 2) return false;
|
||||||
|
strip.applyToAllSelected = false;
|
||||||
|
if (loadBri) bri = EEPROM.read(i+1);
|
||||||
|
WS2812FX::Segment* seg = strip.getSegments();
|
||||||
|
memcpy(seg, EEPROM.getDataPtr() +i+2, 240);
|
||||||
|
setValuesFromMainSeg();
|
||||||
}
|
}
|
||||||
if (loadFX)
|
currentPreset = index;
|
||||||
{
|
isPreset = true;
|
||||||
effectCurrent = EEPROM.read(i+10);
|
|
||||||
effectSpeed = EEPROM.read(i+11);
|
|
||||||
effectIntensity = EEPROM.read(i+16);
|
|
||||||
effectPalette = EEPROM.read(i+17);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void savePreset(byte index)
|
void savePreset(byte index)
|
||||||
{
|
{
|
||||||
if (index > 25) return;
|
if (index > 16) return;
|
||||||
if (index < 1) {saveSettingsToEEPROM();return;}
|
if (index < 1) {saveSettingsToEEPROM();return;}
|
||||||
uint16_t i = 380 + index*20;//min400
|
uint16_t i = 380 + index*20;//min400
|
||||||
EEPROM.write(i, 1);
|
|
||||||
EEPROM.write(i+1, bri);
|
if (index < 16) {
|
||||||
for (uint16_t j=0; j<4; j++)
|
EEPROM.write(i, 1);
|
||||||
{
|
EEPROM.write(i+1, bri);
|
||||||
EEPROM.write(i+j+2, col[j]);
|
for (uint16_t j=0; j<4; j++)
|
||||||
EEPROM.write(i+j+6, colSec[j]);
|
{
|
||||||
|
EEPROM.write(i+j+2, col[j]);
|
||||||
|
EEPROM.write(i+j+6, colSec[j]);
|
||||||
|
}
|
||||||
|
EEPROM.write(i+10, effectCurrent);
|
||||||
|
EEPROM.write(i+11, effectSpeed);
|
||||||
|
|
||||||
|
EEPROM.write(i+16, effectIntensity);
|
||||||
|
EEPROM.write(i+17, effectPalette);
|
||||||
|
} else { //segment 16 can save segments
|
||||||
|
EEPROM.write(i, 2);
|
||||||
|
EEPROM.write(i+1, bri);
|
||||||
|
WS2812FX::Segment* seg = strip.getSegments();
|
||||||
|
memcpy(EEPROM.getDataPtr() +i+2, seg, 240);
|
||||||
}
|
}
|
||||||
EEPROM.write(i+10, effectCurrent);
|
|
||||||
EEPROM.write(i+11, effectSpeed);
|
commit();
|
||||||
|
savedToPresets();
|
||||||
EEPROM.write(i+16, effectIntensity);
|
currentPreset = index;
|
||||||
EEPROM.write(i+17, effectPalette);
|
isPreset = true;
|
||||||
EEPROM.commit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -629,5 +653,5 @@ void saveMacro(byte index, String mc, bool sing=true) //only commit on single sa
|
|||||||
{
|
{
|
||||||
EEPROM.write(i, mc.charAt(i-s));
|
EEPROM.write(i, mc.charAt(i-s));
|
||||||
}
|
}
|
||||||
if (sing) EEPROM.commit();
|
if (sing) commit();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//build XML response to HTTP /win API request
|
//build XML response to HTTP /win API request
|
||||||
char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest = nullptr)
|
char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr)
|
||||||
{
|
{
|
||||||
char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed
|
char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed
|
||||||
obuf = (dest == nullptr)? sbuf:dest;
|
obuf = (dest == nullptr)? sbuf:dest;
|
||||||
@ -53,9 +53,7 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
|
|||||||
}
|
}
|
||||||
oappend("</wv><ws>");
|
oappend("</wv><ws>");
|
||||||
oappendi(colSec[3]);
|
oappendi(colSec[3]);
|
||||||
oappend("</ws><md>");
|
oappend("</ws><cy>");
|
||||||
oappendi(useHSB);
|
|
||||||
oappend("</md><cy>");
|
|
||||||
oappendi(presetCyclingEnabled);
|
oappendi(presetCyclingEnabled);
|
||||||
oappend("</cy><ds>");
|
oappend("</cy><ds>");
|
||||||
if (realtimeActive)
|
if (realtimeActive)
|
||||||
@ -77,34 +75,14 @@ char* XML_response(AsyncWebServerRequest *request, bool includeTheme, char* dest
|
|||||||
} else {
|
} else {
|
||||||
oappend(serverDescription);
|
oappend(serverDescription);
|
||||||
}
|
}
|
||||||
|
oappend("</ds><ss>");
|
||||||
oappend("</ds>");
|
oappendi(strip.getMainSegmentId());
|
||||||
if (includeTheme)
|
oappend("</ss></vs>");
|
||||||
{
|
|
||||||
char cs[6][9];
|
|
||||||
getThemeColors(cs);
|
|
||||||
oappend("<th><ca>#");
|
|
||||||
oappend(cs[0]);
|
|
||||||
oappend("</ca><cb>#");
|
|
||||||
oappend(cs[1]);
|
|
||||||
oappend("</cb><cc>#");
|
|
||||||
oappend(cs[2]);
|
|
||||||
oappend("</cc><cd>#");
|
|
||||||
oappend(cs[3]);
|
|
||||||
oappend("</cd><cu>#");
|
|
||||||
oappend(cs[4]);
|
|
||||||
oappend("</cu><ct>#");
|
|
||||||
oappend(cs[5]);
|
|
||||||
oappend("</ct><cf>");
|
|
||||||
oappend(cssFont);
|
|
||||||
oappend("</cf></th>");
|
|
||||||
}
|
|
||||||
oappend("</vs>");
|
|
||||||
if (request != nullptr) request->send(200, "text/xml", obuf);
|
if (request != nullptr) request->send(200, "text/xml", obuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//append a numeric setting to string buffer
|
//append a numeric setting to string buffer
|
||||||
void sappend(char stype, char* key, int val)
|
void sappend(char stype, const char* key, int val)
|
||||||
{
|
{
|
||||||
char ds[] = "d.Sf.";
|
char ds[] = "d.Sf.";
|
||||||
|
|
||||||
@ -135,7 +113,7 @@ void sappend(char stype, char* key, int val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//append a string setting to buffer
|
//append a string setting to buffer
|
||||||
void sappends(char stype, char* key, char* val)
|
void sappends(char stype, const char* key, char* val)
|
||||||
{
|
{
|
||||||
switch(stype)
|
switch(stype)
|
||||||
{
|
{
|
||||||
@ -223,8 +201,14 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 2) {
|
if (subPage == 2) {
|
||||||
|
#ifdef ESP8266
|
||||||
|
#if LEDPIN == 3
|
||||||
|
oappend("d.Sf.LC.max=500;");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
sappend('v',"LC",ledCount);
|
sappend('v',"LC",ledCount);
|
||||||
sappend('v',"MA",strip.ablMilliampsMax);
|
sappend('v',"MA",strip.ablMilliampsMax);
|
||||||
|
sappend('v',"LA",strip.milliampsPerLed);
|
||||||
if (strip.currentMilliamps)
|
if (strip.currentMilliamps)
|
||||||
{
|
{
|
||||||
sappends('m',"(\"pow\")[0]","");
|
sappends('m',"(\"pow\")[0]","");
|
||||||
@ -232,33 +216,20 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
oappendi(strip.currentMilliamps);
|
oappendi(strip.currentMilliamps);
|
||||||
oappend("mA\";");
|
oappend("mA\";");
|
||||||
}
|
}
|
||||||
sappend('v',"CR",colS[0]);
|
|
||||||
sappend('v',"CG",colS[1]);
|
|
||||||
sappend('v',"CB",colS[2]);
|
|
||||||
sappend('v',"CA",briS);
|
sappend('v',"CA",briS);
|
||||||
sappend('c',"EW",useRGBW);
|
sappend('c',"EW",useRGBW);
|
||||||
sappend('i',"CO",strip.colorOrder);
|
sappend('i',"CO",strip.colorOrder);
|
||||||
sappend('c',"AW",autoRGBtoRGBW);
|
sappend('c',"AW",autoRGBtoRGBW);
|
||||||
sappend('v',"CW",colS[3]);
|
|
||||||
sappend('v',"SR",colSecS[0]);
|
|
||||||
sappend('v',"SG",colSecS[1]);
|
|
||||||
sappend('v',"SB",colSecS[2]);
|
|
||||||
sappend('v',"SW",colSecS[3]);
|
|
||||||
sappend('c',"BO",turnOnAtBoot);
|
sappend('c',"BO",turnOnAtBoot);
|
||||||
sappend('v',"BP",bootPreset);
|
sappend('v',"BP",bootPreset);
|
||||||
oappend("f=");
|
|
||||||
oappendi(effectDefault);
|
|
||||||
oappend(";p=");
|
|
||||||
oappendi(effectPaletteDefault);
|
|
||||||
oappend(";");
|
|
||||||
sappend('v',"SX",effectSpeedDefault);
|
|
||||||
sappend('v',"IX",effectIntensityDefault);
|
|
||||||
sappend('c',"GB",strip.gammaCorrectBri);
|
sappend('c',"GB",strip.gammaCorrectBri);
|
||||||
sappend('c',"GC",strip.gammaCorrectCol);
|
sappend('c',"GC",strip.gammaCorrectCol);
|
||||||
sappend('c',"TF",fadeTransition);
|
sappend('c',"TF",fadeTransition);
|
||||||
sappend('v',"TD",transitionDelay);
|
sappend('v',"TD",transitionDelayDefault);
|
||||||
sappend('c',"PF",strip.paletteFade);
|
sappend('c',"PF",strip.paletteFade);
|
||||||
sappend('c',"T2",enableSecTransition);
|
|
||||||
sappend('v',"BF",briMultiplier);
|
sappend('v',"BF",briMultiplier);
|
||||||
sappend('v',"TB",nightlightTargetBri);
|
sappend('v',"TB",nightlightTargetBri);
|
||||||
sappend('v',"TL",nightlightDelayMinsDefault);
|
sappend('v',"TL",nightlightDelayMinsDefault);
|
||||||
@ -266,21 +237,13 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('i',"PB",strip.paletteBlend);
|
sappend('i',"PB",strip.paletteBlend);
|
||||||
sappend('c',"RV",strip.reverseMode);
|
sappend('c',"RV",strip.reverseMode);
|
||||||
sappend('c',"SL",skipFirstLed);
|
sappend('c',"SL",skipFirstLed);
|
||||||
|
sappend('v',"DL",disableNLeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 3)
|
if (subPage == 3)
|
||||||
{
|
{
|
||||||
sappend('i',"UI",uiConfiguration);
|
|
||||||
sappends('s',"DS",serverDescription);
|
sappends('s',"DS",serverDescription);
|
||||||
sappend('c',"MD",useHSBDefault);
|
sappend('c',"ST",syncToggleReceive);
|
||||||
sappend('i',"TH",currentTheme);
|
|
||||||
char k[3]; k[0] = 'C'; k[2] = 0; //keys
|
|
||||||
for (int i=0; i<6; i++)
|
|
||||||
{
|
|
||||||
k[1] = 48+i; //ascii 0,1,2,3,4,5
|
|
||||||
sappends('s',k,cssCol[i]);
|
|
||||||
}
|
|
||||||
sappends('s',"CF",cssFont);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 4)
|
if (subPage == 4)
|
||||||
@ -307,6 +270,9 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappends('s',"AI",alexaInvocationName);
|
sappends('s',"AI",alexaInvocationName);
|
||||||
sappend('c',"SA",notifyAlexa);
|
sappend('c',"SA",notifyAlexa);
|
||||||
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
|
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_MQTT
|
||||||
|
sappend('c',"MQ",mqttEnabled);
|
||||||
sappends('s',"MS",mqttServer);
|
sappends('s',"MS",mqttServer);
|
||||||
sappend('v',"MQPORT",mqttPort);
|
sappend('v',"MQPORT",mqttPort);
|
||||||
sappends('s',"MQUSER",mqttUser);
|
sappends('s',"MQUSER",mqttUser);
|
||||||
@ -319,6 +285,11 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappends('s',"MQCID",mqttClientID);
|
sappends('s',"MQCID",mqttClientID);
|
||||||
sappends('s',"MD",mqttDeviceTopic);
|
sappends('s',"MD",mqttDeviceTopic);
|
||||||
sappends('s',"MG",mqttGroupTopic);
|
sappends('s',"MG",mqttGroupTopic);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WLED_DISABLE_HUESYNC
|
||||||
|
sappends('m',"(\"hms\")[0]","Unsupported in build");
|
||||||
|
#else
|
||||||
sappend('v',"H0",hueIP[0]);
|
sappend('v',"H0",hueIP[0]);
|
||||||
sappend('v',"H1",hueIP[1]);
|
sappend('v',"H1",hueIP[1]);
|
||||||
sappend('v',"H2",hueIP[2]);
|
sappend('v',"H2",hueIP[2]);
|
||||||
@ -330,11 +301,13 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',"HB",hueApplyBri);
|
sappend('c',"HB",hueApplyBri);
|
||||||
sappend('c',"HC",hueApplyColor);
|
sappend('c',"HC",hueApplyColor);
|
||||||
sappends('m',"(\"hms\")[0]",hueError);
|
sappends('m',"(\"hms\")[0]",hueError);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subPage == 5)
|
if (subPage == 5)
|
||||||
{
|
{
|
||||||
sappend('c',"NT",ntpEnabled);
|
sappend('c',"NT",ntpEnabled);
|
||||||
|
sappends('s',"NS",ntpServerName);
|
||||||
sappend('c',"CF",!useAMPM);
|
sappend('c',"CF",!useAMPM);
|
||||||
sappend('i',"TZ",currentTimezone);
|
sappend('i',"TZ",currentTimezone);
|
||||||
sappend('v',"UO",utcOffsetSecs);
|
sappend('v',"UO",utcOffsetSecs);
|
||||||
@ -399,29 +372,3 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
}
|
}
|
||||||
oappend("}</script>");
|
oappend("}</script>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//get colors from current theme as c strings
|
|
||||||
void getThemeColors(char o[][9])
|
|
||||||
{
|
|
||||||
switch (currentTheme)
|
|
||||||
{
|
|
||||||
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
|
|
||||||
default: strcpy(o[0], "D9B310"); strcpy(o[1], "0B3C5D"); strcpy(o[2], "1D2731"); strcpy(o[3], "328CC1"); strcpy(o[4], "000"); strcpy(o[5], "328CC1"); break; //night
|
|
||||||
case 1: strcpy(o[0], "eee"); strcpy(o[1], "ddd"); strcpy(o[2], "b9b9b9"); strcpy(o[3], "049"); strcpy(o[4], "777"); strcpy(o[5], "049"); break; //modern
|
|
||||||
case 2: strcpy(o[0], "abb"); strcpy(o[1], "fff"); strcpy(o[2], "ddd"); strcpy(o[3], "000"); strcpy(o[4], "0004"); strcpy(o[5], "000"); break; //bright
|
|
||||||
case 3: strcpy(o[0], "c09f80"); strcpy(o[1], "d7cec7"); strcpy(o[2], "76323f"); strcpy(o[3], "888"); strcpy(o[4], "3334"); strcpy(o[5], "888"); break; //wine
|
|
||||||
case 4: strcpy(o[0], "3cc47c"); strcpy(o[1], "828081"); strcpy(o[2], "d9a803"); strcpy(o[3], "1e392a"); strcpy(o[4], "000a"); strcpy(o[5], "1e392a"); break; //electric
|
|
||||||
case 5: strcpy(o[0], "57bc90"); strcpy(o[1], "a5a5af"); strcpy(o[2], "015249"); strcpy(o[3], "88c9d4"); strcpy(o[4], "0004"); strcpy(o[5], "88c9d4"); break; //mint
|
|
||||||
case 6: strcpy(o[0], "f7c331"); strcpy(o[1], "dca"); strcpy(o[2], "6b7a8f"); strcpy(o[3], "f7882f"); strcpy(o[4], "0007"); strcpy(o[5], "f7882f"); break; //amber
|
|
||||||
case 7: strcpy(o[0], "fff"); strcpy(o[1], "333"); strcpy(o[2], "222"); strcpy(o[3], "666"); strcpy(o[4], ""); strcpy(o[5], "fff"); break; //dark
|
|
||||||
case 8: strcpy(o[0], "0ac"); strcpy(o[1], "124"); strcpy(o[2], "224"); strcpy(o[3], "003eff"); strcpy(o[4], "003eff"); strcpy(o[5], "003eff"); break; //air
|
|
||||||
case 9: strcpy(o[0], "f70"); strcpy(o[1], "421"); strcpy(o[2], "221"); strcpy(o[3], "a50"); strcpy(o[4], "f70"); strcpy(o[5], "f70"); break; //nixie
|
|
||||||
case 10: strcpy(o[0], "2d2"); strcpy(o[1], "010"); strcpy(o[2], "121"); strcpy(o[3], "060"); strcpy(o[4], "040"); strcpy(o[5], "3f3"); break; //terminal
|
|
||||||
case 11: strcpy(o[0], "867ADE"); strcpy(o[1], "4033A3"); strcpy(o[2], "483AAA"); strcpy(o[3], "483AAA"); strcpy(o[4], ""); strcpy(o[5], "867ADE"); break; //c64
|
|
||||||
case 12: strcpy(o[0], "fbe8a6"); strcpy(o[1], "d2fdff"); strcpy(o[2], "b4dfe5"); strcpy(o[3], "f4976c"); strcpy(o[4], ""); strcpy(o[5], "303c6c"); break; //easter
|
|
||||||
case 13: strcpy(o[0], "d4af37"); strcpy(o[1], "173305"); strcpy(o[2], "308505"); strcpy(o[3], "f21313"); strcpy(o[4], "f002"); strcpy(o[5], "d4af37"); break; //christmas
|
|
||||||
case 14: strcpy(o[0], "fc7"); strcpy(o[1], "49274a"); strcpy(o[2], "94618e"); strcpy(o[3], "f4decb"); strcpy(o[4], "0008"); strcpy(o[5], "f4decb"); break; //end
|
|
||||||
case 15: for (int i=0;i<6;i++) strcpy(o[i], cssCol[i]); //custom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -14,6 +14,16 @@ void _setRandomColor(bool _sec,bool fromButton=false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isAsterisksOnly(const char* str, byte maxLen)
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < maxLen; i++) {
|
||||||
|
if (str[i] == 0) break;
|
||||||
|
if (str[i] != '*') return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//called upon POST settings form submit
|
//called upon POST settings form submit
|
||||||
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
{
|
{
|
||||||
@ -23,16 +33,17 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
//WIFI SETTINGS
|
//WIFI SETTINGS
|
||||||
if (subPage == 1)
|
if (subPage == 1)
|
||||||
{
|
{
|
||||||
strcpy(clientSSID,request->arg("CS").c_str());
|
strlcpy(clientSSID,request->arg("CS").c_str(), 33);
|
||||||
if (request->arg("CP").charAt(0) != '*') strcpy(clientPass, request->arg("CP").c_str());
|
|
||||||
|
|
||||||
strcpy(cmDNS, request->arg("CM").c_str());
|
if (!isAsterisksOnly(request->arg("CP").c_str(), 65)) strlcpy(clientPass, request->arg("CP").c_str(), 65);
|
||||||
|
|
||||||
|
strlcpy(cmDNS, request->arg("CM").c_str(), 33);
|
||||||
|
|
||||||
apBehavior = request->arg("AB").toInt();
|
apBehavior = request->arg("AB").toInt();
|
||||||
strcpy(apSSID, request->arg("AS").c_str());
|
strlcpy(apSSID, request->arg("AS").c_str(), 33);
|
||||||
apHide = request->hasArg("AH");
|
apHide = request->hasArg("AH");
|
||||||
int passlen = request->arg("AP").length();
|
int passlen = request->arg("AP").length();
|
||||||
if (passlen == 0 || (passlen > 7 && request->arg("AP").charAt(0) != '*')) strcpy(apPass, request->arg("AP").c_str());
|
if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg("AP").c_str(), 65))) strlcpy(apPass, request->arg("AP").c_str(), 65);
|
||||||
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t;
|
||||||
|
|
||||||
char k[3]; k[2] = 0;
|
char k[3]; k[2] = 0;
|
||||||
@ -56,44 +67,20 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
{
|
{
|
||||||
int t = request->arg("LC").toInt();
|
int t = request->arg("LC").toInt();
|
||||||
if (t > 0 && t <= MAX_LEDS) ledCount = t;
|
if (t > 0 && t <= MAX_LEDS) ledCount = t;
|
||||||
#ifndef ARDUINO_ARCH_ESP32
|
#ifdef ESP8266
|
||||||
#if LEDPIN == 3
|
#if LEDPIN == 3
|
||||||
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
strip.ablMilliampsMax = request->arg("MA").toInt();
|
strip.ablMilliampsMax = request->arg("MA").toInt();
|
||||||
|
strip.milliampsPerLed = request->arg("LA").toInt();
|
||||||
|
|
||||||
useRGBW = request->hasArg("EW");
|
useRGBW = request->hasArg("EW");
|
||||||
strip.colorOrder = request->arg("CO").toInt();
|
strip.colorOrder = request->arg("CO").toInt();
|
||||||
autoRGBtoRGBW = request->hasArg("AW");
|
autoRGBtoRGBW = request->hasArg("AW");
|
||||||
|
|
||||||
//ignore settings and save current brightness, colors and fx as default
|
briS = request->arg("CA").toInt();
|
||||||
if (request->hasArg("IS"))
|
|
||||||
{
|
|
||||||
for (byte i=0; i<4; i++)
|
|
||||||
{
|
|
||||||
colS[i] = col[i];
|
|
||||||
colSecS[i] = colSec[i];
|
|
||||||
}
|
|
||||||
briS = bri;
|
|
||||||
effectDefault = effectCurrent;
|
|
||||||
effectSpeedDefault = effectSpeed;
|
|
||||||
effectIntensityDefault = effectIntensity;
|
|
||||||
effectPaletteDefault = effectPalette;
|
|
||||||
} else {
|
|
||||||
colS[0] = request->arg("CR").toInt();
|
|
||||||
colS[1] = request->arg("CG").toInt();
|
|
||||||
colS[2] = request->arg("CB").toInt();
|
|
||||||
colSecS[0] = request->arg("SR").toInt();
|
|
||||||
colSecS[1] = request->arg("SG").toInt();
|
|
||||||
colSecS[2] = request->arg("SB").toInt();
|
|
||||||
colS[3] = request->arg("CW").toInt();
|
|
||||||
colSecS[3] = request->arg("SW").toInt();
|
|
||||||
briS = request->arg("CA").toInt();
|
|
||||||
effectDefault = request->arg("FX").toInt();
|
|
||||||
effectSpeedDefault = request->arg("SX").toInt();
|
|
||||||
effectIntensityDefault = request->arg("IX").toInt();
|
|
||||||
effectPaletteDefault = request->arg("FP").toInt();
|
|
||||||
}
|
|
||||||
saveCurrPresetCycConf = request->hasArg("PC");
|
saveCurrPresetCycConf = request->hasArg("PC");
|
||||||
turnOnAtBoot = request->hasArg("BO");
|
turnOnAtBoot = request->hasArg("BO");
|
||||||
t = request->arg("BP").toInt();
|
t = request->arg("BP").toInt();
|
||||||
@ -106,7 +93,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (t > 0) transitionDelay = t;
|
if (t > 0) transitionDelay = t;
|
||||||
transitionDelayDefault = t;
|
transitionDelayDefault = t;
|
||||||
strip.paletteFade = request->hasArg("PF");
|
strip.paletteFade = request->hasArg("PF");
|
||||||
enableSecTransition = request->hasArg("T2");
|
|
||||||
|
|
||||||
nightlightTargetBri = request->arg("TB").toInt();
|
nightlightTargetBri = request->arg("TB").toInt();
|
||||||
t = request->arg("TL").toInt();
|
t = request->arg("TL").toInt();
|
||||||
@ -118,6 +104,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (t >= 0 && t < 4) strip.paletteBlend = t;
|
if (t >= 0 && t < 4) strip.paletteBlend = t;
|
||||||
strip.reverseMode = request->hasArg("RV");
|
strip.reverseMode = request->hasArg("RV");
|
||||||
skipFirstLed = request->hasArg("SL");
|
skipFirstLed = request->hasArg("SL");
|
||||||
|
disableNLeds = request->arg("DL").toInt();
|
||||||
t = request->arg("BF").toInt();
|
t = request->arg("BF").toInt();
|
||||||
if (t > 0) briMultiplier = t;
|
if (t > 0) briMultiplier = t;
|
||||||
}
|
}
|
||||||
@ -125,19 +112,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
//UI
|
//UI
|
||||||
if (subPage == 3)
|
if (subPage == 3)
|
||||||
{
|
{
|
||||||
int t = request->arg("UI").toInt();
|
strlcpy(serverDescription, request->arg("DS").c_str(), 33);
|
||||||
if (t >= 0 && t < 3) uiConfiguration = t;
|
syncToggleReceive = request->hasArg("ST");
|
||||||
strcpy(serverDescription, request->arg("DS").c_str());
|
|
||||||
useHSBDefault = request->hasArg("MD");
|
|
||||||
useHSB = useHSBDefault;
|
|
||||||
currentTheme = request->arg("TH").toInt();
|
|
||||||
char k[3]; k[0]='C'; k[2]=0;
|
|
||||||
for(int i=0;i<6;i++)
|
|
||||||
{
|
|
||||||
k[1] = i+48;
|
|
||||||
strcpy(cssCol[i],request->arg(k).c_str());
|
|
||||||
}
|
|
||||||
strcpy(cssFont,request->arg("CF").c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//SYNC
|
//SYNC
|
||||||
@ -171,21 +147,25 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
if (t >= -255 && t <= 255) arlsOffset = t;
|
if (t >= -255 && t <= 255) arlsOffset = t;
|
||||||
|
|
||||||
alexaEnabled = request->hasArg("AL");
|
alexaEnabled = request->hasArg("AL");
|
||||||
strcpy(alexaInvocationName, request->arg("AI").c_str());
|
strlcpy(alexaInvocationName, request->arg("AI").c_str(), 33);
|
||||||
|
|
||||||
if (request->hasArg("BK") && !request->arg("BK").equals("Hidden")) {
|
if (request->hasArg("BK") && !request->arg("BK").equals("Hidden")) {
|
||||||
strcpy(blynkApiKey,request->arg("BK").c_str()); initBlynk(blynkApiKey);
|
strlcpy(blynkApiKey, request->arg("BK").c_str(), 36); initBlynk(blynkApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(mqttServer, request->arg("MS").c_str());
|
#ifdef WLED_ENABLE_MQTT
|
||||||
|
mqttEnabled = request->hasArg("MQ");
|
||||||
|
strlcpy(mqttServer, request->arg("MS").c_str(), 33);
|
||||||
t = request->arg("MQPORT").toInt();
|
t = request->arg("MQPORT").toInt();
|
||||||
if (t > 0) mqttPort = t;
|
if (t > 0) mqttPort = t;
|
||||||
strcpy(mqttUser, request->arg("MQUSER").c_str());
|
strlcpy(mqttUser, request->arg("MQUSER").c_str(), 41);
|
||||||
if (request->arg("MQPASS").charAt(0) != '*') strcpy(mqttPass, request->arg("MQPASS").c_str());
|
if (!isAsterisksOnly(request->arg("MQPASS").c_str(), 41)) strlcpy(mqttPass, request->arg("MQPASS").c_str(), 41);
|
||||||
strcpy(mqttClientID, request->arg("MQCID").c_str());
|
strlcpy(mqttClientID, request->arg("MQCID").c_str(), 41);
|
||||||
strcpy(mqttDeviceTopic, request->arg("MD").c_str());
|
strlcpy(mqttDeviceTopic, request->arg("MD").c_str(), 33);
|
||||||
strcpy(mqttGroupTopic, request->arg("MG").c_str());
|
strlcpy(mqttGroupTopic, request->arg("MG").c_str(), 33);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLED_DISABLE_HUESYNC
|
||||||
for (int i=0;i<4;i++){
|
for (int i=0;i<4;i++){
|
||||||
String a = "H"+String(i);
|
String a = "H"+String(i);
|
||||||
hueIP[i] = request->arg(a).toInt();
|
hueIP[i] = request->arg(a).toInt();
|
||||||
@ -203,12 +183,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
huePollingEnabled = request->hasArg("HP");
|
huePollingEnabled = request->hasArg("HP");
|
||||||
hueStoreAllowed = true;
|
hueStoreAllowed = true;
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//TIME
|
//TIME
|
||||||
if (subPage == 5)
|
if (subPage == 5)
|
||||||
{
|
{
|
||||||
ntpEnabled = request->hasArg("NT");
|
ntpEnabled = request->hasArg("NT");
|
||||||
|
strlcpy(ntpServerName, request->arg("NS").c_str(), 33);
|
||||||
useAMPM = !request->hasArg("CF");
|
useAMPM = !request->hasArg("CF");
|
||||||
currentTimezone = request->arg("TZ").toInt();
|
currentTimezone = request->arg("TZ").toInt();
|
||||||
utcOffsetSecs = request->arg("UO").toInt();
|
utcOffsetSecs = request->arg("UO").toInt();
|
||||||
@ -296,7 +278,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
if (!otaLock && request->arg("OP").length() > 0)
|
if (!otaLock && request->arg("OP").length() > 0)
|
||||||
{
|
{
|
||||||
strcpy(otaPass,request->arg("OP").c_str());
|
strlcpy(otaPass,request->arg("OP").c_str(), 33);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +290,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset
|
if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset
|
||||||
if (subPage == 2) strip.init(useRGBW,ledCount,skipFirstLed);
|
if (subPage == 2) {
|
||||||
|
strip.init(useRGBW,ledCount,skipFirstLed,disableNLeds);
|
||||||
|
}
|
||||||
if (subPage == 4) alexaInit();
|
if (subPage == 4) alexaInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,11 +357,45 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pos = req.indexOf("IN");
|
pos = req.indexOf("IN");
|
||||||
if (pos < 1) XML_response(request, false);
|
if (pos < 1) XML_response(request);
|
||||||
return true;
|
return true;
|
||||||
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
|
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strip.applyToAllSelected = true;
|
||||||
|
|
||||||
|
//segment select (sets main segment)
|
||||||
|
byte prevMain = strip.getMainSegmentId();
|
||||||
|
pos = req.indexOf("SM=");
|
||||||
|
if (pos > 0) {
|
||||||
|
strip.mainSegment = getNumVal(&req, pos);
|
||||||
|
}
|
||||||
|
byte main = strip.getMainSegmentId();
|
||||||
|
if (main != prevMain) setValuesFromMainSeg();
|
||||||
|
|
||||||
|
pos = req.indexOf("SS=");
|
||||||
|
if (pos > 0) {
|
||||||
|
byte t = getNumVal(&req, pos);
|
||||||
|
if (t < strip.getMaxSegments()) main = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = req.indexOf("SV="); //segment selected
|
||||||
|
if (pos > 0) strip.getSegment(main).setOption(0, (req.charAt(pos+3) != '0'));
|
||||||
|
|
||||||
|
uint16_t startI = strip.getSegment(main).start;
|
||||||
|
uint16_t stopI = strip.getSegment(main).stop;
|
||||||
|
pos = req.indexOf("&S="); //segment start
|
||||||
|
if (pos > 0) {
|
||||||
|
startI = getNumVal(&req, pos);
|
||||||
|
}
|
||||||
|
pos = req.indexOf("S2="); //segment stop
|
||||||
|
if (pos > 0) {
|
||||||
|
stopI = getNumVal(&req, pos);
|
||||||
|
}
|
||||||
|
strip.setSegment(main, startI, stopI);
|
||||||
|
|
||||||
|
main = strip.getMainSegmentId();
|
||||||
|
|
||||||
//set brightness
|
//set brightness
|
||||||
updateVal(&req, "&A=", &bri);
|
updateVal(&req, "&A=", &bri);
|
||||||
|
|
||||||
@ -413,45 +431,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str());
|
colorFromDecOrHexString(colSec, (char*)req.substring(pos + 3).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//set 2nd to white
|
|
||||||
pos = req.indexOf("SW");
|
|
||||||
if (pos > 0) {
|
|
||||||
if(useRGBW) {
|
|
||||||
colSec[3] = 255;
|
|
||||||
colSec[0] = 0;
|
|
||||||
colSec[1] = 0;
|
|
||||||
colSec[2] = 0;
|
|
||||||
} else {
|
|
||||||
colSec[0] = 255;
|
|
||||||
colSec[1] = 255;
|
|
||||||
colSec[2] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//set 2nd to black
|
|
||||||
pos = req.indexOf("SB");
|
|
||||||
if (pos > 0) {
|
|
||||||
colSec[3] = 0;
|
|
||||||
colSec[0] = 0;
|
|
||||||
colSec[1] = 0;
|
|
||||||
colSec[2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set to random hue SR=0->1st SR=1->2nd
|
//set to random hue SR=0->1st SR=1->2nd
|
||||||
pos = req.indexOf("SR");
|
pos = req.indexOf("SR");
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
_setRandomColor(getNumVal(&req, pos));
|
_setRandomColor(getNumVal(&req, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
//set 2nd to 1st
|
|
||||||
pos = req.indexOf("SP");
|
|
||||||
if (pos > 0) {
|
|
||||||
colSec[0] = col[0];
|
|
||||||
colSec[1] = col[1];
|
|
||||||
colSec[2] = col[2];
|
|
||||||
colSec[3] = col[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
//swap 2nd & 1st
|
//swap 2nd & 1st
|
||||||
pos = req.indexOf("SC");
|
pos = req.indexOf("SC");
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
@ -470,27 +455,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
updateVal(&req, "IX=", &effectIntensity);
|
updateVal(&req, "IX=", &effectIntensity);
|
||||||
updateVal(&req, "FP=", &effectPalette, 0, strip.getPaletteCount()-1);
|
updateVal(&req, "FP=", &effectPalette, 0, strip.getPaletteCount()-1);
|
||||||
|
|
||||||
//set hue polling light: 0 -off
|
|
||||||
#ifndef WLED_DISABLE_HUESYNC
|
|
||||||
pos = req.indexOf("HP=");
|
|
||||||
if (pos > 0) {
|
|
||||||
int id = getNumVal(&req, pos);
|
|
||||||
if (id > 0)
|
|
||||||
{
|
|
||||||
if (id < 100) huePollLightId = id;
|
|
||||||
reconnectHue();
|
|
||||||
} else {
|
|
||||||
huePollingEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//set default control mode (0 - RGB, 1 - HSB)
|
|
||||||
pos = req.indexOf("MD=");
|
|
||||||
if (pos > 0) {
|
|
||||||
useHSB = getNumVal(&req, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//set advanced overlay
|
//set advanced overlay
|
||||||
pos = req.indexOf("OL=");
|
pos = req.indexOf("OL=");
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
@ -601,7 +565,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
|
|
||||||
//Segment reverse
|
//Segment reverse
|
||||||
pos = req.indexOf("RV=");
|
pos = req.indexOf("RV=");
|
||||||
if (pos > 0) strip.getSegment(0).setOption(1, req.charAt(pos+3) != '0');
|
if (pos > 0) strip.getSegment(main).setOption(1, req.charAt(pos+3) != '0');
|
||||||
|
|
||||||
//deactivate nightlight if target brightness is reached
|
//deactivate nightlight if target brightness is reached
|
||||||
if (bri == nightlightTargetBri) nightlightActive = false;
|
if (bri == nightlightTargetBri) nightlightActive = false;
|
||||||
@ -660,17 +624,14 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
#ifndef WLED_DISABLE_CRONIXIE
|
#ifndef WLED_DISABLE_CRONIXIE
|
||||||
pos = req.indexOf("NX="); //sets digits to code
|
pos = req.indexOf("NX="); //sets digits to code
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
strcpy(cronixieDisplay,req.substring(pos + 3, pos + 9).c_str());
|
strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6);
|
||||||
setCronixie();
|
setCronixie();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.indexOf("NB=") > 0) //sets backlight
|
pos = req.indexOf("NB=");
|
||||||
|
if (pos > 0) //sets backlight
|
||||||
{
|
{
|
||||||
cronixieBacklight = true;
|
presetApplyFx = (req.charAt(pos+3) != '0');
|
||||||
if (req.indexOf("NB=0") > 0)
|
|
||||||
{
|
|
||||||
cronixieBacklight = false;
|
|
||||||
}
|
|
||||||
if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight);
|
if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight);
|
||||||
overlayRefreshedTime = 0;
|
overlayRefreshedTime = 0;
|
||||||
}
|
}
|
||||||
@ -692,7 +653,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
|
|
||||||
//internal call, does not send XML response
|
//internal call, does not send XML response
|
||||||
pos = req.indexOf("IN");
|
pos = req.indexOf("IN");
|
||||||
if (pos < 1) XML_response(request, (req.indexOf("&IT") > 0)); //include theme if firstload
|
if (pos < 1) XML_response(request);
|
||||||
|
|
||||||
pos = req.indexOf("&NN"); //do not send UDP notifications this time
|
pos = req.indexOf("&NN"); //do not send UDP notifications this time
|
||||||
colorUpdated((pos > 0) ? 5:1);
|
colorUpdated((pos > 0) ? 5:1);
|
||||||
|
@ -1,40 +1,82 @@
|
|||||||
/*
|
/*
|
||||||
* Utility for SPIFFS filesystem & Serial console
|
* Utility for SPIFFS filesystem & Serial console
|
||||||
*/
|
*/
|
||||||
|
enum class AdaState {
|
||||||
|
Header_A,
|
||||||
|
Header_d,
|
||||||
|
Header_a,
|
||||||
|
Header_CountHi,
|
||||||
|
Header_CountLo,
|
||||||
|
Header_CountCheck,
|
||||||
|
Data_Red,
|
||||||
|
Data_Green,
|
||||||
|
Data_Blue
|
||||||
|
};
|
||||||
|
|
||||||
void handleSerial()
|
void handleSerial()
|
||||||
{
|
{
|
||||||
if (Serial.available() > 0) //support for Adalight protocol to high-speed control LEDs over serial
|
#ifdef WLED_ENABLE_ADALIGHT
|
||||||
|
static auto state = AdaState::Header_A;
|
||||||
|
static uint16_t count = 0;
|
||||||
|
static uint16_t pixel = 0;
|
||||||
|
static byte check = 0x00;
|
||||||
|
static byte red = 0x00;
|
||||||
|
static byte green = 0x00;
|
||||||
|
|
||||||
|
while (Serial.available() > 0)
|
||||||
{
|
{
|
||||||
if (!Serial.find("Ada")) return;
|
|
||||||
|
|
||||||
if (!realtimeActive && bri == 0) strip.setBrightness(briLast);
|
|
||||||
arlsLock(realtimeTimeoutMs);
|
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
byte hi = Serial.read();
|
byte next = Serial.read();
|
||||||
byte ledc = Serial.read();
|
switch (state) {
|
||||||
byte chk = Serial.read();
|
case AdaState::Header_A:
|
||||||
if(chk != (hi ^ ledc ^ 0x55)) return;
|
if (next == 'A') state = AdaState::Header_d;
|
||||||
if (ledCount < ledc) ledc = ledCount;
|
break;
|
||||||
|
case AdaState::Header_d:
|
||||||
byte sc[3]; int t =-1; int to = 0;
|
if (next == 'd') state = AdaState::Header_a;
|
||||||
for (int i=0; i < ledc; i++)
|
else state = AdaState::Header_A;
|
||||||
{
|
break;
|
||||||
for (byte j=0; j<3; j++)
|
case AdaState::Header_a:
|
||||||
{
|
if (next == 'a') state = AdaState::Header_CountHi;
|
||||||
while (Serial.peek()<0) //no data yet available
|
else state = AdaState::Header_A;
|
||||||
{
|
break;
|
||||||
yield();
|
case AdaState::Header_CountHi:
|
||||||
to++;
|
pixel = 0;
|
||||||
if (to>15) {strip.show(); return;} //unexpected end of transmission
|
count = next * 0x100;
|
||||||
|
check = next;
|
||||||
|
state = AdaState::Header_CountLo;
|
||||||
|
break;
|
||||||
|
case AdaState::Header_CountLo:
|
||||||
|
count += next + 1;
|
||||||
|
check = check ^ next ^ 0x55;
|
||||||
|
state = AdaState::Header_CountCheck;
|
||||||
|
break;
|
||||||
|
case AdaState::Header_CountCheck:
|
||||||
|
if (check == next) state = AdaState::Data_Red;
|
||||||
|
else state = AdaState::Header_A;
|
||||||
|
break;
|
||||||
|
case AdaState::Data_Red:
|
||||||
|
red = next;
|
||||||
|
state = AdaState::Data_Green;
|
||||||
|
break;
|
||||||
|
case AdaState::Data_Green:
|
||||||
|
green = next;
|
||||||
|
state = AdaState::Data_Blue;
|
||||||
|
break;
|
||||||
|
case AdaState::Data_Blue:
|
||||||
|
byte blue = next;
|
||||||
|
setRealtimePixel(pixel++, red, green, blue, 0);
|
||||||
|
if (--count > 0) state = AdaState::Data_Red;
|
||||||
|
else {
|
||||||
|
if (!realtimeActive && bri == 0) strip.setBrightness(briLast);
|
||||||
|
arlsLock(realtimeTimeoutMs);
|
||||||
|
|
||||||
|
strip.show();
|
||||||
|
state = AdaState::Header_A;
|
||||||
}
|
}
|
||||||
to = 0;
|
break;
|
||||||
sc[j] = Serial.read();
|
|
||||||
}
|
|
||||||
setRealtimePixel(i,sc[0],sc[1],sc[2],0);
|
|
||||||
}
|
}
|
||||||
strip.show();
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,12 @@ void wledInit()
|
|||||||
EEPROM.begin(EEPSIZE);
|
EEPROM.begin(EEPSIZE);
|
||||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
|
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
|
||||||
if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30;
|
if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30;
|
||||||
#ifndef ARDUINO_ARCH_ESP32
|
|
||||||
|
disableNLeds = EEPROM.read(2213);
|
||||||
|
//this was reading 255 after inital flash causing bootloop. Don't know why.
|
||||||
|
disableNLeds = disableNLeds != 255 ? disableNLeds : 0;
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
#if LEDPIN == 3
|
#if LEDPIN == 3
|
||||||
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram
|
||||||
#endif
|
#endif
|
||||||
@ -25,7 +30,7 @@ void wledInit()
|
|||||||
DEBUG_PRINT("heap ");
|
DEBUG_PRINT("heap ");
|
||||||
DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
|
||||||
strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly
|
strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204),disableNLeds); //init LEDs quickly
|
||||||
strip.setBrightness(0);
|
strip.setBrightness(0);
|
||||||
|
|
||||||
DEBUG_PRINT("LEDs inited. heap usage ~");
|
DEBUG_PRINT("LEDs inited. heap usage ~");
|
||||||
@ -85,10 +90,6 @@ void wledInit()
|
|||||||
|
|
||||||
//HTTP server page init
|
//HTTP server page init
|
||||||
initServer();
|
initServer();
|
||||||
|
|
||||||
strip.service();
|
|
||||||
|
|
||||||
initConnection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,7 +140,10 @@ void initAP(bool resetAP=false){
|
|||||||
if (udpPort > 0 && udpPort != ntpLocalPort)
|
if (udpPort > 0 && udpPort != ntpLocalPort)
|
||||||
{
|
{
|
||||||
udpConnected = notifierUdp.begin(udpPort);
|
udpConnected = notifierUdp.begin(udpPort);
|
||||||
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
}
|
||||||
|
if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort)
|
||||||
|
{
|
||||||
|
udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||||
@ -152,7 +156,7 @@ void initConnection()
|
|||||||
{
|
{
|
||||||
WiFi.disconnect(); //close old connections
|
WiFi.disconnect(); //close old connections
|
||||||
|
|
||||||
if (staticIP[0] != 0)
|
if (staticIP[0] != 0 && staticGateway[0] != 0)
|
||||||
{
|
{
|
||||||
WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8,8,8,8));
|
WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8,8,8,8));
|
||||||
} else
|
} else
|
||||||
@ -230,7 +234,7 @@ void initInterfaces() {
|
|||||||
if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||||
|
|
||||||
initBlynk(blynkApiKey);
|
initBlynk(blynkApiKey);
|
||||||
initE131();
|
e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT);
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
initMqtt();
|
initMqtt();
|
||||||
interfacesInited = true;
|
interfacesInited = true;
|
||||||
@ -238,25 +242,44 @@ void initInterfaces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte stacO = 0;
|
byte stacO = 0;
|
||||||
|
uint32_t lastHeap;
|
||||||
|
unsigned long heapTime = 0;
|
||||||
|
|
||||||
void handleConnection() {
|
void handleConnection() {
|
||||||
//TODO: reconnect if heap <8000
|
if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return;
|
||||||
byte stac = 0;
|
if (lastReconnectAttempt == 0) initConnection();
|
||||||
#ifdef ESP8266
|
|
||||||
stac = wifi_softap_get_station_num();
|
//reconnect WiFi to clear stale allocations if heap gets too low
|
||||||
#else
|
if (millis() - heapTime > 5000)
|
||||||
wifi_sta_list_t stationList;
|
|
||||||
esp_wifi_ap_get_sta_list(&stationList);
|
|
||||||
stac = stationList.num;
|
|
||||||
#endif
|
|
||||||
if (stac != stacO)
|
|
||||||
{
|
{
|
||||||
stacO = stac;
|
uint32_t heap = ESP.getFreeHeap();
|
||||||
DEBUG_PRINT("Connected AP clients: ");
|
if (heap < 9000 && lastHeap < 9000) {
|
||||||
DEBUG_PRINTLN(stac);
|
DEBUG_PRINT("Heap too low! ");
|
||||||
if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected
|
DEBUG_PRINTLN(heap);
|
||||||
if (stac) WiFi.disconnect(); //disable search so that AP can work
|
forceReconnect = true;
|
||||||
else initConnection(); //restart search
|
}
|
||||||
|
lastHeap = heap;
|
||||||
|
heapTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte stac = 0;
|
||||||
|
if (apActive) {
|
||||||
|
#ifdef ESP8266
|
||||||
|
stac = wifi_softap_get_station_num();
|
||||||
|
#else
|
||||||
|
wifi_sta_list_t stationList;
|
||||||
|
esp_wifi_ap_get_sta_list(&stationList);
|
||||||
|
stac = stationList.num;
|
||||||
|
#endif
|
||||||
|
if (stac != stacO)
|
||||||
|
{
|
||||||
|
stacO = stac;
|
||||||
|
DEBUG_PRINT("Connected AP clients: ");
|
||||||
|
DEBUG_PRINTLN(stac);
|
||||||
|
if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected
|
||||||
|
if (stac) WiFi.disconnect(); //disable search so that AP can work
|
||||||
|
else initConnection(); //restart search
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (forceReconnect) {
|
if (forceReconnect) {
|
||||||
@ -273,7 +296,7 @@ void handleConnection() {
|
|||||||
interfacesInited = false;
|
interfacesInited = false;
|
||||||
initConnection();
|
initConnection();
|
||||||
}
|
}
|
||||||
if (millis() - lastReconnectAttempt > 300000 && WLED_WIFI_CONFIGURED) initConnection();
|
if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) initConnection();
|
||||||
if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == 1)) initAP();
|
if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == 1)) initAP();
|
||||||
} else if (!interfacesInited) { //newly connected
|
} else if (!interfacesInited) { //newly connected
|
||||||
DEBUG_PRINTLN("");
|
DEBUG_PRINTLN("");
|
||||||
@ -307,13 +330,3 @@ int getSignalQuality(int rssi)
|
|||||||
}
|
}
|
||||||
return quality;
|
return quality;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkClientIsMobile(String useragent)
|
|
||||||
{
|
|
||||||
//to save complexity this function is not comprehensive
|
|
||||||
if (useragent.indexOf("Android") >= 0) return true;
|
|
||||||
if (useragent.indexOf("iPhone") >= 0) return true;
|
|
||||||
if (useragent.indexOf("iPod") >= 0) return true;
|
|
||||||
if (useragent.indexOf("iPad") >= 0) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -38,7 +38,7 @@ void notify(byte callMode, bool followUp=false)
|
|||||||
//0: old 1: supports white 2: supports secondary color
|
//0: old 1: supports white 2: supports secondary color
|
||||||
//3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
//3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
||||||
//6: supports timebase syncing, 29 byte packet 7: supports tertiary color
|
//6: supports timebase syncing, 29 byte packet 7: supports tertiary color
|
||||||
udpOut[11] = 6;
|
udpOut[11] = 7;
|
||||||
udpOut[12] = colSec[0];
|
udpOut[12] = colSec[0];
|
||||||
udpOut[13] = colSec[1];
|
udpOut[13] = colSec[1];
|
||||||
udpOut[14] = colSec[2];
|
udpOut[14] = colSec[2];
|
||||||
@ -47,10 +47,12 @@ void notify(byte callMode, bool followUp=false)
|
|||||||
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
||||||
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
||||||
udpOut[19] = effectPalette;
|
udpOut[19] = effectPalette;
|
||||||
/*udpOut[20] = colTer[0];
|
uint32_t colTer = strip.getSegment(strip.getMainSegmentId()).colors[2];
|
||||||
udpOut[21] = colTer[1];
|
udpOut[20] = (colTer >> 16) & 0xFF;
|
||||||
udpOut[22] = colTer[2];
|
udpOut[21] = (colTer >> 8) & 0xFF;
|
||||||
udpOut[23] = colTer[3];*/
|
udpOut[22] = (colTer >> 0) & 0xFF;
|
||||||
|
udpOut[23] = (colTer >> 24) & 0xFF;
|
||||||
|
|
||||||
udpOut[24] = followUp;
|
udpOut[24] = followUp;
|
||||||
uint32_t t = millis() + strip.timebase;
|
uint32_t t = millis() + strip.timebase;
|
||||||
udpOut[25] = (t >> 24) & 0xFF;
|
udpOut[25] = (t >> 24) & 0xFF;
|
||||||
@ -86,36 +88,26 @@ void arlsLock(uint32_t timeoutMs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void initE131(){
|
void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
||||||
if (WLED_CONNECTED && e131Enabled)
|
|
||||||
{
|
|
||||||
if (e131 == nullptr) e131 = new E131();
|
|
||||||
e131->begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe);
|
|
||||||
} else {
|
|
||||||
e131Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void handleE131(){
|
|
||||||
//E1.31 protocol support
|
//E1.31 protocol support
|
||||||
if(WLED_CONNECTED && e131Enabled) {
|
uint16_t uni = htons(p->universe);
|
||||||
uint16_t len = e131->parsePacket();
|
if (uni < e131Universe || uni >= e131Universe + E131_MAX_UNIVERSE_COUNT) return;
|
||||||
if (!len || e131->universe < e131Universe || e131->universe > e131Universe +4) return;
|
|
||||||
len /= 3; //one LED is 3 DMX channels
|
uint16_t len = htons(p->property_value_count) -1;
|
||||||
|
len /= 3; //one LED is 3 DMX channels
|
||||||
uint16_t multipacketOffset = (e131->universe - e131Universe)*170; //if more than 170 LEDs (510 channels), client will send in next higher universe
|
|
||||||
if (ledCount <= multipacketOffset) return;
|
uint16_t multipacketOffset = (uni - e131Universe)*170; //if more than 170 LEDs (510 channels), client will send in next higher universe
|
||||||
|
if (ledCount <= multipacketOffset) return;
|
||||||
|
|
||||||
arlsLock(realtimeTimeoutMs);
|
arlsLock(realtimeTimeoutMs);
|
||||||
if (len + multipacketOffset > ledCount) len = ledCount - multipacketOffset;
|
if (len + multipacketOffset > ledCount) len = ledCount - multipacketOffset;
|
||||||
|
|
||||||
for (uint16_t i = 0; i < len; i++) {
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
int j = i * 3;
|
int j = i * 3 +1;
|
||||||
setRealtimePixel(i + multipacketOffset, e131->data[j], e131->data[j+1], e131->data[j+2], 0);
|
setRealtimePixel(i + multipacketOffset, p->property_values[j], p->property_values[j+1], p->property_values[j+2], 0);
|
||||||
}
|
|
||||||
strip.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e131NewData = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -126,7 +118,11 @@ void handleNotifications()
|
|||||||
notify(notificationSentCallMode,true);
|
notify(notificationSentCallMode,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleE131();
|
if (e131NewData && millis() - strip.getLastShow() > 15)
|
||||||
|
{
|
||||||
|
e131NewData = false;
|
||||||
|
strip.show();
|
||||||
|
}
|
||||||
|
|
||||||
//unlock strip when realtime UDP times out
|
//unlock strip when realtime UDP times out
|
||||||
if (realtimeActive && millis() > realtimeTimeout)
|
if (realtimeActive && millis() > realtimeTimeout)
|
||||||
@ -176,6 +172,7 @@ void handleNotifications()
|
|||||||
{
|
{
|
||||||
//ignore notification if received within a second after sending a notification ourselves
|
//ignore notification if received within a second after sending a notification ourselves
|
||||||
if (millis() - notificationSentTime < 1000) return;
|
if (millis() - notificationSentTime < 1000) return;
|
||||||
|
if (udpIn[1] > 199) return; //do not receive custom versions
|
||||||
|
|
||||||
bool someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
bool someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||||
//apply colors from notification
|
//apply colors from notification
|
||||||
@ -184,7 +181,7 @@ void handleNotifications()
|
|||||||
col[0] = udpIn[3];
|
col[0] = udpIn[3];
|
||||||
col[1] = udpIn[4];
|
col[1] = udpIn[4];
|
||||||
col[2] = udpIn[5];
|
col[2] = udpIn[5];
|
||||||
if (udpIn[11] > 0) //check if sending modules white val is inteded
|
if (udpIn[11] > 0) //sending module's white val is intended
|
||||||
{
|
{
|
||||||
col[3] = udpIn[10];
|
col[3] = udpIn[10];
|
||||||
if (udpIn[11] > 1)
|
if (udpIn[11] > 1)
|
||||||
@ -197,17 +194,14 @@ void handleNotifications()
|
|||||||
if (udpIn[11] > 5)
|
if (udpIn[11] > 5)
|
||||||
{
|
{
|
||||||
uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]);
|
uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]);
|
||||||
t -= 2;
|
t += 2;
|
||||||
t -= millis();
|
t -= millis();
|
||||||
strip.timebase = t;
|
strip.timebase = t;
|
||||||
}
|
}
|
||||||
/*if (udpIn[11] > 6)
|
if (udpIn[11] > 6)
|
||||||
{
|
{
|
||||||
colTer[0] = udpIn[20];
|
strip.setColor(2, udpIn[20], udpIn[21], udpIn[22], udpIn[23]); //tertiary color
|
||||||
colTer[1] = udpIn[21];
|
}
|
||||||
colTer[2] = udpIn[22];
|
|
||||||
colSec[3] = udpIn[23];
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +225,7 @@ void handleNotifications()
|
|||||||
if (receiveNotificationBrightness || !someSel) bri = udpIn[2];
|
if (receiveNotificationBrightness || !someSel) bri = udpIn[2];
|
||||||
colorUpdated(3);
|
colorUpdated(3);
|
||||||
|
|
||||||
} else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
|
} else if (udpIn[0] > 0 && udpIn[0] < 5 && receiveDirect) //1 warls //2 drgb //3 drgbw
|
||||||
{
|
{
|
||||||
realtimeIP = notifierUdp.remoteIP();
|
realtimeIP = notifierUdp.remoteIP();
|
||||||
DEBUG_PRINTLN(notifierUdp.remoteIP());
|
DEBUG_PRINTLN(notifierUdp.remoteIP());
|
||||||
@ -273,7 +267,7 @@ void handleNotifications()
|
|||||||
for (uint16_t i = 4; i < packetSize -2; i += 3)
|
for (uint16_t i = 4; i < packetSize -2; i += 3)
|
||||||
{
|
{
|
||||||
if (id >= ledCount) break;
|
if (id >= ledCount) break;
|
||||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* LED methods
|
* LED methods
|
||||||
*/
|
*/
|
||||||
|
void setValuesFromMainSeg()
|
||||||
|
{
|
||||||
|
WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId());
|
||||||
|
colorFromUint32(seg.colors[0]);
|
||||||
|
colorFromUint32(seg.colors[1], true);
|
||||||
|
effectCurrent = seg.mode;
|
||||||
|
effectSpeed = seg.speed;
|
||||||
|
effectIntensity = seg.intensity;
|
||||||
|
effectPalette = seg.palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void resetTimebase()
|
||||||
|
{
|
||||||
|
strip.timebase = 0 - millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void toggleOnOff()
|
void toggleOnOff()
|
||||||
{
|
{
|
||||||
@ -71,6 +88,8 @@ void colorUpdated(int callMode)
|
|||||||
{
|
{
|
||||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
||||||
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
||||||
|
if (callMode != 0 && callMode != 1 && callMode != 5) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments
|
||||||
|
|
||||||
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
|
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
|
||||||
if (!colorChanged())
|
if (!colorChanged())
|
||||||
{
|
{
|
||||||
@ -82,10 +101,14 @@ void colorUpdated(int callMode)
|
|||||||
notify(6);
|
notify(6);
|
||||||
if (callMode != 8) interfaceUpdateCallMode = 6;
|
if (callMode != 8) interfaceUpdateCallMode = 6;
|
||||||
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
||||||
|
if (isPreset) {isPreset = false;}
|
||||||
|
else {currentPreset = -1;}
|
||||||
}
|
}
|
||||||
return; //no change
|
return; //no change
|
||||||
}
|
}
|
||||||
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0;
|
||||||
|
if (isPreset) {isPreset = false;}
|
||||||
|
else {currentPreset = -1;}
|
||||||
if (callMode != 5 && nightlightActive && nightlightFade)
|
if (callMode != 5 && nightlightActive && nightlightFade)
|
||||||
{
|
{
|
||||||
briNlT = bri;
|
briNlT = bri;
|
||||||
@ -97,6 +120,7 @@ void colorUpdated(int callMode)
|
|||||||
colIT[i] = col[i];
|
colIT[i] = col[i];
|
||||||
colSecIT[i] = colSec[i];
|
colSecIT[i] = colSec[i];
|
||||||
}
|
}
|
||||||
|
if (briT == 0 && callMode != 3) resetTimebase();
|
||||||
briIT = bri;
|
briIT = bri;
|
||||||
if (bri > 0) briLast = bri;
|
if (bri > 0) briLast = bri;
|
||||||
|
|
||||||
|
@ -75,7 +75,15 @@ void handleNetworkTime()
|
|||||||
|
|
||||||
void sendNTPPacket()
|
void sendNTPPacket()
|
||||||
{
|
{
|
||||||
WiFi.hostByName(ntpServerName, ntpServerIP);
|
if (!ntpServerIP.fromString(ntpServerName)) //see if server is IP or domain
|
||||||
|
{
|
||||||
|
#ifdef ESP8266
|
||||||
|
WiFi.hostByName(ntpServerName, ntpServerIP, 750);
|
||||||
|
#else
|
||||||
|
WiFi.hostByName(ntpServerName, ntpServerIP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_PRINTLN("send NTP");
|
DEBUG_PRINTLN("send NTP");
|
||||||
byte pbuf[NTP_PACKET_SIZE];
|
byte pbuf[NTP_PACKET_SIZE];
|
||||||
memset(pbuf, 0, NTP_PACKET_SIZE);
|
memset(pbuf, 0, NTP_PACKET_SIZE);
|
||||||
|
@ -17,107 +17,6 @@ void initCronixie()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _nixieDisplay(int num[], uint16_t dur[], uint16_t pausedur[], byte cnt)
|
|
||||||
{
|
|
||||||
strip.setRange(overlayMin, overlayMax, 0);
|
|
||||||
if (num[nixieClockI] >= 0 && !nixiePause)
|
|
||||||
{
|
|
||||||
strip.setIndividual(num[nixieClockI],((uint32_t)colT[3] << 24)| ((uint32_t)colT[0] << 16) | ((uint32_t)colT[1] << 8) | colT[2]);
|
|
||||||
strip.unlock(num[nixieClockI]);
|
|
||||||
}
|
|
||||||
if (!nixiePause)
|
|
||||||
{
|
|
||||||
overlayRefreshMs = dur[nixieClockI];
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayRefreshMs = pausedur[nixieClockI];
|
|
||||||
}
|
|
||||||
if (pausedur[nixieClockI] > 0 && !nixiePause)
|
|
||||||
{
|
|
||||||
nixiePause = true;
|
|
||||||
} else {
|
|
||||||
if (nixieClockI < cnt -1)
|
|
||||||
{
|
|
||||||
nixieClockI++;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
nixieClockI = -1;
|
|
||||||
}
|
|
||||||
nixiePause = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _nixieNumber(int number, int dur)
|
|
||||||
{
|
|
||||||
if (nixieClockI < 0)
|
|
||||||
{
|
|
||||||
DEBUG_PRINT(number);
|
|
||||||
int digitCnt = -1;
|
|
||||||
int digits[4];
|
|
||||||
digits[3] = number/1000;
|
|
||||||
digits[2] = (number/100)%10;
|
|
||||||
digits[1] = (number/10)%10;
|
|
||||||
digits[0] = number%10;
|
|
||||||
if (number > 999) //four digits
|
|
||||||
{
|
|
||||||
digitCnt = 4;
|
|
||||||
} else if (number > 99) //three digits
|
|
||||||
{
|
|
||||||
digitCnt = 3;
|
|
||||||
} else if (number > 9) //two digits
|
|
||||||
{
|
|
||||||
digitCnt = 2;
|
|
||||||
} else { //single digit
|
|
||||||
digitCnt = 1;
|
|
||||||
}
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
for (int i = 0; i < digitCnt; i++)
|
|
||||||
{
|
|
||||||
DEBUG_PRINT(digits[i]);
|
|
||||||
overlayArr[digitCnt-1-i] = digits[i];
|
|
||||||
overlayDur[digitCnt-1-i] = ((dur/4)*3)/digitCnt;
|
|
||||||
overlayPauseDur[digitCnt-1-i] = 0;
|
|
||||||
}
|
|
||||||
DEBUG_PRINTLN(" ");
|
|
||||||
for (int i = 1; i < digitCnt; i++)
|
|
||||||
{
|
|
||||||
if (overlayArr[i] == overlayArr[i-1])
|
|
||||||
{
|
|
||||||
overlayPauseDur[i-1] = dur/12;
|
|
||||||
overlayDur[i-1] = overlayDur[i-1]-dur/12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = digitCnt; i < 6; i++)
|
|
||||||
{
|
|
||||||
overlayArr[i] = -1;
|
|
||||||
overlayDur[i] = 0;
|
|
||||||
overlayPauseDur[i] = 0;
|
|
||||||
}
|
|
||||||
overlayPauseDur[5] = dur/4;
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
if (overlayArr[i] != -1)
|
|
||||||
{
|
|
||||||
overlayArr[i] = overlayArr[i] + overlayMin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i <6; i++)
|
|
||||||
{
|
|
||||||
DEBUG_PRINT(overlayArr[i]);
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
DEBUG_PRINT(overlayDur[i]);
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
DEBUG_PRINT(overlayPauseDur[i]);
|
|
||||||
DEBUG_PRINT(" ");
|
|
||||||
}
|
|
||||||
DEBUG_PRINTLN(" ");
|
|
||||||
nixieClockI = 0;
|
|
||||||
} else {
|
|
||||||
_nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void handleOverlays()
|
void handleOverlays()
|
||||||
{
|
{
|
||||||
if (millis() - overlayRefreshedTime > overlayRefreshMs)
|
if (millis() - overlayRefreshedTime > overlayRefreshMs)
|
||||||
@ -129,14 +28,15 @@ void handleOverlays()
|
|||||||
{
|
{
|
||||||
case 0: break;//no overlay
|
case 0: break;//no overlay
|
||||||
case 1: _overlayAnalogClock(); break;//2 analog clock
|
case 1: _overlayAnalogClock(); break;//2 analog clock
|
||||||
case 2: _overlayNixieClock(); break;//nixie 1-digit
|
case 2: break;//nixie 1-digit, removed
|
||||||
case 3: _overlayCronixie();//Diamex cronixie clock kit
|
case 3: _overlayCronixie();//Diamex cronixie clock kit
|
||||||
}
|
}
|
||||||
if (!countdownMode || overlayCurrent < 2) checkCountdown(); //countdown macro activation must work
|
if (!countdownMode || overlayCurrent < 3) checkCountdown(); //countdown macro activation must work
|
||||||
overlayRefreshedTime = millis();
|
overlayRefreshedTime = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _overlayAnalogClock()
|
void _overlayAnalogClock()
|
||||||
{
|
{
|
||||||
int overlaySize = overlayMax - overlayMin +1;
|
int overlaySize = overlayMax - overlayMin +1;
|
||||||
@ -182,98 +82,6 @@ void _overlayAnalogClock()
|
|||||||
overlayRefreshMs = 998;
|
overlayRefreshMs = 998;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _overlayNixieClock()
|
|
||||||
{
|
|
||||||
#ifdef WLED_DISABLE_CRONIXIE
|
|
||||||
if (countdownMode) checkCountdown();
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (countdownMode)
|
|
||||||
{
|
|
||||||
_overlayNixieCountdown(); return;
|
|
||||||
}
|
|
||||||
if (nixieClockI < 0)
|
|
||||||
{
|
|
||||||
overlayArr[0] = hour(local);
|
|
||||||
if (useAMPM) overlayArr[0] = overlayArr[0]%12;
|
|
||||||
overlayArr[1] = -1;
|
|
||||||
if (overlayArr[0] > 9)
|
|
||||||
{
|
|
||||||
overlayArr[1] = overlayArr[0]%10;
|
|
||||||
overlayArr[0] = overlayArr[0]/10;
|
|
||||||
}
|
|
||||||
overlayArr[2] = minute(local);
|
|
||||||
overlayArr[3] = overlayArr[2]%10;
|
|
||||||
overlayArr[2] = overlayArr[2]/10;
|
|
||||||
overlayArr[4] = -1;
|
|
||||||
overlayArr[5] = -1;
|
|
||||||
if (analogClockSecondsTrail)
|
|
||||||
{
|
|
||||||
overlayArr[4] = second(local);
|
|
||||||
overlayArr[5] = overlayArr[4]%10;
|
|
||||||
overlayArr[4] = overlayArr[4]/10;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
if (overlayArr[i] != -1)
|
|
||||||
{
|
|
||||||
overlayArr[i] = overlayArr[i] + overlayMin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
overlayDur[0] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
if (overlayArr[1] == overlayArr[0])
|
|
||||||
{
|
|
||||||
overlayPauseDur[0] = 3 + 3*(255 - overlaySpeed);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayPauseDur[0] = 0;
|
|
||||||
}
|
|
||||||
if (overlayArr[1] == -1)
|
|
||||||
{
|
|
||||||
overlayDur[1] = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayDur[1] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
}
|
|
||||||
overlayPauseDur[1] = 9 + 9*(255 - overlaySpeed);
|
|
||||||
|
|
||||||
overlayDur[2] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
if (overlayArr[2] == overlayArr[3])
|
|
||||||
{
|
|
||||||
overlayPauseDur[2] = 3 + 3*(255 - overlaySpeed);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayPauseDur[2] = 0;
|
|
||||||
}
|
|
||||||
overlayDur[3] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
overlayPauseDur[3] = 9 + 9*(255 - overlaySpeed);
|
|
||||||
|
|
||||||
if (overlayArr[4] == -1)
|
|
||||||
{
|
|
||||||
overlayDur[4] = 0;
|
|
||||||
overlayPauseDur[4] = 0;
|
|
||||||
overlayDur[5] = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayDur[4] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
if (overlayArr[5] == overlayArr[4])
|
|
||||||
{
|
|
||||||
overlayPauseDur[4] = 3 + 3*(255 - overlaySpeed);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
overlayPauseDur[4] = 0;
|
|
||||||
}
|
|
||||||
overlayDur[5] = 12 + 12*(255 - overlaySpeed);
|
|
||||||
}
|
|
||||||
overlayPauseDur[5] = 22 + 22*(255 - overlaySpeed);
|
|
||||||
|
|
||||||
nixieClockI = 0;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
_nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void _overlayAnalogCountdown()
|
void _overlayAnalogCountdown()
|
||||||
{
|
{
|
||||||
@ -319,33 +127,3 @@ void _overlayAnalogCountdown()
|
|||||||
}
|
}
|
||||||
overlayRefreshMs = 998;
|
overlayRefreshMs = 998;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
@ -2,12 +2,19 @@
|
|||||||
* Color conversion methods
|
* Color conversion methods
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void colorFromUint32(uint32_t in)
|
void colorFromUint32(uint32_t in, bool secondary)
|
||||||
{
|
{
|
||||||
col[3] = in >> 24 & 0xFF;
|
if (secondary) {
|
||||||
col[0] = in >> 16 & 0xFF;
|
colSec[3] = in >> 24 & 0xFF;
|
||||||
col[1] = in >> 8 & 0xFF;
|
colSec[0] = in >> 16 & 0xFF;
|
||||||
col[2] = in & 0xFF;
|
colSec[1] = in >> 8 & 0xFF;
|
||||||
|
colSec[2] = in & 0xFF;
|
||||||
|
} else {
|
||||||
|
col[3] = in >> 24 & 0xFF;
|
||||||
|
col[0] = in >> 16 & 0xFF;
|
||||||
|
col[1] = in >> 8 & 0xFF;
|
||||||
|
col[2] = in & 0xFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
|
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
* MQTT communication protocol for home automation
|
* MQTT communication protocol for home automation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef WLED_ENABLE_MQTT
|
||||||
|
|
||||||
void parseMQTTBriPayload(char* payload)
|
void parseMQTTBriPayload(char* payload)
|
||||||
{
|
{
|
||||||
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
|
if (strstr(payload, "ON") || strstr(payload, "on") || strstr(payload, "true")) {bri = briLast; colorUpdated(1);}
|
||||||
@ -19,7 +21,6 @@ void onMqttConnect(bool sessionPresent)
|
|||||||
{
|
{
|
||||||
//(re)subscribe to required topics
|
//(re)subscribe to required topics
|
||||||
char subuf[38];
|
char subuf[38];
|
||||||
strcpy(subuf, mqttDeviceTopic);
|
|
||||||
|
|
||||||
if (mqttDeviceTopic[0] != 0)
|
if (mqttDeviceTopic[0] != 0)
|
||||||
{
|
{
|
||||||
@ -43,7 +44,6 @@ void onMqttConnect(bool sessionPresent)
|
|||||||
mqtt->subscribe(subuf, 0);
|
mqtt->subscribe(subuf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
doSendHADiscovery = true;
|
|
||||||
doPublishMqtt = true;
|
doPublishMqtt = true;
|
||||||
DEBUG_PRINTLN("MQTT ready");
|
DEBUG_PRINTLN("MQTT ready");
|
||||||
}
|
}
|
||||||
@ -84,147 +84,29 @@ void publishMqtt()
|
|||||||
strcat(subuf, "/g");
|
strcat(subuf, "/g");
|
||||||
mqtt->publish(subuf, 0, true, s);
|
mqtt->publish(subuf, 0, true, s);
|
||||||
|
|
||||||
sprintf(s, "#%06X", col[3]*16777216 + col[0]*65536 + col[1]*256 + col[2]);
|
sprintf(s, "#%06X", (col[3] << 24) | (col[0] << 16) | (col[1] << 8) | (col[2]));
|
||||||
strcpy(subuf, mqttDeviceTopic);
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
strcat(subuf, "/c");
|
strcat(subuf, "/c");
|
||||||
mqtt->publish(subuf, 0, true, s);
|
mqtt->publish(subuf, 0, true, s);
|
||||||
|
|
||||||
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
|
strcat(subuf, "/status");
|
||||||
|
mqtt->publish(subuf, 0, true, "online");
|
||||||
|
|
||||||
char apires[1024];
|
char apires[1024];
|
||||||
XML_response(nullptr, false, apires);
|
XML_response(nullptr, apires);
|
||||||
strcpy(subuf, mqttDeviceTopic);
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
strcat(subuf, "/v");
|
strcat(subuf, "/v");
|
||||||
mqtt->publish(subuf, 0, true, apires);
|
mqtt->publish(subuf, 0, true, apires);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char HA_static_JSON[] PROGMEM = R"=====(,"bri_val_tpl":"{{value}}","rgb_cmd_tpl":"{{'#%02x%02x%02x' | format(red, green, blue)}}","rgb_val_tpl":"{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}","qos":0,"opt":true,"pl_on":"ON","pl_off":"OFF","fx_val_tpl":"{{value}}","fx_list":[)=====";
|
|
||||||
|
|
||||||
char* buffer;
|
//HA autodiscovery was removed in favor of the native integration in HA v0.102.0
|
||||||
|
|
||||||
void sendHADiscoveryMQTT()
|
|
||||||
{
|
|
||||||
//TODO: With LwIP 1 the ESP loses MQTT connection and causes memory leak when sending discovery packet
|
|
||||||
#if ARDUINO_ARCH_ESP32 || LWIP_VERSION_MAJOR > 1
|
|
||||||
/*
|
|
||||||
|
|
||||||
YYYY is device topic
|
|
||||||
XXXX is device name
|
|
||||||
|
|
||||||
Send out HA MQTT Discovery message on MQTT connect (~2.4kB):
|
|
||||||
{
|
|
||||||
"name": "XXXX",
|
|
||||||
"stat_t":"YYYY/c",
|
|
||||||
"cmd_t":"YYYY",
|
|
||||||
"rgb_stat_t":"YYYY/c",
|
|
||||||
"rgb_cmd_t":"YYYY/col",
|
|
||||||
"bri_cmd_t":"YYYY",
|
|
||||||
"bri_stat_t":"YYYY/g",
|
|
||||||
"bri_val_tpl":"{{value}}",
|
|
||||||
"rgb_cmd_tpl":"{{'#%02x%02x%02x' | format(red, green, blue)}}",
|
|
||||||
"rgb_val_tpl":"{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}",
|
|
||||||
"qos": 0,
|
|
||||||
"opt":true,
|
|
||||||
"pl_on": "ON",
|
|
||||||
"pl_off": "OFF",
|
|
||||||
"fx_cmd_t":"YYYY/api",
|
|
||||||
"fx_stat_t":"YYYY/api",
|
|
||||||
"fx_val_tpl":"{{value}}",
|
|
||||||
"fx_list":[
|
|
||||||
"[FX=00] Solid",
|
|
||||||
"[FX=01] Blink",
|
|
||||||
"[FX=02] ...",
|
|
||||||
"[FX=79] Ripple"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
doSendHADiscovery = false;
|
|
||||||
if (mqtt == nullptr || !mqtt->connected()) return;
|
|
||||||
buffer = new char[2400];
|
|
||||||
if (!buffer) {delete[] buffer; return;}
|
|
||||||
|
|
||||||
char bufc[36], bufcol[38], bufg[36], bufapi[38];
|
|
||||||
|
|
||||||
strcpy(bufc, mqttDeviceTopic);
|
|
||||||
strcpy(bufcol, mqttDeviceTopic);
|
|
||||||
strcpy(bufg, mqttDeviceTopic);
|
|
||||||
strcpy(bufapi, mqttDeviceTopic);
|
|
||||||
|
|
||||||
strcat(bufc, "/c");
|
|
||||||
strcat(bufcol, "/col");
|
|
||||||
strcat(bufg, "/g");
|
|
||||||
strcat(bufapi, "/api");
|
|
||||||
|
|
||||||
StaticJsonDocument<JSON_OBJECT_SIZE(9) +512> root;
|
|
||||||
root["name"] = serverDescription;
|
|
||||||
root["stat_t"] = bufc;
|
|
||||||
root["cmd_t"] = mqttDeviceTopic;
|
|
||||||
root["rgb_stat_t"] = bufc;
|
|
||||||
root["rgb_cmd_t"] = bufcol;
|
|
||||||
root["bri_cmd_t"] = mqttDeviceTopic;
|
|
||||||
root["bri_stat_t"] = bufg;
|
|
||||||
root["fx_cmd_t"] = bufapi;
|
|
||||||
root["fx_stat_t"] = bufapi;
|
|
||||||
|
|
||||||
size_t jlen = measureJson(root);
|
|
||||||
//DEBUG_PRINTLN(jlen);
|
|
||||||
serializeJson(root, buffer, jlen);
|
|
||||||
|
|
||||||
//add values which don't change
|
|
||||||
strcpy_P(buffer + jlen -1, HA_static_JSON);
|
|
||||||
|
|
||||||
olen = 0;
|
|
||||||
obuf = buffer + jlen -1 + strlen_P(HA_static_JSON);
|
|
||||||
|
|
||||||
//add fx_list
|
|
||||||
uint16_t jmnlen = strlen_P(JSON_mode_names);
|
|
||||||
uint16_t nameStart = 0, nameEnd = 0;
|
|
||||||
int i = 0;
|
|
||||||
bool isNameStart = true;
|
|
||||||
|
|
||||||
for (uint16_t j = 0; j < jmnlen; j++)
|
|
||||||
{
|
|
||||||
if (pgm_read_byte(JSON_mode_names + j) == '\"' || j == jmnlen -1)
|
|
||||||
{
|
|
||||||
if (isNameStart)
|
|
||||||
{
|
|
||||||
nameStart = j +1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nameEnd = j;
|
|
||||||
char mdnfx[64], mdn[56];
|
|
||||||
uint16_t namelen = nameEnd - nameStart;
|
|
||||||
strncpy_P(mdn, JSON_mode_names + nameStart, namelen);
|
|
||||||
mdn[namelen] = 0;
|
|
||||||
snprintf(mdnfx, 64, "\"[FX=%02d] %s\",", i, mdn);
|
|
||||||
oappend(mdnfx);
|
|
||||||
//DEBUG_PRINTLN(mdnfx);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
isNameStart = !isNameStart;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
olen--;
|
|
||||||
oappend("]}");
|
|
||||||
|
|
||||||
DEBUG_PRINT("HA Discovery Sending >>");
|
|
||||||
DEBUG_PRINTLN(buffer);
|
|
||||||
|
|
||||||
char pubt[25 + 12 + 8];
|
|
||||||
strcpy(pubt, "homeassistant/light/");
|
|
||||||
strcat(pubt, mqttClientID);
|
|
||||||
strcat(pubt, "/config");
|
|
||||||
bool success = mqtt->publish(pubt, 0, true, buffer);
|
|
||||||
DEBUG_PRINTLN(success);
|
|
||||||
yield();
|
|
||||||
delete[] buffer;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool initMqtt()
|
bool initMqtt()
|
||||||
{
|
{
|
||||||
lastMqttReconnectAttempt = millis();
|
lastMqttReconnectAttempt = millis();
|
||||||
if (mqttServer[0] == 0 || !WLED_CONNECTED) return false;
|
if (!mqttEnabled || mqttServer[0] == 0 || !WLED_CONNECTED) return false;
|
||||||
|
|
||||||
if (mqtt == nullptr) {
|
if (mqtt == nullptr) {
|
||||||
mqtt = new AsyncMqttClient();
|
mqtt = new AsyncMqttClient();
|
||||||
@ -243,6 +125,15 @@ bool initMqtt()
|
|||||||
}
|
}
|
||||||
mqtt->setClientId(mqttClientID);
|
mqtt->setClientId(mqttClientID);
|
||||||
if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
|
if (mqttUser[0] && mqttPass[0]) mqtt->setCredentials(mqttUser, mqttPass);
|
||||||
|
|
||||||
|
strcpy(mqttStatusTopic, mqttDeviceTopic);
|
||||||
|
strcat(mqttStatusTopic, "/status");
|
||||||
|
mqtt->setWill(mqttStatusTopic, 0, true, "offline");
|
||||||
mqtt->connect();
|
mqtt->connect();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
bool initMqtt(){return false;}
|
||||||
|
void publishMqtt(){}
|
||||||
|
#endif
|
||||||
|
@ -36,6 +36,10 @@ void initServer()
|
|||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "*");
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "*");
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "*");
|
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "*");
|
||||||
|
|
||||||
|
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
|
request->send_P(200, "text/html", PAGE_liveview);
|
||||||
|
});
|
||||||
|
|
||||||
//settings page
|
//settings page
|
||||||
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
@ -64,7 +68,7 @@ void initServer()
|
|||||||
|
|
||||||
server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
if (!(wifiLock && otaLock)) handleSettingsSet(request, 1);
|
if (!(wifiLock && otaLock)) handleSettingsSet(request, 1);
|
||||||
serveMessage(request, 200,"WiFi settings saved.","Reconnecting now...",255);
|
serveMessage(request, 200,"WiFi settings saved.","Please connect to the new IP (if changed)",129);
|
||||||
forceReconnect = true;
|
forceReconnect = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -75,7 +79,7 @@ void initServer()
|
|||||||
|
|
||||||
server.on("/settings/ui", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/ui", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
handleSettingsSet(request, 3);
|
handleSettingsSet(request, 3);
|
||||||
serveMessage(request, 200,"UI settings saved.","Reloading to apply theme...",122);
|
serveMessage(request, 200,"UI settings saved.","Redirecting...",1);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
@ -90,7 +94,7 @@ void initServer()
|
|||||||
|
|
||||||
server.on("/settings/sec", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings/sec", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
handleSettingsSet(request, 6);
|
handleSettingsSet(request, 6);
|
||||||
if (!doReboot) serveMessage(request, 200,"Security settings saved.","Rebooting now, please wait ~10 seconds...",129);
|
if (!doReboot) serveMessage(request, 200,"Security settings saved.","Rebooting, please wait ~10 seconds...",129);
|
||||||
doReboot = true;
|
doReboot = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,9 +102,20 @@ void initServer()
|
|||||||
serveJson(request);
|
serveJson(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request, JsonObject root) {
|
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) {
|
||||||
if (root.isNull()){request->send(500, "application/json", "{\"error\":\"Parsing failed\"}"); return;}
|
bool verboseResponse = false;
|
||||||
if (deserializeState(root)) { serveJson(request); return; } //if JSON contains "v" (verbose response)
|
if (1) { //scope JsonDocument so it releases its buffer
|
||||||
|
DynamicJsonDocument jsonBuffer(8192);
|
||||||
|
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
|
||||||
|
JsonObject root = jsonBuffer.as<JsonObject>();
|
||||||
|
if (error || root.isNull()) {
|
||||||
|
request->send(400, "application/json", "{\"error\":10}"); return;
|
||||||
|
}
|
||||||
|
verboseResponse = deserializeState(root);
|
||||||
|
}
|
||||||
|
if (verboseResponse) { //if JSON contains "v"
|
||||||
|
serveJson(request); return;
|
||||||
|
}
|
||||||
request->send(200, "application/json", "{\"success\":true}");
|
request->send(200, "application/json", "{\"success\":true}");
|
||||||
});
|
});
|
||||||
server.addHandler(handler);
|
server.addHandler(handler);
|
||||||
@ -143,9 +158,7 @@ void initServer()
|
|||||||
//init ota page
|
//init ota page
|
||||||
#ifndef WLED_DISABLE_OTA
|
#ifndef WLED_DISABLE_OTA
|
||||||
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
olen = 0;
|
request->send_P(200, "text/html", PAGE_update);
|
||||||
getCSSColors();
|
|
||||||
request->send_P(200, "text/html", PAGE_update, msgProcessor);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
@ -158,7 +171,7 @@ void initServer()
|
|||||||
},[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
},[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||||
if(!index){
|
if(!index){
|
||||||
DEBUG_PRINTLN("OTA Update Start");
|
DEBUG_PRINTLN("OTA Update Start");
|
||||||
#ifndef ARDUINO_ARCH_ESP32
|
#ifdef ESP8266
|
||||||
Update.runAsync(true);
|
Update.runAsync(true);
|
||||||
#endif
|
#endif
|
||||||
Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
||||||
@ -227,47 +240,15 @@ void serveIndexOrWelcome(AsyncWebServerRequest *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void getCSSColors()
|
|
||||||
{
|
|
||||||
char cs[6][9];
|
|
||||||
getThemeColors(cs);
|
|
||||||
oappend("<style>:root{--aCol:#"); oappend(cs[0]);
|
|
||||||
oappend(";--bCol:#"); oappend(cs[1]);
|
|
||||||
oappend(";--cCol:#"); oappend(cs[2]);
|
|
||||||
oappend(";--dCol:#"); oappend(cs[3]);
|
|
||||||
oappend(";--sCol:#"); oappend(cs[4]);
|
|
||||||
oappend(";--tCol:#"); oappend(cs[5]);
|
|
||||||
oappend(";--cFn:"); oappend(cssFont);
|
|
||||||
oappend(";}");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void serveIndex(AsyncWebServerRequest* request)
|
void serveIndex(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
bool serveMobile = false;
|
|
||||||
if (uiConfiguration == 0 && request->hasHeader("User-Agent")) serveMobile = checkClientIsMobile(request->getHeader("User-Agent")->value());
|
|
||||||
else if (uiConfiguration == 2) serveMobile = true;
|
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_FS_SERVING
|
#ifdef WLED_ENABLE_FS_SERVING
|
||||||
if (serveMobile)
|
if (handleFileRead(request, "/index.htm")) return;
|
||||||
{
|
|
||||||
if (handleFileRead(request, "/index_mobile.htm")) return;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
if (handleFileRead(request, "/index.htm")) return;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html",
|
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L);
|
||||||
(serveMobile) ? (uint8_t*)PAGE_indexM : PAGE_index,
|
|
||||||
(serveMobile) ? PAGE_indexM_L : PAGE_index_L);
|
|
||||||
|
|
||||||
//error message is not gzipped
|
|
||||||
#ifdef WLED_DISABLE_MOBILE_UI
|
|
||||||
if (!serveMobile) response->addHeader("Content-Encoding","gzip");
|
|
||||||
#else
|
|
||||||
response->addHeader("Content-Encoding","gzip");
|
response->addHeader("Content-Encoding","gzip");
|
||||||
#endif
|
|
||||||
|
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
@ -275,13 +256,6 @@ void serveIndex(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
String msgProcessor(const String& var)
|
String msgProcessor(const String& var)
|
||||||
{
|
{
|
||||||
if (var == "CSS") {
|
|
||||||
char css[512];
|
|
||||||
obuf = css;
|
|
||||||
olen = 0;
|
|
||||||
getCSSColors();
|
|
||||||
return String(obuf);
|
|
||||||
}
|
|
||||||
if (var == "MSG") {
|
if (var == "MSG") {
|
||||||
String messageBody = messageHead;
|
String messageBody = messageHead;
|
||||||
messageBody += "</h2>";
|
messageBody += "</h2>";
|
||||||
@ -312,12 +286,6 @@ String msgProcessor(const String& var)
|
|||||||
|
|
||||||
void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255)
|
void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255)
|
||||||
{
|
{
|
||||||
#ifndef ARDUINO_ARCH_ESP32
|
|
||||||
char buf[256];
|
|
||||||
obuf = buf;
|
|
||||||
#endif
|
|
||||||
olen = 0;
|
|
||||||
getCSSColors();
|
|
||||||
messageHead = headl;
|
messageHead = headl;
|
||||||
messageSub = subl;
|
messageSub = subl;
|
||||||
optionType = optionT;
|
optionType = optionT;
|
||||||
@ -331,7 +299,6 @@ String settingsProcessor(const String& var)
|
|||||||
if (var == "CSS") {
|
if (var == "CSS") {
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
getSettingsJS(optionType, buf);
|
getSettingsJS(optionType, buf);
|
||||||
getCSSColors();
|
|
||||||
return String(buf);
|
return String(buf);
|
||||||
}
|
}
|
||||||
if (var == "SCSS") return String(FPSTR(PAGE_settingsCss));
|
if (var == "SCSS") return String(FPSTR(PAGE_settingsCss));
|
||||||
@ -373,6 +340,6 @@ void serveSettings(AsyncWebServerRequest* request)
|
|||||||
case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break;
|
case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break;
|
||||||
case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break;
|
case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break;
|
||||||
case 255: request->send_P(200, "text/html", PAGE_welcome); break;
|
case 255: request->send_P(200, "text/html", PAGE_welcome); break;
|
||||||
default: request->send_P(200, "text/html", PAGE_settings , settingsProcessor);
|
default: request->send_P(200, "text/html", PAGE_settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,85 @@
|
|||||||
* JSON API (De)serialization
|
* JSON API (De)serialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void deserializeSegment(JsonObject elem, byte it)
|
||||||
|
{
|
||||||
|
byte id = elem["id"] | it;
|
||||||
|
if (id < strip.getMaxSegments())
|
||||||
|
{
|
||||||
|
WS2812FX::Segment& seg = strip.getSegment(id);
|
||||||
|
uint16_t start = elem["start"] | seg.start;
|
||||||
|
int stop = elem["stop"] | -1;
|
||||||
|
|
||||||
|
if (stop < 0) {
|
||||||
|
uint16_t len = elem["len"];
|
||||||
|
stop = (len > 0) ? start + len : seg.stop;
|
||||||
|
}
|
||||||
|
strip.setSegment(id, start, stop);
|
||||||
|
|
||||||
|
JsonArray colarr = elem["col"];
|
||||||
|
if (!colarr.isNull())
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
JsonArray colX = colarr[i];
|
||||||
|
if (colX.isNull()) break;
|
||||||
|
byte sz = colX.size();
|
||||||
|
if (sz > 0 && sz < 5)
|
||||||
|
{
|
||||||
|
int rgbw[] = {0,0,0,0};
|
||||||
|
byte cp = copyArray(colX, rgbw);
|
||||||
|
seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
|
||||||
|
if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0;
|
||||||
|
if (id == strip.getMainSegmentId()) //temporary
|
||||||
|
{
|
||||||
|
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
|
||||||
|
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
||||||
|
seg.setOption(0, elem["sel"] | seg.getOption(0)); //selected
|
||||||
|
seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse
|
||||||
|
//int cln = seg_0["cln"];
|
||||||
|
//temporary, strip object gets updated via colorUpdated()
|
||||||
|
if (id == strip.getMainSegmentId()) {
|
||||||
|
effectCurrent = elem["fx"] | effectCurrent;
|
||||||
|
effectSpeed = elem["sx"] | effectSpeed;
|
||||||
|
effectIntensity = elem["ix"] | effectIntensity;
|
||||||
|
effectPalette = elem["pal"] | effectPalette;
|
||||||
|
} else { //permanent
|
||||||
|
byte fx = elem["fx"] | seg.mode;
|
||||||
|
if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
|
||||||
|
seg.speed = elem["sx"] | seg.speed;
|
||||||
|
seg.intensity = elem["ix"] | seg.intensity;
|
||||||
|
seg.palette = elem["pal"] | seg.palette;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool deserializeState(JsonObject root)
|
bool deserializeState(JsonObject root)
|
||||||
{
|
{
|
||||||
|
strip.applyToAllSelected = false;
|
||||||
bool stateResponse = root["v"] | false;
|
bool stateResponse = root["v"] | false;
|
||||||
|
|
||||||
bri = root["bri"] | bri;
|
bri = root["bri"] | bri;
|
||||||
|
|
||||||
bool on = root["on"] | (bri > 0);
|
bool on = root["on"] | (bri > 0);
|
||||||
if (!on != !bri) toggleOnOff();
|
if (!on != !bri) toggleOnOff();
|
||||||
|
|
||||||
if (root.containsKey("transition"))
|
int tr = root["transition"] | -1;
|
||||||
|
if (tr >= 0)
|
||||||
{
|
{
|
||||||
transitionDelay = root["transition"];
|
transitionDelay = tr;
|
||||||
transitionDelay *= 100;
|
transitionDelay *= 100;
|
||||||
}
|
}
|
||||||
if (root.containsKey("tt"))
|
|
||||||
|
tr = root["tt"] | -1;
|
||||||
|
if (tr >= 0)
|
||||||
{
|
{
|
||||||
transitionDelayTemp = root["tt"];
|
transitionDelayTemp = tr;
|
||||||
transitionDelayTemp *= 100;
|
transitionDelayTemp *= 100;
|
||||||
jsonTransitionOnce = true;
|
jsonTransitionOnce = true;
|
||||||
}
|
}
|
||||||
@ -26,8 +88,17 @@ bool deserializeState(JsonObject root)
|
|||||||
int ps = root["ps"] | -1;
|
int ps = root["ps"] | -1;
|
||||||
if (ps >= 0) applyPreset(ps);
|
if (ps >= 0) applyPreset(ps);
|
||||||
|
|
||||||
int cy = root["pl"] | -1;
|
int cy = root["pl"] | -2;
|
||||||
presetCyclingEnabled = (cy >= 0);
|
if (cy > -2) presetCyclingEnabled = (cy >= 0);
|
||||||
|
JsonObject ccnf = root["ccnf"];
|
||||||
|
presetCycleMin = ccnf["min"] | presetCycleMin;
|
||||||
|
presetCycleMax = ccnf["max"] | presetCycleMax;
|
||||||
|
tr = ccnf["time"] | -1;
|
||||||
|
if (tr >= 2)
|
||||||
|
{
|
||||||
|
presetCycleTime = tr;
|
||||||
|
presetCycleTime *= 100;
|
||||||
|
}
|
||||||
|
|
||||||
JsonObject nl = root["nl"];
|
JsonObject nl = root["nl"];
|
||||||
nightlightActive = nl["on"] | nightlightActive;
|
nightlightActive = nl["on"] | nightlightActive;
|
||||||
@ -43,68 +114,49 @@ bool deserializeState(JsonObject root)
|
|||||||
int timein = root["time"] | -1;
|
int timein = root["time"] | -1;
|
||||||
if (timein != -1) setTime(timein);
|
if (timein != -1) setTime(timein);
|
||||||
|
|
||||||
int it = 0;
|
byte prevMain = strip.getMainSegmentId();
|
||||||
JsonArray segs = root["seg"];
|
strip.mainSegment = root["mainseg"] | prevMain;
|
||||||
for (JsonObject elem : segs)
|
if (strip.getMainSegmentId() != prevMain) setValuesFromMainSeg();
|
||||||
{
|
|
||||||
byte id = elem["id"] | it;
|
|
||||||
if (id < strip.getMaxSegments())
|
|
||||||
{
|
|
||||||
WS2812FX::Segment& seg = strip.getSegment(id);
|
|
||||||
uint16_t start = elem["start"] | seg.start;
|
|
||||||
int stop = elem["stop"] | -1;
|
|
||||||
|
|
||||||
if (stop < 0) {
|
int it = 0;
|
||||||
uint16_t len = elem["len"];
|
JsonVariant segVar = root["seg"];
|
||||||
stop = (len > 0) ? start + len : seg.stop;
|
if (segVar.is<JsonObject>())
|
||||||
}
|
{
|
||||||
strip.setSegment(id, start, stop);
|
int id = segVar["id"] | -1;
|
||||||
|
|
||||||
JsonArray colarr = elem["col"];
|
if (id < 0) { //set all selected segments
|
||||||
if (!colarr.isNull())
|
bool didSet = false;
|
||||||
|
byte lowestActive = 99;
|
||||||
|
for (byte s = 0; s < strip.getMaxSegments(); s++)
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < 3; i++)
|
WS2812FX::Segment sg = strip.getSegment(s);
|
||||||
|
if (sg.isActive())
|
||||||
{
|
{
|
||||||
JsonArray colX = colarr[i];
|
if (lowestActive == 99) lowestActive = s;
|
||||||
if (colX.isNull()) break;
|
if (sg.isSelected()) {
|
||||||
byte sz = colX.size();
|
deserializeSegment(segVar, s);
|
||||||
if (sz > 0 && sz < 5)
|
didSet = true;
|
||||||
{
|
|
||||||
int rgbw[] = {0,0,0,0};
|
|
||||||
byte cp = copyArray(colX, rgbw);
|
|
||||||
seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
|
|
||||||
if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0;
|
|
||||||
if (id == 0) //temporary
|
|
||||||
{
|
|
||||||
if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];}
|
|
||||||
if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!didSet && lowestActive < strip.getMaxSegments()) deserializeSegment(segVar, lowestActive);
|
||||||
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
} else { //set only the segment with the specified ID
|
||||||
seg.setOption(0, elem["sel"] | seg.getOption(0)); //selected
|
deserializeSegment(segVar, it);
|
||||||
seg.setOption(1, elem["rev"] | seg.getOption(1)); //reverse
|
}
|
||||||
//int cln = seg_0["cln"];
|
} else {
|
||||||
//temporary, strip object gets updated via colorUpdated()
|
JsonArray segs = segVar.as<JsonArray>();
|
||||||
if (id == 0) {
|
for (JsonObject elem : segs)
|
||||||
effectCurrent = elem["fx"] | effectCurrent;
|
{
|
||||||
effectSpeed = elem["sx"] | effectSpeed;
|
deserializeSegment(elem, it);
|
||||||
effectIntensity = elem["ix"] | effectIntensity ;
|
it++;
|
||||||
effectPalette = elem["pal"] | effectPalette;
|
|
||||||
} else { //permanent
|
|
||||||
byte fx = elem["fx"] | seg.mode;
|
|
||||||
if (fx != seg.mode && fx < strip.getModeCount()) strip.setMode(id, fx);
|
|
||||||
seg.speed = elem["sx"] | seg.speed;
|
|
||||||
seg.intensity = elem["ix"] | seg.intensity;
|
|
||||||
seg.palette = elem["pal"] | seg.palette;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
colorUpdated(noNotification ? 5:1);
|
colorUpdated(noNotification ? 5:1);
|
||||||
|
|
||||||
|
ps = root["psave"] | -1;
|
||||||
|
if (ps >= 0) savePreset(ps);
|
||||||
|
|
||||||
return stateResponse;
|
return stateResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,18 +185,26 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id)
|
|||||||
root["pal"] = seg.palette;
|
root["pal"] = seg.palette;
|
||||||
root["sel"] = seg.isSelected();
|
root["sel"] = seg.isSelected();
|
||||||
root["rev"] = seg.getOption(1);
|
root["rev"] = seg.getOption(1);
|
||||||
root["cln"] = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void serializeState(JsonObject root)
|
void serializeState(JsonObject root)
|
||||||
{
|
{
|
||||||
|
if (errorFlag) root["error"] = errorFlag;
|
||||||
|
|
||||||
root["on"] = (bri > 0);
|
root["on"] = (bri > 0);
|
||||||
root["bri"] = briLast;
|
root["bri"] = briLast;
|
||||||
root["transition"] = transitionDelay/100; //in 100ms
|
root["transition"] = transitionDelay/100; //in 100ms
|
||||||
|
|
||||||
root["ps"] = -1; //
|
root["ps"] = currentPreset;
|
||||||
|
root["pss"] = savedPresets;
|
||||||
root["pl"] = (presetCyclingEnabled) ? 0: -1;
|
root["pl"] = (presetCyclingEnabled) ? 0: -1;
|
||||||
|
|
||||||
|
//temporary for preser cycle
|
||||||
|
JsonObject ccnf = root.createNestedObject("ccnf");
|
||||||
|
ccnf["min"] = presetCycleMin;
|
||||||
|
ccnf["max"] = presetCycleMax;
|
||||||
|
ccnf["time"] = presetCycleTime/100;
|
||||||
|
|
||||||
JsonObject nl = root.createNestedObject("nl");
|
JsonObject nl = root.createNestedObject("nl");
|
||||||
nl["on"] = nightlightActive;
|
nl["on"] = nightlightActive;
|
||||||
@ -155,6 +215,8 @@ void serializeState(JsonObject root)
|
|||||||
JsonObject udpn = root.createNestedObject("udpn");
|
JsonObject udpn = root.createNestedObject("udpn");
|
||||||
udpn["send"] = notifyDirect;
|
udpn["send"] = notifyDirect;
|
||||||
udpn["recv"] = receiveNotifications;
|
udpn["recv"] = receiveNotifications;
|
||||||
|
|
||||||
|
root["mainseg"] = strip.getMainSegmentId();
|
||||||
|
|
||||||
JsonArray seg = root.createNestedArray("seg");
|
JsonArray seg = root.createNestedArray("seg");
|
||||||
for (byte s = 0; s < strip.getMaxSegments(); s++)
|
for (byte s = 0; s < strip.getMaxSegments(); s++)
|
||||||
@ -176,12 +238,16 @@ void serializeInfo(JsonObject root)
|
|||||||
JsonObject leds = root.createNestedObject("leds");
|
JsonObject leds = root.createNestedObject("leds");
|
||||||
leds["count"] = ledCount;
|
leds["count"] = ledCount;
|
||||||
leds["rgbw"] = useRGBW;
|
leds["rgbw"] = useRGBW;
|
||||||
|
leds["wv"] = useRGBW && !autoRGBtoRGBW; //should a white channel slider be displayed?
|
||||||
JsonArray leds_pin = leds.createNestedArray("pin");
|
JsonArray leds_pin = leds.createNestedArray("pin");
|
||||||
leds_pin.add(LEDPIN);
|
leds_pin.add(LEDPIN);
|
||||||
|
|
||||||
leds["pwr"] = strip.currentMilliamps;
|
leds["pwr"] = strip.currentMilliamps;
|
||||||
leds["maxpwr"] = strip.ablMilliampsMax;
|
leds["maxpwr"] = strip.ablMilliampsMax;
|
||||||
leds["maxseg"] = strip.getMaxSegments();
|
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["name"] = serverDescription;
|
||||||
root["udpport"] = udpPort;
|
root["udpport"] = udpPort;
|
||||||
@ -228,7 +294,7 @@ void serializeInfo(JsonObject root)
|
|||||||
#ifndef WLED_DISABLE_HUESYNC
|
#ifndef WLED_DISABLE_HUESYNC
|
||||||
os += 0x04;
|
os += 0x04;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_DISABLE_MOBILE_UI
|
#ifdef WLED_ENABLE_ADALIGHT
|
||||||
os += 0x02;
|
os += 0x02;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_DISABLE_OTA
|
#ifndef WLED_DISABLE_OTA
|
||||||
@ -248,6 +314,10 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
const String& url = request->url();
|
const String& url = request->url();
|
||||||
if (url.indexOf("state") > 0) subJson = 1;
|
if (url.indexOf("state") > 0) subJson = 1;
|
||||||
else if (url.indexOf("info") > 0) subJson = 2;
|
else if (url.indexOf("info") > 0) subJson = 2;
|
||||||
|
else if (url.indexOf("live") > 0) {
|
||||||
|
serveLiveLeds(request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (url.indexOf("eff") > 0) {
|
else if (url.indexOf("eff") > 0) {
|
||||||
request->send_P(200, "application/json", JSON_mode_names);
|
request->send_P(200, "application/json", JSON_mode_names);
|
||||||
return;
|
return;
|
||||||
@ -282,3 +352,24 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_LIVE_LEDS 180
|
||||||
|
|
||||||
|
void serveLiveLeds(AsyncWebServerRequest* request)
|
||||||
|
{
|
||||||
|
byte used = strip.getUsableCount();
|
||||||
|
byte n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS
|
||||||
|
char buffer[2000] = "{\"leds\":[";
|
||||||
|
olen = 9;
|
||||||
|
obuf = buffer;
|
||||||
|
|
||||||
|
for (uint16_t i= 0; i < used; i += n)
|
||||||
|
{
|
||||||
|
olen += sprintf(buffer + olen, "\"%06X\",", strip.getPixelColor(i));
|
||||||
|
}
|
||||||
|
olen -= 1;
|
||||||
|
oappend("],\"n\":");
|
||||||
|
oappendi(n);
|
||||||
|
oappend("}");
|
||||||
|
request->send(200, "application/json", buffer);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user