Compare commits
128 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a371239172 | ||
|
|
4fd904fbcc | ||
|
|
b73a257389 | ||
|
|
9e70d6b3e1 | ||
|
|
9caca37ab1 | ||
|
|
6e76fc0aa7 | ||
|
|
6171883758 | ||
|
|
942b68c948 | ||
|
|
9ca7ffa5a3 | ||
|
|
d1ce23c5ac | ||
|
|
b7b6d0a6bc | ||
|
|
10c51eea2c | ||
|
|
48d20c02a1 | ||
|
|
c5cc0b3f2b | ||
|
|
6ebef8846c | ||
|
|
5d1993935e | ||
|
|
caab8943cb | ||
|
|
f5c05b24fb | ||
|
|
940a0d006d | ||
|
|
8fe67a04d8 | ||
|
|
bec745d095 | ||
|
|
223fd35138 | ||
|
|
d3fc0309c0 | ||
|
|
830223f6e2 | ||
|
|
eb53c52499 | ||
|
|
96c9e2b4d6 | ||
|
|
c34b948bad | ||
|
|
9ac609f846 | ||
|
|
6aa47bfd1b | ||
|
|
ff46e6ea86 | ||
|
|
5489c74986 | ||
|
|
f6f8151150 | ||
|
|
a20d577f6c | ||
|
|
c4c2494dd1 | ||
|
|
c9c294a1d5 | ||
|
|
6359a8a8a2 | ||
|
|
f9b44381bd | ||
|
|
eb1ccb600b | ||
|
|
b2db61aa03 | ||
|
|
ee55a574de | ||
|
|
0998fd32cd | ||
|
|
686f2c4aa6 | ||
|
|
cd234673ea | ||
|
|
54d7a81f16 | ||
|
|
9d8d2c0aa1 | ||
|
|
17ce6b9507 | ||
|
|
296065a976 | ||
|
|
0b0f600f97 | ||
|
|
f1371d6737 | ||
|
|
03a33790e1 | ||
|
|
c0816c80ae | ||
|
|
071ebe6ef2 | ||
|
|
2126e42743 | ||
|
|
8a2b34adb4 | ||
|
|
93eb4d21bf | ||
|
|
868cedeed2 | ||
|
|
5c794f428a | ||
|
|
612d6f85bd | ||
|
|
e5cef6b877 | ||
|
|
f2a63c04a8 | ||
|
|
5a5064e070 | ||
|
|
478fa3132c | ||
|
|
a84859c211 | ||
|
|
67013bd58f | ||
|
|
b51be31d8a | ||
|
|
a3bef49124 | ||
|
|
a5cf553f17 | ||
|
|
640188f4e2 | ||
|
|
48265bbe02 | ||
|
|
6aaf544079 | ||
|
|
9904c10984 | ||
|
|
81c810eba4 | ||
|
|
5e6b1e8175 | ||
|
|
48c165b0b4 | ||
|
|
042605701e | ||
|
|
32cf1495d3 | ||
|
|
9577e49231 | ||
|
|
de19839145 | ||
|
|
f970780d6c | ||
|
|
1e69cc75c7 | ||
|
|
377e4fa0a5 | ||
|
|
a5d6dc58d3 | ||
|
|
a122c17340 | ||
|
|
34ddf104a9 | ||
|
|
f98b0beee5 | ||
|
|
75a61f85db | ||
|
|
c1cdf27507 | ||
|
|
43e9743645 | ||
|
|
c2972786f5 | ||
|
|
eeb17b417c | ||
|
|
473991638c | ||
|
|
92b4b69b3f | ||
|
|
dbd6f134c1 | ||
|
|
5f59487a88 | ||
|
|
bb7f673ff9 | ||
|
|
4715180a32 | ||
|
|
4b31610169 | ||
|
|
2466c5a204 | ||
|
|
0505baff38 | ||
|
|
c55e3a37ae | ||
|
|
ce5fec4d5f | ||
|
|
6d4339b034 | ||
|
|
70d0aae07c | ||
|
|
e3b9b341fd | ||
|
|
95083cf743 | ||
|
|
3842c4ac46 | ||
|
|
fe178043ee | ||
|
|
82d40f60f1 | ||
|
|
1d4d885276 | ||
|
|
ed3557ffca | ||
|
|
1c3878fcb0 | ||
|
|
b3dcb9fe6c | ||
|
|
0462755922 | ||
|
|
415dfd2750 | ||
|
|
72f203e4fa | ||
|
|
4e3c83af94 | ||
|
|
65a0f60257 | ||
|
|
094bdf02c4 | ||
|
|
5d8d12bc89 | ||
|
|
89b9fd8a45 | ||
|
|
ce1ba3bc2c | ||
|
|
3afb499930 | ||
|
|
356ff57005 | ||
|
|
16ce67057d | ||
|
|
4c9dc739ae | ||
|
|
a665607fac | ||
|
|
7f5671f975 | ||
|
|
ee6676cd89 |
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.vscode
|
||||
!.vscode/extensions.json
|
||||
35
.travis.yml
Normal file
35
.travis.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
# Continuous Integration (CI) is the practice, in software
|
||||
# engineering, of merging all developer working copies with a shared mainline
|
||||
# several times a day < https://docs.platformio.org/page/ci/index.html >
|
||||
#
|
||||
# Documentation:
|
||||
#
|
||||
# * Travis CI Embedded Builds with PlatformIO
|
||||
# < https://docs.travis-ci.com/user/integration/platformio/ >
|
||||
#
|
||||
# * PlatformIO integration with Travis CI
|
||||
# < https://docs.platformio.org/page/ci/travis.html >
|
||||
#
|
||||
# * User Guide for `platformio ci` command
|
||||
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
|
||||
#
|
||||
#
|
||||
# Please choose one of the following templates (proposed below) and uncomment
|
||||
# it (remove "# " before each line) or use own configuration according to the
|
||||
# Travis CI documentation (see above).
|
||||
#
|
||||
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
env:
|
||||
- PLATFORMIO_CI_SRC=wled00
|
||||
install:
|
||||
- pip install -U platformio
|
||||
- platformio update
|
||||
script:
|
||||
- platformio ci --project-conf=./platformio.ini -v
|
||||
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
]
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
### Where are the new binaries?
|
||||
|
||||
From v0.5.0 on forward, the GitHub [releases](https://github.com/Aircoookie/WLED/releases) system will be used for binaries.
|
||||
|
||||
### What binary should I choose?
|
||||
|
||||
Currently WLED supports the ESP8266 and a very early, experimental version of ESP32 support.
|
||||
Be sure to choose the correct binary for your platform and LED type.
|
||||
|
||||
- Do you have a standard RGB WS2812B NeoPixel strip?
|
||||
--> Use wled05dev_XXXXXXX_RGB_PLATFORM.bin
|
||||
|
||||
- Do you have an RGBW SK6812 strip (half of the LED is white)?
|
||||
--> Use wled05dev_XXXXXXX_RGBW_PLATFORM.bin
|
||||
|
||||
- Do you have a Cronixie clock set by Diamex?
|
||||
--> Use wled05dev_XXXXXXX_CRONIXIE_PLATFORM.bin
|
||||
|
||||
|
||||
### What about wled03 and wled04?
|
||||
|
||||
These are legacy releases only for the ESP8266. They don't include the latest features and may have unfixed bugs - only use them if the new wled05dev test builds don't work for you!
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
39
include/README
Normal file
39
include/README
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
46
lib/README
Normal file
46
lib/README
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
126
platformio.ini
Normal file
126
platformio.ini
Normal file
@@ -0,0 +1,126 @@
|
||||
; PlatformIO Project Configuration File
|
||||
; Please visit documentation: https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
src_dir = ./wled00
|
||||
data_dir = ./wled00/data
|
||||
lib_extra_dirs = ./wled00/src
|
||||
env_default = nodemcuv2
|
||||
; env_default = esp01
|
||||
; env_default = esp01_1m
|
||||
; env_default = d1_mini
|
||||
; env_default = esp32dev
|
||||
|
||||
|
||||
[common]
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
board_build.flash_mode = dout
|
||||
upload_speed = 921600
|
||||
build_flags =
|
||||
; -D VERSION=0.8.2
|
||||
; -D DEBUG
|
||||
# TODO replace libs in /lib with managed libs in here if possible.
|
||||
# If they are not changed it's just a matter of setting the correct version and change the import statement
|
||||
lib_deps_external =
|
||||
#Blynk@0.5.4
|
||||
#E131@1.0.0
|
||||
#webserver
|
||||
FastLED@3.2.1
|
||||
NeoPixelBus@2.4.1
|
||||
#PubSubClient@2.7
|
||||
#Time@1.5
|
||||
#Timezone@1.2.1
|
||||
#WS2812FX@1.1.2
|
||||
|
||||
[common:esp8266]
|
||||
platform = espressif8266@1.8.0
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
|
||||
[common:esp8266_512k]
|
||||
platform = espressif8266@1.7.0
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
|
||||
; -D WLED_DISABLE_MOBILE_UI
|
||||
-D WLED_DISABLE_OTA
|
||||
-D WLED_DISABLE_ALEXA
|
||||
; -D WLED_DISABLE_BLYNK
|
||||
; -D WLED_DISABLE_CRONIXIE
|
||||
-D WLED_DISABLE_HUESYNC
|
||||
-D WLED_DISABLE_INFRARED
|
||||
|
||||
[common:esp32]
|
||||
platform = espressif32@1.5.0
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
-D ARDUINO_ARCH_ESP32
|
||||
-D WORKAROUND_ESP32_BITBANG
|
||||
|
||||
|
||||
# see: http://docs.platformio.org/en/latest/platforms/espressif8266.html
|
||||
[env:nodemcuv2]
|
||||
board = nodemcuv2
|
||||
platform = ${common:esp8266.platform}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp8266.build_flags}
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
IRremoteESP8266@2.5.3
|
||||
|
||||
[env:d1_mini]
|
||||
board = d1_mini
|
||||
platform = ${common:esp8266.platform}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp8266.build_flags}
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
IRremoteESP8266@2.5.3
|
||||
|
||||
[env:esp01_1m]
|
||||
board = esp01_1m
|
||||
platform = ${common:esp8266.platform}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp8266.build_flags}
|
||||
# disable IR because there is no pin for it
|
||||
-D WLED_DISABLE_INFRARED
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
|
||||
[env:esp01]
|
||||
board = esp01
|
||||
platform = ${common:esp8266_512k.platform}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp8266_512k.build_flags}
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
|
||||
# see: http://docs.platformio.org/en/latest/platforms/espressif32.html
|
||||
[env:esp32dev]
|
||||
board = esp32dev
|
||||
platform = ${common:esp32.platform}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp32.build_flags}
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
|
||||
71
readme.md
71
readme.md
@@ -1,31 +1,42 @@
|
||||

|
||||
|
||||
[](https://github.com/Aircoookie/WLED/releases)
|
||||
[](https://discord.gg/KuqP7NE)
|
||||
[](https://github.com/Aircoookie/WLED/wiki)
|
||||
[](https://github.com/Aircoookie/WLED-App)
|
||||
|
||||
## Welcome to my project WLED!
|
||||
|
||||
WLED is a fast and (relatively) secure implementation of an ESP8266 webserver to control NeoPixel (WS2812B) LEDs!
|
||||
Now also with experimental ESP32 support.
|
||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
|
||||
|
||||
### Features: (V0.6.2)
|
||||
- Easter eggs!
|
||||
- RGB, HSB, and brightness sliders
|
||||
### Features:
|
||||
- WS2812FX library integrated for 80 special effects
|
||||
- FastLED noise effects and palettes
|
||||
- Customizable Mobile and desktop UI with color and effect controls
|
||||
- Settings page - configuration over network
|
||||
- Access Point and station mode - automatic failsafe AP
|
||||
- WS2812FX library integrated for over 50 special effects!
|
||||
- Secondary color support lets you use even more effect combinations
|
||||
- Alexa smart home device server (including dimming)
|
||||
- Beta syncronization to Philips hue lights
|
||||
- Support for RGBW strips
|
||||
- 25 user presets! Save your favorite colors and effects and apply them easily!
|
||||
- HTTP request API for simple integration
|
||||
- 25 user presets to save and load colors/effects easily, supports cycling through them.
|
||||
- Macro functions to automatically execute API calls
|
||||
- Nightlight function (gradually dims down)
|
||||
- Notifier function (multiple ESPs sync color via UDP broadcast)
|
||||
- Support for power pushbutton
|
||||
- Custom Theater Chase
|
||||
- Full OTA software update capability (HTTP and ArduinoOTA)
|
||||
- Password protected OTA page for added security (OTA lock)
|
||||
- NTP and configurable analog clock function
|
||||
- Support for the Cronixie Clock kit by Diamex
|
||||
- Realtime UDP Packet Control (WARLS) possible
|
||||
- Client HTML UI controlled, customizable themes
|
||||
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
||||
- Configurable analog clock + support for the Cronixie kit by Diamex
|
||||
- Configurable Auto Brightness limit for safer operation
|
||||
|
||||
### Supported light control interfaces:
|
||||
- WLED Android app
|
||||
- HTTP request API
|
||||
- Blynk IoT
|
||||
- MQTT
|
||||
- E1.31
|
||||
- Hyperion
|
||||
- UDP realtime
|
||||
- Alexa voice control (including dimming and color)
|
||||
- Sync to Philips hue lights
|
||||
- Adalight (PC ambilight via serial)
|
||||
- Sync color of multiple WLED devices (UDP notifier)
|
||||
- Infrared remotes (24-key RGB, receiver required)
|
||||
- Simple timers/schedules (time from NTP, timezones/DST supported)
|
||||
|
||||
### Quick start guide and documentation:
|
||||
|
||||
@@ -33,19 +44,11 @@ See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
|
||||
|
||||
### Other
|
||||
|
||||
Licensed under the MIT license
|
||||
Uses libraries:
|
||||
ESP8266/ESP32 Arduino Core
|
||||
NeoPixelBus by Makuna
|
||||
[WS2812FX](https://github.com/kitesurfer1404/WS2812FX) by kitesurfer1404 (Aircoookie fork)
|
||||
Time library
|
||||
Timezone library by JChristensen
|
||||
Alexa code based on arduino-esp8266-alexa-multiple-wemo-switch by kakopappa
|
||||
|
||||
Uses Linearicons by Perxis! (link in settings page)
|
||||
|
||||
|
||||
|
||||
|
||||
Licensed under the MIT license
|
||||
Credits [here](https://github.com/Aircoookie/WLED/wiki/Contributors-&-About)!
|
||||
|
||||
Uses Linearicons by Perxis!
|
||||
|
||||
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).
|
||||
If WLED really brightens up your every day, you can [](https://paypal.me/aircoookie)
|
||||
|
||||
11
test/README
Normal file
11
test/README
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PIO Unit Testing and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PIO Unit Testing:
|
||||
- https://docs.platformio.org/page/plus/unit-testing.html
|
||||
193
wled00/NpbWrapper.h
Normal file
193
wled00/NpbWrapper.h
Normal file
@@ -0,0 +1,193 @@
|
||||
//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
|
||||
#ifndef NpbWrapper_h
|
||||
#define NpbWrapper_h
|
||||
|
||||
//#define WORKAROUND_ESP32_BITBANG
|
||||
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
|
||||
|
||||
//PIN CONFIGURATION
|
||||
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 is recommended for ESP8266
|
||||
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
||||
#define IR_PIN 4 //infrared pin.
|
||||
#define AUXPIN 15 //unused auxiliary output pin
|
||||
|
||||
|
||||
|
||||
//automatically uses the right driver method for each platform
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
|
||||
#pragma message "Software BitBang is used because of your NeoPixelBus version. Look in NpbWrapper.h for instructions on how to mitigate flickering."
|
||||
#else
|
||||
#define PIXELMETHOD NeoWs2813Method
|
||||
#endif
|
||||
#else //esp8266
|
||||
//autoselect the right method depending on strip pin
|
||||
#if LEDPIN == 2
|
||||
#define PIXELMETHOD NeoEsp8266UartWs2813Method //if you get an error here, try to change to NeoEsp8266Uart1Ws2813Method or use Neopixelbus v2.3.5
|
||||
#elif LEDPIN == 3
|
||||
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp8266BitBang800KbpsMethod
|
||||
#pragma message "Software BitBang will be used because of your selected LED pin. This may cause flicker. Use GPIO 2 or 3 for best results."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//you can now change the color order in the web settings
|
||||
#define PIXELFEATURE3 NeoGrbFeature
|
||||
#define PIXELFEATURE4 NeoGrbwFeature
|
||||
|
||||
|
||||
#include <NeoPixelBrightnessBus.h>
|
||||
|
||||
enum NeoPixelType
|
||||
{
|
||||
NeoPixelType_None = 0,
|
||||
NeoPixelType_Grb = 1,
|
||||
NeoPixelType_Grbw = 2,
|
||||
NeoPixelType_End = 3
|
||||
};
|
||||
|
||||
class NeoPixelWrapper
|
||||
{
|
||||
public:
|
||||
NeoPixelWrapper() :
|
||||
// initialize each member to null
|
||||
_pGrb(NULL),
|
||||
_pGrbw(NULL),
|
||||
_type(NeoPixelType_None)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~NeoPixelWrapper()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void Begin(NeoPixelType type, uint16_t countPixels)
|
||||
{
|
||||
cleanup();
|
||||
_type = type;
|
||||
|
||||
switch (_type)
|
||||
{
|
||||
case NeoPixelType_Grb:
|
||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
|
||||
_pGrb->Begin();
|
||||
break;
|
||||
|
||||
case NeoPixelType_Grbw:
|
||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
|
||||
_pGrbw->Begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Show()
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
delay(1);
|
||||
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
switch (_type)
|
||||
{
|
||||
case NeoPixelType_Grb: _pGrb->Show(); break;
|
||||
case NeoPixelType_Grbw: _pGrbw->Show(); break;
|
||||
}
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
portENABLE_INTERRUPTS();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break;
|
||||
case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetBrightness(byte b)
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: _pGrb->SetBrightness(b); break;
|
||||
case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break;
|
||||
}
|
||||
}
|
||||
|
||||
RgbColor GetPixelColor(uint16_t indexPixel) const
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
|
||||
case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: Due to feature differences, some support RGBW but the method name
|
||||
// here needs to be unique, thus GetPixeColorRgbw
|
||||
RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break;
|
||||
case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ClearTo(RgbColor color)
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: _pGrb->ClearTo(color); break;
|
||||
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClearTo(RgbwColor color)
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: break;
|
||||
case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
NeoPixelType _type;
|
||||
|
||||
// have a member for every possible type
|
||||
NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>* _pGrb;
|
||||
NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>* _pGrbw;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: delete _pGrb ; _pGrb = NULL; break;
|
||||
case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
3416
wled00/WS2812FX.cpp
3416
wled00/WS2812FX.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,40 +1,10 @@
|
||||
//#define RGBW
|
||||
#define PIN 2 //strip pin. Only change for ESP32
|
||||
#define WORKAROUND_ESP32_BITBANG
|
||||
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
|
||||
|
||||
//automatically uses the right driver method for each platform
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
|
||||
#endif
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
|
||||
#endif
|
||||
|
||||
//selects correct feature for RGB/RGBW
|
||||
#ifdef RGBW
|
||||
#define PIXELFEATURE NeoGrbwFeature
|
||||
#else
|
||||
#define PIXELFEATURE NeoGrbFeature
|
||||
#endif
|
||||
|
||||
/*
|
||||
WS2812FX.h - Library for WS2812 LED effects.
|
||||
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
FEATURES
|
||||
* A lot of blinken modes and counting
|
||||
* WS2812FX can be used as drop-in replacement for Adafruit Neopixel Library
|
||||
NOTES
|
||||
* Uses the Adafruit Neopixel library. Get it here:
|
||||
https://github.com/adafruit/Adafruit_NeoPixel
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
@@ -50,27 +20,60 @@
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Modified to work with WLED - differs from Github WS2812FX
|
||||
|
||||
Modified for WLED
|
||||
*/
|
||||
|
||||
#ifndef WS2812FX_h
|
||||
#define WS2812FX_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <NeoPixelBrightnessBus.h>
|
||||
#include "NpbWrapper.h"
|
||||
|
||||
#define DEFAULT_BRIGHTNESS 50
|
||||
#define DEFAULT_MODE 0
|
||||
#define DEFAULT_SPEED 150
|
||||
#define DEFAULT_COLOR 0xFFAA00
|
||||
#define FASTLED_INTERNAL //remove annoying pragma messages
|
||||
#include "FastLED.h"
|
||||
|
||||
#define SPEED_MIN 0
|
||||
#define SPEED_MAX 255
|
||||
#define DEFAULT_BRIGHTNESS (uint8_t)127
|
||||
#define DEFAULT_MODE (uint8_t)0
|
||||
#define DEFAULT_SPEED (uint8_t)128
|
||||
#define DEFAULT_COLOR (uint32_t)0xFF0000
|
||||
|
||||
#define BRIGHTNESS_MIN 0
|
||||
#define BRIGHTNESS_MAX 255
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#define MODE_COUNT 58
|
||||
/* each segment uses 38 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#define MAX_NUM_SEGMENTS 10
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define SEGMENT _segments[_segment_index]
|
||||
#define SEGMENT_RUNTIME _segment_runtimes[_segment_index]
|
||||
#define SEGMENT_LENGTH (SEGMENT.stop - SEGMENT.start + 1)
|
||||
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGMENT_LENGTH
|
||||
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
||||
|
||||
// some common colors
|
||||
#define RED (uint32_t)0xFF0000
|
||||
#define GREEN (uint32_t)0x00FF00
|
||||
#define BLUE (uint32_t)0x0000FF
|
||||
#define WHITE (uint32_t)0xFFFFFF
|
||||
#define BLACK (uint32_t)0x000000
|
||||
#define YELLOW (uint32_t)0xFFFF00
|
||||
#define CYAN (uint32_t)0x00FFFF
|
||||
#define MAGENTA (uint32_t)0xFF00FF
|
||||
#define PURPLE (uint32_t)0x400080
|
||||
#define ORANGE (uint32_t)0xFF3000
|
||||
#define PINK (uint32_t)0xFF1493
|
||||
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
||||
|
||||
// options
|
||||
// bit 8: reverse animation
|
||||
// bits 5-7: fade rate (0-7)
|
||||
// bit 4: gamma correction
|
||||
// bits 1-3: TBD
|
||||
#define NO_OPTIONS (uint8_t)0x00
|
||||
#define REVERSE (uint8_t)0x80
|
||||
#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE)
|
||||
|
||||
#define MODE_COUNT 80
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
@@ -78,7 +81,7 @@
|
||||
#define FX_MODE_COLOR_WIPE 3
|
||||
#define FX_MODE_COLOR_WIPE_RANDOM 4
|
||||
#define FX_MODE_RANDOM_COLOR 5
|
||||
#define FX_MODE_EASTER 6
|
||||
#define FX_MODE_COLOR_SWEEP 6
|
||||
#define FX_MODE_DYNAMIC 7
|
||||
#define FX_MODE_RAINBOW 8
|
||||
#define FX_MODE_RAINBOW_CYCLE 9
|
||||
@@ -88,10 +91,10 @@
|
||||
#define FX_MODE_THEATER_CHASE 13
|
||||
#define FX_MODE_THEATER_CHASE_RAINBOW 14
|
||||
#define FX_MODE_RUNNING_LIGHTS 15
|
||||
#define FX_MODE_TWINKLE 16
|
||||
#define FX_MODE_TWINKLE_RANDOM 17
|
||||
#define FX_MODE_TWINKLE_FADE 18
|
||||
#define FX_MODE_TWINKLE_FADE_RANDOM 19
|
||||
#define FX_MODE_SAW 16
|
||||
#define FX_MODE_TWINKLE 17
|
||||
#define FX_MODE_DISSOLVE 18
|
||||
#define FX_MODE_DISSOLVE_RANDOM 19
|
||||
#define FX_MODE_SPARKLE 20
|
||||
#define FX_MODE_FLASH_SPARKLE 21
|
||||
#define FX_MODE_HYPER_SPARKLE 22
|
||||
@@ -115,7 +118,7 @@
|
||||
#define FX_MODE_LARSON_SCANNER 40
|
||||
#define FX_MODE_COMET 41
|
||||
#define FX_MODE_FIREWORKS 42
|
||||
#define FX_MODE_FIREWORKS_RANDOM 43
|
||||
#define FX_MODE_RAIN 43
|
||||
#define FX_MODE_MERRY_CHRISTMAS 44
|
||||
#define FX_MODE_FIRE_FLICKER 45
|
||||
#define FX_MODE_GRADIENT 46
|
||||
@@ -125,191 +128,258 @@
|
||||
#define FX_MODE_DUAL_COLOR_WIPE_OUT_OUT 50
|
||||
#define FX_MODE_DUAL_COLOR_WIPE_OUT_IN 51
|
||||
#define FX_MODE_CIRCUS_COMBUSTUS 52
|
||||
#define FX_MODE_CUSTOM_CHASE 53
|
||||
#define FX_MODE_CC_ON_RAINBOW 54
|
||||
#define FX_MODE_CC_ON_RAINBOW_CYCLE 55
|
||||
#define FX_MODE_CC_BLINK 56
|
||||
#define FX_MODE_CC_RANDOM 57
|
||||
#define FX_MODE_HALLOWEEN 53
|
||||
#define FX_MODE_TRICOLOR_CHASE 54
|
||||
#define FX_MODE_TRICOLOR_WIPE 55
|
||||
#define FX_MODE_TRICOLOR_FADE 56
|
||||
#define FX_MODE_LIGHTNING 57
|
||||
#define FX_MODE_ICU 58
|
||||
#define FX_MODE_MULTI_COMET 59
|
||||
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
||||
#define FX_MODE_RANDOM_CHASE 61
|
||||
#define FX_MODE_OSCILLATE 62
|
||||
//Modes that use FastLED -->
|
||||
#define FX_MODE_PRIDE_2015 63
|
||||
#define FX_MODE_JUGGLE 64
|
||||
#define FX_MODE_PALETTE 65
|
||||
#define FX_MODE_FIRE_2012 66
|
||||
#define FX_MODE_COLORWAVES 67
|
||||
#define FX_MODE_BPM 68
|
||||
#define FX_MODE_FILLNOISE8 69
|
||||
#define FX_MODE_NOISE16_1 70
|
||||
#define FX_MODE_NOISE16_2 71
|
||||
#define FX_MODE_NOISE16_3 72
|
||||
#define FX_MODE_NOISE16_4 73
|
||||
#define FX_MODE_COLORTWINKLE 74
|
||||
#define FX_MODE_LAKE 75
|
||||
#define FX_MODE_METEOR 76
|
||||
#define FX_MODE_METEOR_SMOOTH 77
|
||||
#define FX_MODE_RAILWAY 78
|
||||
#define FX_MODE_RIPPLE 79
|
||||
|
||||
|
||||
class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
typedef void (WS2812FX::*mode_ptr)(void);
|
||||
class WS2812FX {
|
||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||
|
||||
// segment parameters
|
||||
public:
|
||||
WS2812FX(uint16_t n) : NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD>(n,PIN) {
|
||||
typedef struct Segment { // 21 bytes
|
||||
uint16_t start;
|
||||
uint16_t stop;
|
||||
uint8_t speed;
|
||||
uint8_t intensity;
|
||||
uint8_t palette;
|
||||
uint8_t mode;
|
||||
uint8_t options;
|
||||
uint32_t colors[NUM_COLORS];
|
||||
} segment;
|
||||
|
||||
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
|
||||
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
|
||||
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
|
||||
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
|
||||
_mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random;
|
||||
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
|
||||
_mode[FX_MODE_EASTER] = &WS2812FX::mode_easter;
|
||||
_mode[FX_MODE_DYNAMIC] = &WS2812FX::mode_dynamic;
|
||||
_mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow;
|
||||
_mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle;
|
||||
_mode[FX_MODE_SCAN] = &WS2812FX::mode_scan;
|
||||
_mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan;
|
||||
_mode[FX_MODE_FADE] = &WS2812FX::mode_fade;
|
||||
_mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase;
|
||||
_mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow;
|
||||
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
|
||||
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
|
||||
_mode[FX_MODE_TWINKLE_RANDOM] = &WS2812FX::mode_twinkle_random;
|
||||
_mode[FX_MODE_TWINKLE_FADE] = &WS2812FX::mode_twinkle_fade;
|
||||
_mode[FX_MODE_TWINKLE_FADE_RANDOM] = &WS2812FX::mode_twinkle_fade_random;
|
||||
_mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle;
|
||||
_mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle;
|
||||
_mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle;
|
||||
_mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe;
|
||||
_mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow;
|
||||
_mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe;
|
||||
_mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow;
|
||||
_mode[FX_MODE_ANDROID] = &WS2812FX::mode_android;
|
||||
_mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color;
|
||||
_mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random;
|
||||
_mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow;
|
||||
_mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash;
|
||||
_mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random;
|
||||
_mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white;
|
||||
_mode[FX_MODE_COLORFUL] = &WS2812FX::mode_colorful;
|
||||
_mode[FX_MODE_TRAFFIC_LIGHT] = &WS2812FX::mode_traffic_light;
|
||||
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
|
||||
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
|
||||
_mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
|
||||
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
|
||||
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
|
||||
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
|
||||
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
|
||||
_mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random;
|
||||
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
|
||||
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
||||
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
|
||||
_mode[FX_MODE_LOADING] = &WS2812FX::mode_loading;
|
||||
// segment runtime parameters
|
||||
typedef struct Segment_runtime { // 17 bytes
|
||||
unsigned long next_time;
|
||||
uint32_t counter_mode_step;
|
||||
uint32_t counter_mode_call;
|
||||
uint16_t aux_param;
|
||||
uint16_t aux_param2;
|
||||
uint8_t trans_act;
|
||||
} segment_runtime;
|
||||
|
||||
WS2812FX() {
|
||||
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
|
||||
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
|
||||
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
|
||||
_mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random;
|
||||
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
|
||||
_mode[FX_MODE_COLOR_SWEEP] = &WS2812FX::mode_color_sweep;
|
||||
_mode[FX_MODE_DYNAMIC] = &WS2812FX::mode_dynamic;
|
||||
_mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow;
|
||||
_mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle;
|
||||
_mode[FX_MODE_SCAN] = &WS2812FX::mode_scan;
|
||||
_mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan;
|
||||
_mode[FX_MODE_FADE] = &WS2812FX::mode_fade;
|
||||
_mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase;
|
||||
_mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow;
|
||||
_mode[FX_MODE_SAW] = &WS2812FX::mode_saw;
|
||||
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
|
||||
_mode[FX_MODE_DISSOLVE] = &WS2812FX::mode_dissolve;
|
||||
_mode[FX_MODE_DISSOLVE_RANDOM] = &WS2812FX::mode_dissolve_random;
|
||||
_mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle;
|
||||
_mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle;
|
||||
_mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle;
|
||||
_mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe;
|
||||
_mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow;
|
||||
_mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe;
|
||||
_mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow;
|
||||
_mode[FX_MODE_ANDROID] = &WS2812FX::mode_android;
|
||||
_mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color;
|
||||
_mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random;
|
||||
_mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow;
|
||||
_mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash;
|
||||
_mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random;
|
||||
_mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white;
|
||||
_mode[FX_MODE_COLORFUL] = &WS2812FX::mode_colorful;
|
||||
_mode[FX_MODE_TRAFFIC_LIGHT] = &WS2812FX::mode_traffic_light;
|
||||
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
|
||||
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
|
||||
_mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
|
||||
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
|
||||
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
|
||||
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
|
||||
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
|
||||
_mode[FX_MODE_RAIN] = &WS2812FX::mode_rain;
|
||||
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
|
||||
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
||||
_mode[FX_MODE_GRADIENT] = &WS2812FX::mode_gradient;
|
||||
_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_DUAL_COLOR_WIPE_IN_IN] = &WS2812FX::mode_dual_color_wipe_in_in;
|
||||
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_OUT] = &WS2812FX::mode_dual_color_wipe_out_out;
|
||||
_mode[FX_MODE_DUAL_COLOR_WIPE_OUT_IN] = &WS2812FX::mode_dual_color_wipe_out_in;
|
||||
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
||||
_mode[FX_MODE_CUSTOM_CHASE] = &WS2812FX::mode_cc_standard;
|
||||
_mode[FX_MODE_CC_ON_RAINBOW] = &WS2812FX::mode_cc_rainbow;
|
||||
_mode[FX_MODE_CC_ON_RAINBOW_CYCLE] = &WS2812FX::mode_cc_cycle;
|
||||
_mode[FX_MODE_CC_BLINK] = &WS2812FX::mode_cc_blink;
|
||||
_mode[FX_MODE_CC_RANDOM] = &WS2812FX::mode_cc_random;
|
||||
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
||||
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
||||
_mode[FX_MODE_TRICOLOR_WIPE] = &WS2812FX::mode_tricolor_wipe;
|
||||
_mode[FX_MODE_TRICOLOR_FADE] = &WS2812FX::mode_tricolor_fade;
|
||||
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
|
||||
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
|
||||
_mode[FX_MODE_LIGHTNING] = &WS2812FX::mode_lightning;
|
||||
_mode[FX_MODE_ICU] = &WS2812FX::mode_icu;
|
||||
_mode[FX_MODE_MULTI_COMET] = &WS2812FX::mode_multi_comet;
|
||||
_mode[FX_MODE_DUAL_LARSON_SCANNER] = &WS2812FX::mode_dual_larson_scanner;
|
||||
_mode[FX_MODE_RANDOM_CHASE] = &WS2812FX::mode_random_chase;
|
||||
_mode[FX_MODE_OSCILLATE] = &WS2812FX::mode_oscillate;
|
||||
_mode[FX_MODE_FIRE_2012] = &WS2812FX::mode_fire_2012;
|
||||
_mode[FX_MODE_PRIDE_2015] = &WS2812FX::mode_pride_2015;
|
||||
_mode[FX_MODE_BPM] = &WS2812FX::mode_bpm;
|
||||
_mode[FX_MODE_JUGGLE] = &WS2812FX::mode_juggle;
|
||||
_mode[FX_MODE_PALETTE] = &WS2812FX::mode_palette;
|
||||
_mode[FX_MODE_COLORWAVES] = &WS2812FX::mode_colorwaves;
|
||||
_mode[FX_MODE_FILLNOISE8] = &WS2812FX::mode_fillnoise8;
|
||||
_mode[FX_MODE_NOISE16_1] = &WS2812FX::mode_noise16_1;
|
||||
_mode[FX_MODE_NOISE16_2] = &WS2812FX::mode_noise16_2;
|
||||
_mode[FX_MODE_NOISE16_3] = &WS2812FX::mode_noise16_3;
|
||||
_mode[FX_MODE_NOISE16_4] = &WS2812FX::mode_noise16_4;
|
||||
_mode[FX_MODE_COLORTWINKLE] = &WS2812FX::mode_colortwinkle;
|
||||
_mode[FX_MODE_LAKE] = &WS2812FX::mode_lake;
|
||||
_mode[FX_MODE_METEOR] = &WS2812FX::mode_meteor;
|
||||
_mode[FX_MODE_METEOR_SMOOTH] = &WS2812FX::mode_meteor_smooth;
|
||||
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
|
||||
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;
|
||||
|
||||
_mode_index = DEFAULT_MODE;
|
||||
_speed = DEFAULT_SPEED;
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
_running = false;
|
||||
_led_count = n;
|
||||
_mode_last_call_time = 0;
|
||||
_mode_delay = 0;
|
||||
_color = DEFAULT_COLOR;
|
||||
_mode_color = DEFAULT_COLOR;
|
||||
_color_sec = 0;
|
||||
_mode_var1 = 0;
|
||||
_cc_fs = true;
|
||||
_cc_fe = false;
|
||||
_cc_is = 0;
|
||||
_cc_i1 = 0;
|
||||
_cc_i2 = n-1;
|
||||
_cc_num1 = 5;
|
||||
_cc_num2 = 5;
|
||||
_ccStep = 1;
|
||||
_counter_mode_call = 0;
|
||||
_counter_mode_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
_fastStandard = false;
|
||||
_num_segments = 1;
|
||||
_segments[0].mode = DEFAULT_MODE;
|
||||
_segments[0].colors[0] = DEFAULT_COLOR;
|
||||
_segments[0].start = 0;
|
||||
_segments[0].speed = DEFAULT_SPEED;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
targetPalette = CloudColors_p;
|
||||
_reverseMode = false;
|
||||
_locked = new bool[n];
|
||||
_skipFirstMode = false;
|
||||
colorOrder = 0;
|
||||
paletteFade = 0;
|
||||
paletteBlend = 0;
|
||||
ablMilliampsMax = 750;
|
||||
currentMilliamps = 0;
|
||||
_locked = NULL;
|
||||
_modeUsesLock = false;
|
||||
_cronixieDigits = new byte[6];
|
||||
bus = new NeoPixelWrapper();
|
||||
RESET_RUNTIME;
|
||||
}
|
||||
|
||||
void
|
||||
show(void),
|
||||
setPixelColor(uint16_t i, byte r, byte g, byte b),
|
||||
init(void),
|
||||
init(bool supportWhite, uint16_t countPixels, bool skipFirst),
|
||||
service(void),
|
||||
start(void),
|
||||
stop(void),
|
||||
setMode(byte m),
|
||||
setCustomChase(byte i1, byte i2, byte is, byte np, byte ns, byte stp, bool fs, bool fe),
|
||||
setCCIndex1(byte i1),
|
||||
setCCIndex2(byte i2),
|
||||
setCCStart(byte is),
|
||||
setCCNum1(byte np),
|
||||
setCCNum2(byte ns),
|
||||
setCCStep(byte stp),
|
||||
setCCFS(bool fs),
|
||||
setCCFE(bool fe),
|
||||
setSpeed(byte s),
|
||||
setIntensity(byte in),
|
||||
increaseSpeed(byte s),
|
||||
decreaseSpeed(byte s),
|
||||
setColor(byte r, byte g, byte b),
|
||||
setColor(byte r, byte g, byte b, byte w),
|
||||
blur(uint8_t),
|
||||
fade_out(uint8_t r),
|
||||
setMode(uint8_t m),
|
||||
setSpeed(uint8_t s),
|
||||
setIntensity(uint8_t i),
|
||||
setPalette(uint8_t p),
|
||||
setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setColor(uint32_t c),
|
||||
setSecondaryColor(byte r, byte g, byte b),
|
||||
setSecondaryColor(byte r, byte g, byte b, byte w),
|
||||
setSecondaryColor(uint32_t c),
|
||||
setBrightness(byte b),
|
||||
increaseBrightness(byte s),
|
||||
decreaseBrightness(byte s),
|
||||
setBrightness(uint8_t b),
|
||||
setReverseMode(bool b),
|
||||
driverModeCronixie(bool b),
|
||||
setCronixieDigits(byte* d),
|
||||
setCronixieBacklight(bool b),
|
||||
setIndividual(int i),
|
||||
setIndividual(int i, uint32_t col),
|
||||
setRange(int i, int i2),
|
||||
setRange(int i, int i2, uint32_t col),
|
||||
lock(int i),
|
||||
lockRange(int i, int i2),
|
||||
lockAll(void),
|
||||
unlock(int i),
|
||||
unlockRange(int i, int i2),
|
||||
setIndividual(uint16_t i, uint32_t col),
|
||||
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
||||
lock(uint16_t i),
|
||||
lockRange(uint16_t i, uint16_t i2),
|
||||
unlock(uint16_t i),
|
||||
unlockRange(uint16_t i, uint16_t i2),
|
||||
unlockAll(void),
|
||||
setFastUpdateMode(bool b),
|
||||
setTransitionMode(bool t),
|
||||
trigger(void),
|
||||
setLedCount(uint16_t i),
|
||||
setFade(int sp);
|
||||
setNumSegments(uint8_t n),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint8_t speed, uint8_t intensity, bool reverse),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint8_t speed, uint8_t intensity, bool reverse),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint8_t speed, uint8_t intensity, uint8_t options),
|
||||
resetSegments(),
|
||||
setPixelColor(uint16_t n, uint32_t c),
|
||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
show(void);
|
||||
|
||||
bool
|
||||
isRunning(void),
|
||||
isLocked(int i);
|
||||
bool
|
||||
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
|
||||
|
||||
byte
|
||||
get_random_wheel_index(byte),
|
||||
uint8_t
|
||||
paletteFade,
|
||||
paletteBlend,
|
||||
colorOrder,
|
||||
getBrightness(void),
|
||||
getMode(void),
|
||||
getSpeed(void),
|
||||
getIntensity(void),
|
||||
getBrightness(void),
|
||||
getModeCount(void);
|
||||
getNumSegments(void),
|
||||
get_random_wheel_index(uint8_t);
|
||||
|
||||
uint32_t
|
||||
color_wheel(byte),
|
||||
color_wheel(uint8_t),
|
||||
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
|
||||
color_blend(uint32_t,uint32_t,uint8_t),
|
||||
getPixelColor(uint16_t),
|
||||
getColor(void);
|
||||
|
||||
double
|
||||
getPowerEstimate(byte leds, uint32_t c, byte b),
|
||||
getSafePowerMultiplier(double safeMilliAmps, byte leds, uint32_t c, byte b);
|
||||
WS2812FX::Segment
|
||||
getSegment(void);
|
||||
|
||||
private:
|
||||
WS2812FX::Segment_runtime
|
||||
getSegmentRuntime(void);
|
||||
|
||||
void
|
||||
begin(void),
|
||||
clear(void),
|
||||
setPixelColor(uint16_t i, uint32_t c),
|
||||
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
|
||||
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
|
||||
dofade(void),
|
||||
strip_off(void),
|
||||
strip_off_respectLock(void),
|
||||
WS2812FX::Segment*
|
||||
getSegments(void);
|
||||
|
||||
// mode helper functions
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps,
|
||||
blink(uint32_t, uint32_t, bool strobe, bool),
|
||||
color_wipe(uint32_t, uint32_t, bool , bool),
|
||||
scan(bool),
|
||||
theater_chase(uint32_t, uint32_t, bool),
|
||||
running_base(bool),
|
||||
dissolve(uint32_t),
|
||||
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||
gradient_base(bool),
|
||||
running(uint32_t, uint32_t),
|
||||
tricolor_chase(uint32_t, uint32_t);
|
||||
|
||||
// builtin modes
|
||||
uint16_t
|
||||
mode_static(void),
|
||||
mode_blink(void),
|
||||
mode_blink_rainbow(void),
|
||||
mode_strobe(void),
|
||||
mode_strobe_rainbow(void),
|
||||
mode_color_wipe(void),
|
||||
mode_color_sweep(void),
|
||||
mode_color_wipe_random(void),
|
||||
mode_color_sweep_random(void),
|
||||
mode_random_color(void),
|
||||
mode_easter(void),
|
||||
mode_dynamic(void),
|
||||
mode_breath(void),
|
||||
mode_fade(void),
|
||||
@@ -320,17 +390,14 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
mode_rainbow(void),
|
||||
mode_rainbow_cycle(void),
|
||||
mode_running_lights(void),
|
||||
mode_saw(void),
|
||||
mode_twinkle(void),
|
||||
mode_twinkle_random(void),
|
||||
mode_twinkle_fade(void),
|
||||
mode_twinkle_fade_random(void),
|
||||
mode_dissolve(void),
|
||||
mode_dissolve_random(void),
|
||||
mode_sparkle(void),
|
||||
mode_flash_sparkle(void),
|
||||
mode_hyper_sparkle(void),
|
||||
mode_strobe(void),
|
||||
mode_strobe_rainbow(void),
|
||||
mode_multi_strobe(void),
|
||||
mode_blink_rainbow(void),
|
||||
mode_android(void),
|
||||
mode_chase_color(void),
|
||||
mode_chase_random(void),
|
||||
@@ -339,17 +406,16 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
mode_chase_flash_random(void),
|
||||
mode_chase_rainbow_white(void),
|
||||
mode_colorful(void),
|
||||
mode_colorful_internal(uint32_t*),
|
||||
mode_traffic_light(void),
|
||||
mode_color_sweep_random(void),
|
||||
mode_running_color(void),
|
||||
mode_running_red_blue(void),
|
||||
mode_running_random(void),
|
||||
mode_larson_scanner(void),
|
||||
mode_comet(void),
|
||||
mode_fireworks(void),
|
||||
mode_fireworks_random(void),
|
||||
mode_rain(void),
|
||||
mode_merry_christmas(void),
|
||||
mode_halloween(void),
|
||||
mode_fire_flicker(void),
|
||||
mode_gradient(void),
|
||||
mode_loading(void),
|
||||
@@ -358,65 +424,209 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
mode_dual_color_wipe_out_out(void),
|
||||
mode_dual_color_wipe_out_in(void),
|
||||
mode_circus_combustus(void),
|
||||
mode_cc_core(void),
|
||||
mode_cc_standard(void),
|
||||
mode_cc_rainbow(void),
|
||||
mode_cc_cycle(void),
|
||||
mode_cc_blink(void),
|
||||
mode_cc_random(void);
|
||||
mode_bicolor_chase(void),
|
||||
mode_tricolor_chase(void),
|
||||
mode_tricolor_wipe(void),
|
||||
mode_tricolor_fade(void),
|
||||
mode_lightning(void),
|
||||
mode_icu(void),
|
||||
mode_multi_comet(void),
|
||||
mode_dual_larson_scanner(void),
|
||||
mode_random_chase(void),
|
||||
mode_oscillate(void),
|
||||
mode_fire_2012(void),
|
||||
mode_pride_2015(void),
|
||||
mode_bpm(void),
|
||||
mode_juggle(void),
|
||||
mode_palette(void),
|
||||
mode_colorwaves(void),
|
||||
mode_fillnoise8(void),
|
||||
mode_noise16_1(void),
|
||||
mode_noise16_2(void),
|
||||
mode_noise16_3(void),
|
||||
mode_noise16_4(void),
|
||||
mode_colortwinkle(void),
|
||||
mode_lake(void),
|
||||
mode_meteor(void),
|
||||
mode_meteor_smooth(void),
|
||||
mode_railway(void),
|
||||
mode_ripple(void);
|
||||
|
||||
private:
|
||||
NeoPixelWrapper *bus;
|
||||
|
||||
CRGB fastled_from_col(uint32_t);
|
||||
CRGBPalette16 currentPalette;
|
||||
CRGBPalette16 targetPalette;
|
||||
|
||||
uint16_t _length;
|
||||
uint16_t _rand16seed;
|
||||
uint8_t _brightness;
|
||||
|
||||
void handle_palette(void);
|
||||
void fill(uint32_t);
|
||||
bool modeUsesLock(uint8_t);
|
||||
|
||||
bool
|
||||
_triggered,
|
||||
_fastStandard,
|
||||
_modeUsesLock,
|
||||
_rgbwMode,
|
||||
_reverseMode,
|
||||
_cronixieMode,
|
||||
_cronixieBacklightEnabled,
|
||||
_cc_fs,
|
||||
_cc_fe,
|
||||
_running;
|
||||
_skipFirstMode,
|
||||
_triggered;
|
||||
|
||||
bool*
|
||||
_locked;
|
||||
byte* _locked;
|
||||
byte* _cronixieDigits;
|
||||
|
||||
byte
|
||||
minval(byte v, byte w),
|
||||
maxval(byte v, byte w),
|
||||
_mode_index,
|
||||
_speed,
|
||||
_intensity,
|
||||
_cc_i1,
|
||||
_cc_i2,
|
||||
_cc_is,
|
||||
_cc_num1,
|
||||
_cc_num2,
|
||||
_ccStep,
|
||||
_brightness;
|
||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
|
||||
byte*
|
||||
_cronixieDigits;
|
||||
|
||||
uint16_t
|
||||
_led_count;
|
||||
|
||||
uint32_t
|
||||
getPixelColor(uint16_t i),
|
||||
_color,
|
||||
_color_sec,
|
||||
_counter_mode_call,
|
||||
_counter_mode_step,
|
||||
_counter_ccStep,
|
||||
_mode_var1,
|
||||
_mode_color,
|
||||
_mode_delay;
|
||||
|
||||
double
|
||||
_cronixieSecMultiplier;
|
||||
|
||||
unsigned long
|
||||
_mode_last_call_time;
|
||||
|
||||
mode_ptr
|
||||
_mode[MODE_COUNT];
|
||||
|
||||
uint32_t _lastPaletteChange = 0;
|
||||
|
||||
uint8_t _segment_index = 0;
|
||||
uint8_t _segment_index_palette_last = 99;
|
||||
uint8_t _num_segments = 1;
|
||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 21 bytes per element
|
||||
// start, stop, speed, intensity, palette, mode, options, color[]
|
||||
{ 0, 7, DEFAULT_SPEED, 128, 0, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
|
||||
};
|
||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 17 bytes per element
|
||||
};
|
||||
|
||||
|
||||
const char JSON_mode_names[] PROGMEM = R"=====({"effects":[
|
||||
"Solid",
|
||||
"Blink",
|
||||
"Breathe",
|
||||
"Wipe",
|
||||
"Wipe Random",
|
||||
"Random Colors",
|
||||
"Sweep",
|
||||
"Dynamic",
|
||||
"Colorloop",
|
||||
"Rainbow",
|
||||
"Scan",
|
||||
"Dual Scan",
|
||||
"Fade",
|
||||
"Chase",
|
||||
"Chase Rainbow",
|
||||
"Running",
|
||||
"Saw",
|
||||
"Twinkle",
|
||||
"Dissolve",
|
||||
"Dissolve Rnd",
|
||||
"Sparkle",
|
||||
"Dark Sparkle",
|
||||
"Sparkle+",
|
||||
"Strobe",
|
||||
"Strobe Rainbow",
|
||||
"Mega Strobe",
|
||||
"Blink Rainbow",
|
||||
"Android",
|
||||
"Chase",
|
||||
"Chase Random",
|
||||
"Chase Rainbow",
|
||||
"Chase Flash",
|
||||
"Chase Flash Rnd",
|
||||
"Rainbow Runner",
|
||||
"Colorful",
|
||||
"Traffic Light",
|
||||
"Sweep Random",
|
||||
"Running 2",
|
||||
"Red & Blue",
|
||||
"Stream",
|
||||
"Scanner",
|
||||
"Lighthouse",
|
||||
"Fireworks",
|
||||
"Rain",
|
||||
"Merry Christmas",
|
||||
"Fire Flicker",
|
||||
"Gradient",
|
||||
"Loading",
|
||||
"In Out",
|
||||
"In In",
|
||||
"Out Out",
|
||||
"Out In",
|
||||
"Circus",
|
||||
"Halloween",
|
||||
"Tri Chase",
|
||||
"Tri Wipe",
|
||||
"Tri Fade",
|
||||
"Lightning",
|
||||
"ICU",
|
||||
"Multi Comet",
|
||||
"Dual Scanner",
|
||||
"Stream 2",
|
||||
"Oscillate",
|
||||
"Pride 2015",
|
||||
"Juggle",
|
||||
"Palette",
|
||||
"Fire 2012",
|
||||
"Colorwaves",
|
||||
"BPM",
|
||||
"Fill Noise",
|
||||
"Noise 1",
|
||||
"Noise 2",
|
||||
"Noise 3",
|
||||
"Noise 4",
|
||||
"Colortwinkle",
|
||||
"Lake",
|
||||
"Meteor",
|
||||
"Smooth Meteor",
|
||||
"Railway",
|
||||
"Ripple"
|
||||
]})=====";
|
||||
|
||||
|
||||
const char JSON_palette_names[] PROGMEM = R"=====({"palettes":[
|
||||
"Default",
|
||||
"Random Cycle",
|
||||
"Primary Color",
|
||||
"Based on Primary",
|
||||
"Set Colors",
|
||||
"Based on Set",
|
||||
"Party",
|
||||
"Cloud",
|
||||
"Lava",
|
||||
"Ocean",
|
||||
"Forest",
|
||||
"Rainbow",
|
||||
"Rainbow Bands",
|
||||
"Sunset",
|
||||
"Rivendell",
|
||||
"Breeze",
|
||||
"Red & Blue",
|
||||
"Yellowout",
|
||||
"Analogous",
|
||||
"Splash",
|
||||
"Pastel",
|
||||
"Sunset 2",
|
||||
"Beech",
|
||||
"Vintage",
|
||||
"Departure",
|
||||
"Landscape",
|
||||
"Beach",
|
||||
"Sherbet",
|
||||
"Hult",
|
||||
"Hult 64",
|
||||
"Drywet",
|
||||
"Jul",
|
||||
"Grintage",
|
||||
"Rewhi",
|
||||
"Tertiary",
|
||||
"Fire",
|
||||
"Icefire",
|
||||
"Cyane",
|
||||
"Light Pink",
|
||||
"Autumn",
|
||||
"Magenta",
|
||||
"Magred",
|
||||
"Yelmag",
|
||||
"Yelblu",
|
||||
"Orange & Teal",
|
||||
"Tiamat",
|
||||
"April Night"
|
||||
]})=====";
|
||||
|
||||
#endif
|
||||
|
||||
717
wled00/WS2812FX_fcn.cpp
Normal file
717
wled00/WS2812FX_fcn.cpp
Normal file
@@ -0,0 +1,717 @@
|
||||
/*
|
||||
WS2812FX_fcn.cpp contains all utility functions
|
||||
Harm Aldick - 2016
|
||||
www.aldick.org
|
||||
LICENSE
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016 Harm Aldick
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Modified heavily for WLED
|
||||
*/
|
||||
|
||||
#include "WS2812FX.h"
|
||||
#include "palettes.h"
|
||||
|
||||
#define LED_SKIP_AMOUNT 1
|
||||
|
||||
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
|
||||
{
|
||||
if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL) return;
|
||||
RESET_RUNTIME;
|
||||
_rgbwMode = supportWhite;
|
||||
_skipFirstMode = skipFirst;
|
||||
_length = countPixels;
|
||||
|
||||
uint8_t ty = 1;
|
||||
if (supportWhite) ty =2;
|
||||
uint16_t lengthRaw = _length;
|
||||
if (_skipFirstMode) lengthRaw += LED_SKIP_AMOUNT;
|
||||
bus->Begin((NeoPixelType)ty, lengthRaw);
|
||||
|
||||
if (_locked != NULL) delete _locked;
|
||||
_locked = new byte[_length];
|
||||
|
||||
_segments[0].start = 0;
|
||||
_segments[0].stop = _length -1;
|
||||
|
||||
unlockAll();
|
||||
setBrightness(_brightness);
|
||||
}
|
||||
|
||||
void WS2812FX::service() {
|
||||
unsigned long now = millis(); // Be aware, millis() rolls over every 49 days
|
||||
bool doShow = false;
|
||||
for(uint8_t i=0; i < _num_segments; i++)
|
||||
{
|
||||
_segment_index = i;
|
||||
if(now > SEGMENT_RUNTIME.next_time || _triggered)
|
||||
{
|
||||
doShow = true;
|
||||
handle_palette();
|
||||
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
||||
SEGMENT_RUNTIME.next_time = now + max(delay, 5);
|
||||
SEGMENT_RUNTIME.counter_mode_call++;
|
||||
}
|
||||
}
|
||||
if(doShow) {
|
||||
show();
|
||||
}
|
||||
_triggered = false;
|
||||
}
|
||||
|
||||
bool WS2812FX::modeUsesLock(uint8_t m)
|
||||
{
|
||||
if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE ||
|
||||
m == FX_MODE_METEOR || m == FX_MODE_METEOR_SMOOTH ||
|
||||
m == FX_MODE_RIPPLE) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||
uint8_t w = (c >> 24) & 0xFF;
|
||||
uint8_t r = (c >> 16) & 0xFF;
|
||||
uint8_t g = (c >> 8) & 0xFF;
|
||||
uint8_t b = c & 0xFF;
|
||||
setPixelColor(n, r, g, b, w);
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
if (_locked[i] && !_modeUsesLock) return;
|
||||
if (_reverseMode) i = _length - 1 -i;
|
||||
if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment
|
||||
byte tmpg = g;
|
||||
switch (colorOrder) //0 = Grb, default
|
||||
{
|
||||
case 0: break; //0 = Grb, default
|
||||
case 1: g = r; r = tmpg; break; //1 = Rgb, common for WS2811
|
||||
case 2: g = b; b = tmpg; break; //2 = Brg
|
||||
case 3: g = b; b = r; r = tmpg; //3 = Rbg
|
||||
}
|
||||
if (!_cronixieMode)
|
||||
{
|
||||
if (_skipFirstMode)
|
||||
{
|
||||
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
|
||||
i += LED_SKIP_AMOUNT;
|
||||
}
|
||||
|
||||
bus->SetPixelColor(i, RgbwColor(r,g,b,w));
|
||||
} else {
|
||||
if(i>6)return;
|
||||
byte o = 10*i;
|
||||
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
|
||||
{
|
||||
byte r2 = (_segments[0].colors[1] >>16) & 0xFF;
|
||||
byte g2 = (_segments[0].colors[1] >> 8) & 0xFF;
|
||||
byte b2 = (_segments[0].colors[1] ) & 0xFF;
|
||||
byte w2 = (_segments[0].colors[1] >>24) & 0xFF;
|
||||
for (int j=o; j< o+19; j++)
|
||||
{
|
||||
bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2));
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (int j=o; j< o+19; j++)
|
||||
{
|
||||
bus->SetPixelColor(j, RgbwColor(0,0,0,0));
|
||||
}
|
||||
}
|
||||
if (_skipFirstMode) o += LED_SKIP_AMOUNT;
|
||||
switch(_cronixieDigits[i])
|
||||
{
|
||||
case 0: bus->SetPixelColor(o+5, RgbwColor(r,g,b,w)); break;
|
||||
case 1: bus->SetPixelColor(o+0, RgbwColor(r,g,b,w)); break;
|
||||
case 2: bus->SetPixelColor(o+6, RgbwColor(r,g,b,w)); break;
|
||||
case 3: bus->SetPixelColor(o+1, RgbwColor(r,g,b,w)); break;
|
||||
case 4: bus->SetPixelColor(o+7, RgbwColor(r,g,b,w)); break;
|
||||
case 5: bus->SetPixelColor(o+2, RgbwColor(r,g,b,w)); break;
|
||||
case 6: bus->SetPixelColor(o+8, RgbwColor(r,g,b,w)); break;
|
||||
case 7: bus->SetPixelColor(o+3, RgbwColor(r,g,b,w)); break;
|
||||
case 8: bus->SetPixelColor(o+9, RgbwColor(r,g,b,w)); break;
|
||||
case 9: bus->SetPixelColor(o+4, RgbwColor(r,g,b,w)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setReverseMode(bool b)
|
||||
{
|
||||
_reverseMode = b;
|
||||
}
|
||||
|
||||
void WS2812FX::driverModeCronixie(bool b)
|
||||
{
|
||||
_cronixieMode = b;
|
||||
_segments[0].stop = (b) ? 5 : _length-1;
|
||||
}
|
||||
|
||||
void WS2812FX::setCronixieBacklight(bool b)
|
||||
{
|
||||
_cronixieBacklightEnabled = b;
|
||||
}
|
||||
|
||||
void WS2812FX::setCronixieDigits(byte d[])
|
||||
{
|
||||
for (int i = 0; i<6; i++)
|
||||
{
|
||||
_cronixieDigits[i] = d[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//DISCLAIMER
|
||||
//The following function attemps to calculate the current LED power usage,
|
||||
//and will limit the brightness to stay below a set amperage threshold.
|
||||
//It is NOT a measurement and NOT guaranteed to stay within the ablMilliampsMax margin.
|
||||
//Stay safe with high amperage and have a reasonable safety margin!
|
||||
//I am NOT to be held liable for burned down garages!
|
||||
|
||||
//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)
|
||||
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
||||
|
||||
void WS2812FX::show(void) {
|
||||
//power limit calculation
|
||||
//each LED can draw up 195075 "power units" (approx. 53mA)
|
||||
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
||||
//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
|
||||
{
|
||||
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * PU_PER_MA; //100mA for ESP power
|
||||
if (powerBudget > PU_PER_MA * _length) //each LED uses about 1mA in standby, exclude that from power budget
|
||||
{
|
||||
powerBudget -= PU_PER_MA * _length;
|
||||
} else
|
||||
{
|
||||
powerBudget = 0;
|
||||
}
|
||||
|
||||
uint32_t powerSum = 0;
|
||||
|
||||
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
|
||||
{
|
||||
RgbwColor c = bus->GetPixelColorRgbw(i);
|
||||
powerSum += (c.R + c.G + c.B + c.W);
|
||||
}
|
||||
|
||||
if (_rgbwMode) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
|
||||
{
|
||||
powerSum *= 3;
|
||||
powerSum >> 2; //same as /= 4
|
||||
}
|
||||
|
||||
uint32_t powerSum0 = powerSum;
|
||||
powerSum *= _brightness;
|
||||
|
||||
if (powerSum > powerBudget) //scale brightness down to stay in current limit
|
||||
{
|
||||
float scale = (float)powerBudget / (float)powerSum;
|
||||
uint16_t scaleI = scale * 255;
|
||||
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
||||
uint8_t newBri = scale8(_brightness, scaleB);
|
||||
bus->SetBrightness(newBri);
|
||||
currentMilliamps = (powerSum0 * newBri) / PU_PER_MA;
|
||||
} else
|
||||
{
|
||||
currentMilliamps = powerSum / PU_PER_MA;
|
||||
bus->SetBrightness(_brightness);
|
||||
}
|
||||
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
||||
currentMilliamps += _length; //add standby power back to estimate
|
||||
} else {
|
||||
currentMilliamps = 0;
|
||||
}
|
||||
|
||||
bus->Show();
|
||||
}
|
||||
|
||||
void WS2812FX::trigger() {
|
||||
_triggered = true;
|
||||
}
|
||||
|
||||
void WS2812FX::setMode(uint8_t m) {
|
||||
RESET_RUNTIME;
|
||||
bool ua = modeUsesLock(_segments[0].mode) && !modeUsesLock(m);
|
||||
if (m > MODE_COUNT - 1) m = MODE_COUNT - 1;
|
||||
_segments[0].mode = m;
|
||||
if (ua) unlockAll();
|
||||
_modeUsesLock = modeUsesLock(_segments[0].mode);
|
||||
setBrightness(_brightness);
|
||||
}
|
||||
|
||||
//TODO transitions
|
||||
|
||||
void WS2812FX::setSpeed(uint8_t s) {
|
||||
_segments[0].speed = s;
|
||||
}
|
||||
|
||||
void WS2812FX::setIntensity(uint8_t in) {
|
||||
_segments[0].intensity = in;
|
||||
}
|
||||
|
||||
void WS2812FX::setPalette(uint8_t p) {
|
||||
_segments[0].palette = p;
|
||||
}
|
||||
|
||||
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p) {
|
||||
bool changed = false;
|
||||
m = constrain(m, 0, MODE_COUNT - 1);
|
||||
if (m != _segments[0].mode) { setMode(m); changed = true; }
|
||||
if (s != _segments[0].speed) { setSpeed(s); changed = true; }
|
||||
if (i != _segments[0].intensity) { setIntensity(i); changed = true; }
|
||||
if (p != _segments[0].palette) { setPalette(p); changed = true; }
|
||||
return changed;
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
setColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
void WS2812FX::setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
setSecondaryColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint32_t c) {
|
||||
_segments[0].colors[0] = c;
|
||||
}
|
||||
|
||||
void WS2812FX::setSecondaryColor(uint32_t c) {
|
||||
_segments[0].colors[1] = c;
|
||||
}
|
||||
|
||||
void WS2812FX::setBrightness(uint8_t b) {
|
||||
if (_brightness == b) return;
|
||||
_brightness = b;
|
||||
bus->SetBrightness(_brightness);
|
||||
show();
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getMode(void) {
|
||||
return _segments[0].mode;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getSpeed(void) {
|
||||
return _segments[0].speed;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getBrightness(void) {
|
||||
return _brightness;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getNumSegments(void) {
|
||||
return _num_segments;
|
||||
}
|
||||
|
||||
void WS2812FX::setNumSegments(uint8_t n) {
|
||||
_num_segments = n;
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getColor(void) {
|
||||
return _segments[0].colors[0];
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||
{
|
||||
if (_reverseMode) i = _length- 1 -i;
|
||||
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
||||
if (_cronixieMode)
|
||||
{
|
||||
if(i>6)return 0;
|
||||
byte o = 10*i;
|
||||
switch(_cronixieDigits[i])
|
||||
{
|
||||
case 0: i=o+5; break;
|
||||
case 1: i=o+0; break;
|
||||
case 2: i=o+6; break;
|
||||
case 3: i=o+1; break;
|
||||
case 4: i=o+7; break;
|
||||
case 5: i=o+2; break;
|
||||
case 6: i=o+8; break;
|
||||
case 7: i=o+3; break;
|
||||
case 8: i=o+9; break;
|
||||
case 9: i=o+4; break;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
RgbwColor lColor = bus->GetPixelColorRgbw(i);
|
||||
byte r = lColor.R, g = lColor.G, b = lColor.B;
|
||||
switch (colorOrder)
|
||||
{
|
||||
case 0: break; //0 = Grb
|
||||
case 1: r = lColor.G; g = lColor.R; break; //1 = Rgb, common for WS2811
|
||||
case 2: g = lColor.B; b = lColor.G; break; //2 = Brg
|
||||
case 3: r = lColor.B; g = lColor.R; b = lColor.G; //3 = Rbg
|
||||
}
|
||||
return ( (lColor.W << 24) | (r << 16) | (g << 8) | (b) );
|
||||
}
|
||||
|
||||
WS2812FX::Segment WS2812FX::getSegment(void) {
|
||||
return SEGMENT;
|
||||
}
|
||||
|
||||
WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) {
|
||||
return SEGMENT_RUNTIME;
|
||||
}
|
||||
|
||||
WS2812FX::Segment* WS2812FX::getSegments(void) {
|
||||
return _segments;
|
||||
}
|
||||
|
||||
void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint8_t speed, uint8_t intensity, bool reverse) {
|
||||
uint32_t colors[] = {color, 0, 0};
|
||||
setSegment(n, start, stop, mode, colors, speed, intensity, reverse);
|
||||
}
|
||||
|
||||
void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint8_t speed, uint8_t intensity, bool reverse) {
|
||||
setSegment(n, start, stop, mode, colors, speed, intensity, (uint8_t)(reverse ? REVERSE : NO_OPTIONS));
|
||||
}
|
||||
|
||||
void WS2812FX::setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint8_t speed, uint8_t intensity, uint8_t options) {
|
||||
if(n < (sizeof(_segments) / sizeof(_segments[0]))) {
|
||||
if(n + 1 > _num_segments) _num_segments = n + 1;
|
||||
_segments[n].start = start;
|
||||
_segments[n].stop = stop;
|
||||
_segments[n].mode = mode;
|
||||
_segments[n].speed = speed;
|
||||
_segments[n].intensity = intensity;
|
||||
_segments[n].options = options;
|
||||
|
||||
for(uint8_t i=0; i<NUM_COLORS; i++) {
|
||||
_segments[n].colors[i] = colors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::resetSegments() {
|
||||
memset(_segments, 0, sizeof(_segments));
|
||||
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
|
||||
_segment_index = 0;
|
||||
_num_segments = 1;
|
||||
setSegment(0, 0, 7, FX_MODE_STATIC, (const uint32_t[]){DEFAULT_COLOR, 0, 0}, DEFAULT_SPEED, 128, NO_OPTIONS);
|
||||
}
|
||||
|
||||
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
if (i >= 0 && i < _length)
|
||||
{
|
||||
_locked[i] = false;
|
||||
setPixelColor(i, col);
|
||||
_locked[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)
|
||||
{
|
||||
if (i2 >= i)
|
||||
{
|
||||
for (uint16_t x = i; x <= i2; x++) setIndividual(x,col);
|
||||
} else
|
||||
{
|
||||
for (uint16_t x = i2; x <= i; x++) setIndividual(x,col);
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::lock(uint16_t i)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
if (i >= 0 && i < _length) _locked[i] = true;
|
||||
}
|
||||
|
||||
void WS2812FX::lockRange(uint16_t i, uint16_t i2)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
for (uint16_t x = i; x <= i2; x++)
|
||||
{
|
||||
if (i >= 0 && i < _length) _locked[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::unlock(uint16_t i)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
if (i >= 0 && i < _length) _locked[i] = false;
|
||||
}
|
||||
|
||||
void WS2812FX::unlockRange(uint16_t i, uint16_t i2)
|
||||
{
|
||||
if (modeUsesLock(SEGMENT.mode)) return;
|
||||
for (uint16_t x = i; x < i2; x++)
|
||||
{
|
||||
if (x >= 0 && x < _length) _locked[x] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::unlockAll()
|
||||
{
|
||||
for (int i=0; i < _length; i++) _locked[i] = false;
|
||||
}
|
||||
|
||||
void WS2812FX::setTransitionMode(bool t)
|
||||
{
|
||||
SEGMENT_RUNTIME.trans_act = (t) ? 1:2;
|
||||
if (!t) return;
|
||||
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
|
||||
if (SEGMENT.mode == FX_MODE_STATIC && SEGMENT_RUNTIME.next_time > waitMax) SEGMENT_RUNTIME.next_time = waitMax;
|
||||
}
|
||||
|
||||
/*
|
||||
* color blend function
|
||||
*/
|
||||
uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) {
|
||||
if(blend == 0) return color1;
|
||||
if(blend == 255) return color2;
|
||||
|
||||
int w1 = (color1 >> 24) & 0xff;
|
||||
int r1 = (color1 >> 16) & 0xff;
|
||||
int g1 = (color1 >> 8) & 0xff;
|
||||
int b1 = color1 & 0xff;
|
||||
|
||||
int w2 = (color2 >> 24) & 0xff;
|
||||
int r2 = (color2 >> 16) & 0xff;
|
||||
int g2 = (color2 >> 8) & 0xff;
|
||||
int b2 = color2 & 0xff;
|
||||
|
||||
uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8;
|
||||
uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8;
|
||||
uint32_t g3 = ((g2 * blend) + (g1 * (255 - blend))) >> 8;
|
||||
uint32_t b3 = ((b2 * blend) + (b1 * (255 - blend))) >> 8;
|
||||
|
||||
return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3));
|
||||
}
|
||||
|
||||
/*
|
||||
* Fills segment with color
|
||||
*/
|
||||
void WS2812FX::fill(uint32_t c) {
|
||||
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) {
|
||||
setPixelColor(i, c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fade out function, higher rate = quicker fade
|
||||
*/
|
||||
void WS2812FX::fade_out(uint8_t rate) {
|
||||
rate = (255-rate) >> 1;
|
||||
float mappedRate = float(rate) +1.1;
|
||||
|
||||
uint32_t color = SEGMENT.colors[1]; // target color
|
||||
int w2 = (color >> 24) & 0xff;
|
||||
int r2 = (color >> 16) & 0xff;
|
||||
int g2 = (color >> 8) & 0xff;
|
||||
int b2 = color & 0xff;
|
||||
|
||||
for(uint16_t i=SEGMENT.start; i <= SEGMENT.stop; i++) {
|
||||
color = getPixelColor(i);
|
||||
int w1 = (color >> 24) & 0xff;
|
||||
int r1 = (color >> 16) & 0xff;
|
||||
int g1 = (color >> 8) & 0xff;
|
||||
int b1 = color & 0xff;
|
||||
|
||||
int wdelta = (w2 - w1) / mappedRate;
|
||||
int rdelta = (r2 - r1) / mappedRate;
|
||||
int gdelta = (g2 - g1) / mappedRate;
|
||||
int bdelta = (b2 - b1) / mappedRate;
|
||||
|
||||
// if fade isn't complete, make sure delta is at least 1 (fixes rounding issues)
|
||||
wdelta += (w2 == w1) ? 0 : (w2 > w1) ? 1 : -1;
|
||||
rdelta += (r2 == r1) ? 0 : (r2 > r1) ? 1 : -1;
|
||||
gdelta += (g2 == g1) ? 0 : (g2 > g1) ? 1 : -1;
|
||||
bdelta += (b2 == b1) ? 0 : (b2 > b1) ? 1 : -1;
|
||||
|
||||
setPixelColor(i, r1 + rdelta, g1 + gdelta, b1 + bdelta, w1 + wdelta);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* blurs segment content, source: FastLED colorutils.cpp
|
||||
*/
|
||||
void WS2812FX::blur(uint8_t blur_amount)
|
||||
{
|
||||
uint8_t keep = 255 - blur_amount;
|
||||
uint8_t seep = blur_amount >> 1;
|
||||
CRGB carryover = CRGB::Black;
|
||||
for(uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++)
|
||||
{
|
||||
CRGB cur = fastled_from_col(getPixelColor(i));
|
||||
CRGB part = cur;
|
||||
part.nscale8(seep);
|
||||
cur.nscale8(keep);
|
||||
cur += carryover;
|
||||
if(i > SEGMENT.start) {
|
||||
uint32_t c = getPixelColor(i-1);
|
||||
uint8_t r = (c >> 16 & 0xFF);
|
||||
uint8_t g = (c >> 8 & 0xFF);
|
||||
uint8_t b = (c & 0xFF);
|
||||
setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue));
|
||||
}
|
||||
setPixelColor(i,cur.red, cur.green, cur.blue);
|
||||
carryover = part;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a value 0 to 255 in to get a color value.
|
||||
* The colours are a transition r -> g -> b -> back to r
|
||||
* Inspired by the Adafruit examples.
|
||||
*/
|
||||
uint32_t WS2812FX::color_wheel(uint8_t pos) {
|
||||
if (SEGMENT.palette) return color_from_palette(pos, false, true, 0);
|
||||
pos = 255 - pos;
|
||||
if(pos < 85) {
|
||||
return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3);
|
||||
} else if(pos < 170) {
|
||||
pos -= 85;
|
||||
return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3);
|
||||
} else {
|
||||
pos -= 170;
|
||||
return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a new, random wheel index with a minimum distance of 42 from pos.
|
||||
*/
|
||||
uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
|
||||
uint8_t r = 0, x = 0, y = 0, d = 0;
|
||||
|
||||
while(d < 42) {
|
||||
r = random8();
|
||||
x = abs(pos - r);
|
||||
y = 255 - x;
|
||||
d = min(x, y);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
CRGB WS2812FX::fastled_from_col(uint32_t color)
|
||||
{
|
||||
CRGB fastled_col;
|
||||
fastled_col.red = (color >> 16 & 0xFF);
|
||||
fastled_col.green = (color >> 8 & 0xFF);
|
||||
fastled_col.blue = (color & 0xFF);
|
||||
return fastled_col;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FastLED palette modes helper function. Limitation: Due to memory reasons, multiple active segments with FastLED will disable the Palette transitions
|
||||
*/
|
||||
void WS2812FX::handle_palette(void)
|
||||
{
|
||||
bool singleSegmentMode = (_segment_index == _segment_index_palette_last);
|
||||
_segment_index_palette_last = _segment_index;
|
||||
|
||||
byte paletteIndex = SEGMENT.palette;
|
||||
if ((SEGMENT.mode >= FX_MODE_METEOR) && SEGMENT.palette == 0) paletteIndex = 4;
|
||||
|
||||
switch (paletteIndex)
|
||||
{
|
||||
case 0: {//default palette. Differs depending on effect
|
||||
switch (SEGMENT.mode)
|
||||
{
|
||||
case FX_MODE_FIRE_2012 : targetPalette = gGradientPalettes[22]; break;//heat palette
|
||||
case FX_MODE_COLORWAVES : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
||||
case FX_MODE_FILLNOISE8 : targetPalette = OceanColors_p; break;
|
||||
case FX_MODE_NOISE16_1 : targetPalette = gGradientPalettes[17]; break;//Drywet
|
||||
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_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33
|
||||
|
||||
default: targetPalette = PartyColors_p; break;//palette, bpm
|
||||
}
|
||||
break;}
|
||||
case 1: {//periodically replace palette with a random one. Doesn't work with multiple FastLED segments
|
||||
if (!singleSegmentMode)
|
||||
{
|
||||
targetPalette = PartyColors_p; break; //fallback
|
||||
}
|
||||
if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-SEGMENT.intensity))*100)
|
||||
{
|
||||
targetPalette = CRGBPalette16(
|
||||
CHSV(random8(), 255, random8(128, 255)),
|
||||
CHSV(random8(), 255, random8(128, 255)),
|
||||
CHSV(random8(), 192, random8(128, 255)),
|
||||
CHSV(random8(), 255, random8(128, 255)));
|
||||
_lastPaletteChange = millis();
|
||||
} break;}
|
||||
case 2: {//primary color only
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
targetPalette = CRGBPalette16(prim); break;}
|
||||
case 3: {//based on primary
|
||||
//considering performance implications
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CHSV prim_hsv = rgb2hsv_approximate(prim);
|
||||
targetPalette = CRGBPalette16(
|
||||
CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself
|
||||
CHSV(prim_hsv.h, max(prim_hsv.s - 50,0), prim_hsv.v), //less saturated
|
||||
CHSV(prim_hsv.h, prim_hsv.s, max(prim_hsv.v - 50,0)), //darker
|
||||
CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v)); //color itself
|
||||
break;}
|
||||
case 4: {//primary + secondary
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CRGB sec = fastled_from_col(SEGMENT.colors[1]);
|
||||
targetPalette = CRGBPalette16(sec,prim); break;}
|
||||
case 5: {//based on primary + secondary
|
||||
CRGB prim = fastled_from_col(SEGMENT.colors[0]);
|
||||
CRGB sec = fastled_from_col(SEGMENT.colors[1]);
|
||||
targetPalette = CRGBPalette16(sec,prim,CRGB::White); break;}
|
||||
case 6: //Party colors
|
||||
targetPalette = PartyColors_p; break;
|
||||
case 7: //Cloud colors
|
||||
targetPalette = CloudColors_p; break;
|
||||
case 8: //Lava colors
|
||||
targetPalette = LavaColors_p; break;
|
||||
case 9: //Ocean colors
|
||||
targetPalette = OceanColors_p; break;
|
||||
case 10: //Forest colors
|
||||
targetPalette = ForestColors_p; break;
|
||||
case 11: //Rainbow colors
|
||||
targetPalette = RainbowColors_p; break;
|
||||
case 12: //Rainbow stripe colors
|
||||
targetPalette = RainbowStripeColors_p; break;
|
||||
default: //progmem palettes
|
||||
targetPalette = gGradientPalettes[constrain(SEGMENT.palette -13, 0, gGradientPaletteCount -1)];
|
||||
}
|
||||
|
||||
if (singleSegmentMode && paletteFade) //only blend if just one segment uses FastLED mode
|
||||
{
|
||||
nblendPaletteTowardPalette(currentPalette, targetPalette, 48);
|
||||
} else
|
||||
{
|
||||
currentPalette = targetPalette;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||
{
|
||||
if (SEGMENT.palette == 0 && mcol < 3) return SEGMENT.colors[mcol]; //WS2812FX default
|
||||
uint8_t paletteIndex = i;
|
||||
if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop,0,255);
|
||||
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||
CRGB fastled_col;
|
||||
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);
|
||||
return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="utf-8">
|
||||
<head><meta charset="utf-8"><meta name="theme-color" content="#fff">
|
||||
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
|
||||
<title>WLED 0.6.2</title>
|
||||
<title>WLED 0.8.3</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var w=window.getComputedStyle(d.querySelector("html"));
|
||||
@@ -18,6 +18,9 @@
|
||||
var nState = 0;
|
||||
var cv=0;
|
||||
var lm=0;
|
||||
var fxi=0;
|
||||
var fpi=0;
|
||||
var fxn=1;
|
||||
aC="";
|
||||
bC="";
|
||||
dC="";
|
||||
@@ -26,16 +29,22 @@
|
||||
{
|
||||
return d.getElementById(s);
|
||||
}
|
||||
|
||||
function Startup()
|
||||
function UCol()
|
||||
{
|
||||
var w=window.getComputedStyle(d.querySelector("html"));
|
||||
aC = w.getPropertyValue("--aCol");
|
||||
bC = w.getPropertyValue("--bCol");
|
||||
dC = w.getPropertyValue("--dCol");
|
||||
d.querySelector("meta[name=theme-color]").setAttribute("content",bC);
|
||||
}
|
||||
function Startup()
|
||||
{
|
||||
var w=window.getComputedStyle(d.querySelector("html"));
|
||||
UCol();
|
||||
CV(0);
|
||||
setInterval('GIO()', 5000);
|
||||
setInterval(GIO, 5000);
|
||||
GIO();
|
||||
setTimeout(function(){fillfx(0);}, 500);
|
||||
setTimeout(function(){fillfx(1);}, 750);
|
||||
}
|
||||
function GIO()
|
||||
{
|
||||
@@ -56,16 +65,29 @@
|
||||
} else {
|
||||
uwv = false;
|
||||
}
|
||||
Cf.TX.selectedIndex = this.responseXML.getElementsByTagName('fx')[0].childNodes[0].nodeValue;
|
||||
fxi = this.responseXML.getElementsByTagName('fx')[0].childNodes[0].nodeValue;
|
||||
fpi = this.responseXML.getElementsByTagName('fp')[0].childNodes[0].nodeValue;
|
||||
d.Cf.SX.value = this.responseXML.getElementsByTagName('sx')[0].childNodes[0].nodeValue;
|
||||
d.Cf.IX.value = this.responseXML.getElementsByTagName('ix')[0].childNodes[0].nodeValue;
|
||||
nla = (this.responseXML.getElementsByTagName('nl')[0].innerHTML)!=0?true:false;
|
||||
if(firstload){
|
||||
d.Cf.NC.checked = (this.responseXML.getElementsByTagName('nf')[0].innerHTML)!=0?true:false;
|
||||
d.Cf.SN.value = this.responseXML.getElementsByTagName('nd')[0].childNodes[0].nodeValue;
|
||||
d.Cf.ST.value = this.responseXML.getElementsByTagName('nt')[0].childNodes[0].nodeValue;
|
||||
CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue));
|
||||
}firstload=false;
|
||||
d.Cf.NC.checked = (this.responseXML.getElementsByTagName('nf')[0].innerHTML)!=0?true:false;
|
||||
d.Cf.SN.value = this.responseXML.getElementsByTagName('nd')[0].childNodes[0].nodeValue;
|
||||
d.Cf.ST.value = this.responseXML.getElementsByTagName('nt')[0].childNodes[0].nodeValue;
|
||||
d.documentElement.style.setProperty("--aCol",this.responseXML.getElementsByTagName('ca')[0].childNodes[0].nodeValue);
|
||||
d.documentElement.style.setProperty("--bCol",this.responseXML.getElementsByTagName('cb')[0].childNodes[0].nodeValue);
|
||||
d.documentElement.style.setProperty("--cCol",this.responseXML.getElementsByTagName('cc')[0].childNodes[0].nodeValue);
|
||||
d.documentElement.style.setProperty("--dCol",this.responseXML.getElementsByTagName('cd')[0].childNodes[0].nodeValue);
|
||||
d.documentElement.style.setProperty("--sCol",this.responseXML.getElementsByTagName('cu')[0].childNodes[0].nodeValue);
|
||||
d.documentElement.style.setProperty("--tCol",this.responseXML.getElementsByTagName('ct')[0].childNodes[0].nodeValue);
|
||||
d.documentElement.style.setProperty("--cFn",this.responseXML.getElementsByTagName('cf')[0].childNodes[0].nodeValue);
|
||||
UCol();
|
||||
CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue));
|
||||
}else{
|
||||
Cf.TX.selectedIndex = fxi;
|
||||
Cf.IX.selectedIndex = fpi;
|
||||
}
|
||||
firstload=false;
|
||||
nState = 0;
|
||||
nState = (this.responseXML.getElementsByTagName('nr')[0].innerHTML)!=0?1:0;
|
||||
nState += (this.responseXML.getElementsByTagName('ns')[0].innerHTML)!=0?2:0;
|
||||
@@ -75,7 +97,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
request.open("GET", "win/" +resp +nocache, true);
|
||||
if (firstload) resp+="&IT"
|
||||
request.open("GET", "win" +resp +nocache, true);
|
||||
request.send(null);
|
||||
resp="";
|
||||
}
|
||||
@@ -119,16 +142,9 @@
|
||||
d.Cf.SB.value=b;
|
||||
GC();
|
||||
}
|
||||
function GetCC()
|
||||
function GP()
|
||||
{
|
||||
resp+="&CP=";
|
||||
resp+=d.Cf.PF.value;
|
||||
resp+="&CS=";
|
||||
resp+=d.Cf.SF.value;
|
||||
resp+="&CM=";
|
||||
resp+=d.Cf.HF.value;
|
||||
resp+=(d.Cf.SC.checked)?"&CF=1":"&CF=0";
|
||||
resp+=(d.Cf.EC.checked)?"&CE=1":"&CE=0";
|
||||
resp+= "&FP=" + Cf.FP.selectedIndex;
|
||||
GIO();
|
||||
}
|
||||
function CV(v)
|
||||
@@ -177,8 +193,8 @@
|
||||
case 3: gId("path1").style.fill = aC; gId("path2").style.fill = aC;
|
||||
}
|
||||
tgb.style.fill=(Cf.SA.value>0)?aC:dC;
|
||||
ccX.style.display=(Cf.TX.selectedIndex>52)?"block":"none";
|
||||
fof.style.fill=(Cf.TX.selectedIndex>52)?aC:dC;
|
||||
fpX.style.display=(Cf.TX.selectedIndex>0)?"block":"none";
|
||||
fof.style.fill=(Cf.TX.selectedIndex>64)?aC:dC;
|
||||
fmr.style.fill=(Cf.TX.selectedIndex<1)?aC:dC;
|
||||
}
|
||||
function TgT()
|
||||
@@ -197,9 +213,10 @@
|
||||
function SwFX(s)
|
||||
{
|
||||
var n=Cf.TX.selectedIndex+s;
|
||||
if (n==-1||n==fxn) return;
|
||||
Cf.TX.selectedIndex =n;
|
||||
if (n < 0) Cf.TX.selectedIndex = 0;
|
||||
if (n > 57) Cf.TX.selectedIndex = 53;
|
||||
if (n > fxn) Cf.TX.selectedIndex = Math.min(65,fxn-1);
|
||||
GX();
|
||||
}
|
||||
function TgHSB()
|
||||
@@ -214,24 +231,25 @@
|
||||
function SwitchPS(x)
|
||||
{
|
||||
d.Cf.FF.value = parseInt(d.Cf.FF.value) +x;
|
||||
if (d.Cf.FF.value < 0) d.Cf.FF.value = 0;
|
||||
if (d.Cf.FF.value > 24) d.Cf.FF.value = 24;
|
||||
if (d.Cf.FF.value < 1) d.Cf.FF.value = 1;
|
||||
if (d.Cf.FF.value > 25) d.Cf.FF.value = 25;
|
||||
}
|
||||
function PAt()
|
||||
{
|
||||
resp+=(d.Cf.BC.checked)?"&PA=1":"&PA=0";
|
||||
resp+=(d.Cf.CC.checked)?"&PC=1":"&PC=0";
|
||||
resp+=(d.Cf.FC.checked)?"&PX=1":"&PX=0";
|
||||
}
|
||||
function PSIO(sv)
|
||||
{
|
||||
PAt();
|
||||
if(sv)
|
||||
{
|
||||
resp+="&PS=";
|
||||
resp+=d.Cf.FF.value;
|
||||
} else
|
||||
{
|
||||
if (d.Cf.BC.checked&&d.Cf.CC.checked&&d.Cf.FC.checked)
|
||||
{resp+="&PL=";resp+=d.Cf.FF.value;}
|
||||
else {
|
||||
if(d.Cf.BC.checked){resp+="&PA=";resp+=d.Cf.FF.value;}
|
||||
if(d.Cf.CC.checked){resp+="&PC=";resp+=d.Cf.FF.value;}
|
||||
if(d.Cf.FC.checked){resp+="&PX=";resp+=d.Cf.FF.value;}
|
||||
}
|
||||
resp+="&PL=";resp+=d.Cf.FF.value;
|
||||
}
|
||||
GIO();
|
||||
}
|
||||
@@ -305,7 +323,6 @@
|
||||
rr=diffc(r);
|
||||
gg=diffc(g);
|
||||
bb=diffc(b);
|
||||
|
||||
if(r===v) {
|
||||
h=bb-gg;
|
||||
}else if (g===v){
|
||||
@@ -335,14 +352,54 @@
|
||||
}
|
||||
GIO();
|
||||
}
|
||||
function uCY()
|
||||
{
|
||||
PAt();
|
||||
resp+=(d.Cf.CY.checked)?"&CY=1":"&CY=0";
|
||||
resp+="&P1=" + Cf.P1.value;
|
||||
resp+="&P2=" + Cf.P2.value;
|
||||
resp+="&PT=" + Cf.PT.value;
|
||||
GIO();
|
||||
}
|
||||
function R()
|
||||
{
|
||||
resp+="&PL=0";GIO();
|
||||
}
|
||||
function fillfx(fp)
|
||||
{
|
||||
e="<option>Error loading list!</option>";
|
||||
el = fp?Cf.FP:Cf.TX;
|
||||
fetch(fp?'/json/palettes':'/json/effects')
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
el.innerHTML=e;
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then(json => {
|
||||
var x="";
|
||||
var l=fp?json.palettes:json.effects;
|
||||
for (i in l) {
|
||||
x += "<option value=\""+i+"\">"+l[i]+" ("+i+")</option>";
|
||||
}
|
||||
el.innerHTML=x;
|
||||
el.selectedIndex=fp?fpi:fxi;
|
||||
if(!fp)fxn=l.length;
|
||||
UV();
|
||||
})
|
||||
.catch(function () {
|
||||
el.innerHTML=e;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
:root {
|
||||
--aCol: #0ac;
|
||||
--bCol: #124;
|
||||
--cCol: #334;
|
||||
--dCol: #288;
|
||||
--sCol: #FF00FF;
|
||||
--aCol: #D9B310;
|
||||
--bCol: #0B3C5D;
|
||||
--cCol: #1D2731;
|
||||
--dCol: #328CC1;
|
||||
--sCol: #000;
|
||||
--tCol: #328CC1;
|
||||
--cFn: Verdana;
|
||||
}
|
||||
.ctrl_box {
|
||||
@@ -575,64 +632,7 @@
|
||||
<svg id="fmf" onclick="SwFX(1)"><use xlink:href="#lnr-arrow-right-circle"></use></svg>
|
||||
<svg id="fof" onclick="SwFX(99)"><use xlink:href="#lnr-rocket"></use></svg><br><br>
|
||||
<select name="TX" onchange="GX()">
|
||||
<option value="0" selected>Static (0)</option>
|
||||
<option value="1">Blink (1)</option>
|
||||
<option value="2">Breath (2)</option>
|
||||
<option value="3">Wipe (3)</option>
|
||||
<option value="4">Wipe Random (4)</option>
|
||||
<option value="5">Color R (5)</option>
|
||||
<option value="6">Easter (6)</option>
|
||||
<option value="7">Dynamic (7)</option>
|
||||
<option value="8">Colorloop (8)</option>
|
||||
<option value="9">Rainbow (9)</option>
|
||||
<option value="10">Scan (10)</option>
|
||||
<option value="11">Scan x2 (11)</option>
|
||||
<option value="12">Fade (12)</option>
|
||||
<option value="13">Chase (13)</option>
|
||||
<option value="14">Chase Cl (14)</option>
|
||||
<option value="15">Running (15)</option>
|
||||
<option value="16">Twinkle (16)</option>
|
||||
<option value="17">Twinkle R (17)</option>
|
||||
<option value="18">Twinkle Fade (18)</option>
|
||||
<option value="19">Twinkle RF (19)</option>
|
||||
<option value="20">Sparkle (20)</option>
|
||||
<option value="21">Sparkle Inv (21)</option>
|
||||
<option value="22">Sparkle Inv+ (22)</option>
|
||||
<option value="23">Strobe (23)</option>
|
||||
<option value="24">Strobe Cl (24)</option>
|
||||
<option value="25">Strobe + (25)</option>
|
||||
<option value="26">Blink Cl (26)</option>
|
||||
<option value="27">Android (27)</option>
|
||||
<option value="28">Chase (28)</option>
|
||||
<option value="29">Chase R (29)</option>
|
||||
<option value="30">Chase Rainbow (30)</option>
|
||||
<option value="31">Chase Flash (31)</option>
|
||||
<option value="32">Chase RF (32)</option>
|
||||
<option value="33">Chase Cl Inv (33)</option>
|
||||
<option value="34">Colorful (34)</option>
|
||||
<option value="35">Traffic Light (35)</option>
|
||||
<option value="36">Sweep R(36)</option>
|
||||
<option value="37">Running 2 (37)</option>
|
||||
<option value="38">Red/Blue (38)</option>
|
||||
<option value="39">Running R (39)</option>
|
||||
<option value="40">Scanner (40)</option>
|
||||
<option value="41">Lighthouse (41)</option>
|
||||
<option value="42">Fireworks (42)</option>
|
||||
<option value="43">Fireworks R (43)</option>
|
||||
<option value="44">Christmas (44)</option>
|
||||
<option value="45">Fire Flicker (45)</option>
|
||||
<option value="46">Gradient (46)</option>
|
||||
<option value="47">Loading (47)</option>
|
||||
<option value="48">Wipe IO (48)</option>
|
||||
<option value="49">Wipe II (49)</option>
|
||||
<option value="50">Wipe OO (50)</option>
|
||||
<option value="51">Wipe OI (51)</option>
|
||||
<option value="52">Circus (52)</option>
|
||||
<option value="53">Custom Chase (53)</option>
|
||||
<option value="54">CC Colorloop (54)</option>
|
||||
<option value="55">CC Rainbow (55)</option>
|
||||
<option value="56">CC Blink (56)</option>
|
||||
<option value="57">CC Random (57)</option>
|
||||
<option>Loading...</option>
|
||||
</select><br><br>
|
||||
Set secondary color to
|
||||
<button type="button" onclick="CS(0)">White</button>
|
||||
@@ -641,12 +641,11 @@
|
||||
<button type="button" onclick="CS(3)">Primary</button>
|
||||
<button type="button" onclick="CS(4)">Swap P/S</button>
|
||||
or <button type="button" onclick="CS(5)">Set Primary to Random</button>
|
||||
<div id="ccX">
|
||||
<br>Custom Theater Chase<br>
|
||||
using <input id="ccP" name="PF" type="number" value="2" min="0" max="255" step="1" onchange="GetCC()"> primary and
|
||||
<input id="ccS" name ="SF" type="number" value="4" min="0" max="255" step="1" onchange="GetCC()"> secondary color LEDs,<br>
|
||||
doing <input id="ccH" name="HF" type="number" value="1" min="0" max="255" step="1" onchange="GetCC()"> steps per tick,
|
||||
from <input type="checkbox" onchange="GetCC()" name="SC"> start and <input type="checkbox" onchange="GetCC()" name="EC"> end.
|
||||
<div id="fpX">
|
||||
<br>FastLED Palette<br><br>
|
||||
<select name="FP" onchange="GP()">
|
||||
<option>Loading...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="slX" class="sl">
|
||||
<input type="range" title="Effect Speed" class="sds" name="SX" value="0" min="0" max="255" step="1" onchange="GX()"></div>
|
||||
@@ -659,14 +658,15 @@
|
||||
<svg id="psp" onclick="SwitchPS(-1)"><use xlink:href="#lnr-arrow-left-circle"></use></svg>
|
||||
<svg id="psn" onclick="SwitchPS(1)"><use xlink:href="#lnr-arrow-right-circle"></use></svg>
|
||||
<svg id="pss" onclick="PSIO(true)"><use xlink:href="#lnr-arrow-down-circle"></use></svg>
|
||||
<br><input id="psI" name = "FF" type="number" value="0" min="0" max="25" step="1"><br><br>
|
||||
Click checkmark to apply <input type="checkbox" checked="true" name="BC"> brightness, <input type="checkbox" checked="true" name="CC"> color and <input type="checkbox" checked="true" name="FC"> effects.<br>
|
||||
Effect 0 is the configuration when the light is powered up.
|
||||
<br><input id="psI" name = "FF" type="number" value="1" min="1" max="25" step="1"><br><br>
|
||||
Click checkmark to apply <input type="checkbox" checked name="CC"> color, <input type="checkbox" checked name="FC"> effects and <input type="checkbox" name="BC"> brightness.<br><br>
|
||||
Cycle through presets <input id="cy1" name="P1" type="number" value="1" min="1" max="25" step="1"> to <input id="cy2" name="P2" type="number" value="5" min="1" max="25" step="1">, keep each for <input id="cyT" name="PT" type="number" value="1250" min="50" max="65501" step="1">ms: <input type="checkbox" name="CY" onclick="uCY()"><br><br>
|
||||
<button type="button" onclick="R()">Apply boot config</button><br>
|
||||
</div>
|
||||
<div id="tlN" class="tools">
|
||||
Timed Light<br><br>
|
||||
<svg id="ntb" onclick="TgNl()"><use xlink:href="#lnr-power-switch"></use></svg><br><br>
|
||||
Gradually dim down <input type="checkbox" checked="true" name="NC"><br>
|
||||
Gradually dim down <input type="checkbox" checked name="NC"><br>
|
||||
1st slider sets duration (1-255min), 2nd sets target brightness.
|
||||
<div id="slN" class="sl">
|
||||
<input type="range" title="Duration" class="sds" name="SN" value="60" min="1" max="255" step="1"></div>
|
||||
|
||||
608
wled00/data/index_mobile.htm
Normal file
608
wled00/data/index_mobile.htm
Normal file
File diff suppressed because one or more lines are too long
@@ -1,5 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta content='width=device-width' name='viewport'>
|
||||
<title>WLED Message</title>
|
||||
<script>
|
||||
function B() {
|
||||
@@ -9,7 +10,7 @@
|
||||
window.location = "/settings";
|
||||
}
|
||||
function RP() {
|
||||
top.location.href=top.location.href;
|
||||
top.location.href="/";
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
margin: 0;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
html {
|
||||
--h:11.55vh;
|
||||
}
|
||||
button {
|
||||
background: var(--bCol);
|
||||
color: var(--tCol);
|
||||
@@ -27,13 +30,23 @@
|
||||
display: inline-block;
|
||||
filter: drop-shadow( -5px -5px 5px var(--sCol) );
|
||||
font-size: 8vmin;
|
||||
height:13.86vh;
|
||||
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>
|
||||
<body>
|
||||
<body onload="BB()">
|
||||
<form action="/"><button type=submit id="b">Back</button></form>
|
||||
<form action="/settings/wifi"><button type="submit">WiFi Setup</button></form>
|
||||
<form action="/settings/leds"><button type="submit">LED Preferences</button></form>
|
||||
<form action="/settings/ui"><button type="submit">User Interface</button></form>
|
||||
|
||||
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,6 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content='width=device-width' name='viewport'>
|
||||
<title>WLED Setup</title>
|
||||
<style>
|
||||
:root {
|
||||
@@ -14,9 +15,7 @@
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
background: linear-gradient(var(--bCol),black);
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
color: var(--dCol);
|
||||
}
|
||||
|
||||
658
wled00/html_classic.h
Normal file
658
wled00/html_classic.h
Normal file
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
* 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://sourceforge.net/projects/bin2header/)
|
||||
* alternative: https://littlevgl.com/image-to-c-array (raw)
|
||||
* 4. update length value
|
||||
*/
|
||||
|
||||
const uint16_t PAGE_index0_L = 10264;
|
||||
|
||||
const char PAGE_index0[] PROGMEM = {
|
||||
0x1f, 0x8b, 0x08, 0x08, 0x67, 0x5e, 0x61, 0x5c, 0x00, 0x03, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x20, 0x28, 0x37, 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, 0x38, 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,
|
||||
0x09, 0xfb, 0x09, 0x34, 0x8d, 0xd0, 0xfa, 0x96, 0xda, 0x90, 0x81, 0x6d, 0x7f, 0xb0, 0xcc, 0xf2,
|
||||
0xc0, 0x0f, 0x26, 0x91, 0xd7, 0xfa, 0x7e, 0xfd, 0x75, 0xf8, 0xb3, 0x5f, 0x4d, 0x94, 0xc2, 0x87,
|
||||
0x48, 0xd3, 0x76, 0xe7, 0x07, 0x4d, 0x65, 0xff, 0x98, 0xfd, 0x8b, 0x08, 0xf2, 0x94, 0x95, 0x97,
|
||||
0x45, 0x57, 0xd2, 0xe5, 0xcf, 0x1f, 0xde, 0x55, 0xd5, 0xec, 0x23, 0x9f, 0x6a, 0x93, 0x3b, 0xb3,
|
||||
0x2f, 0x25, 0xcf, 0x0a, 0x84, 0xef, 0x4d, 0x49, 0xde, 0x85, 0xe8, 0xcd, 0xc6, 0x91, 0xb7, 0xe1,
|
||||
0xe9, 0x60, 0x99, 0xc4, 0xed, 0x6a, 0x92, 0x94, 0x0a, 0x43, 0xe2, 0x2e, 0xe8, 0x99, 0x9d, 0xf5,
|
||||
0x34, 0x2d, 0x9b, 0x97, 0x9e, 0xa7, 0x43, 0xac, 0x1a, 0x6e, 0x39, 0xcb, 0xb3, 0x32, 0x02, 0xcd,
|
||||
0x67, 0x5e, 0x36, 0x4f, 0xd3, 0xce, 0x32, 0x54, 0x4e, 0x62, 0xe5, 0xfc, 0xa5, 0xb2, 0x20, 0x5b,
|
||||
0x7b, 0xdb, 0x58, 0x35, 0xbf, 0x2b, 0x5f, 0xdd, 0x5c, 0xf8, 0xe3, 0x53, 0x18, 0xbb, 0xfd, 0xc2,
|
||||
0x0f, 0x5e, 0x74, 0x7e, 0x57, 0xff, 0x50, 0x82, 0x49, 0x92, 0x86, 0xa7, 0x79, 0x18, 0x95, 0x34,
|
||||
0xca, 0xf0, 0xc1, 0x5c, 0x66, 0xc8, 0x37, 0xfd, 0xb8, 0xdf, 0xa6, 0x41, 0xba, 0xcb, 0xa6, 0x6f,
|
||||
0xbf, 0x61, 0x53, 0xed, 0xa9, 0x4d, 0x5f, 0x7d, 0xc3, 0xa6, 0xfa, 0xc3, 0x9b, 0xde, 0xa3, 0xee,
|
||||
0x07, 0x76, 0xba, 0x5a, 0x3c, 0x2a, 0xf3, 0xb1, 0xa7, 0xae, 0x2c, 0xf4, 0x69, 0x3f, 0x16, 0x9f,
|
||||
0xd8, 0x78, 0x48, 0xf9, 0x8e, 0xa5, 0xb3, 0xdb, 0x08, 0x49, 0x6f, 0xb9, 0x49, 0x7f, 0x70, 0x6d,
|
||||
0x24, 0xac, 0x1d, 0xa9, 0xc4, 0xd7, 0x8f, 0x53, 0xa1, 0x8c, 0xb7, 0xeb, 0x56, 0xb3, 0x5d, 0xac,
|
||||
0x7f, 0xb9, 0x9f, 0x16, 0xca, 0x27, 0xf8, 0x63, 0x9b, 0xbe, 0xdf, 0x73, 0xd3, 0xe4, 0x89, 0x4d,
|
||||
0xa9, 0x04, 0xed, 0x6a, 0xff, 0x4c, 0xf8, 0x7c, 0x92, 0x65, 0x51, 0xf1, 0xee, 0xe2, 0xe7, 0x0f,
|
||||
0x9d, 0x67, 0x9e, 0xfa, 0x23, 0x19, 0x66, 0xc0, 0xcd, 0x01, 0x57, 0x5a, 0xd7, 0x1f, 0xe1, 0x0a,
|
||||
0xa7, 0x27, 0x20, 0x1d, 0x05, 0x5f, 0xa2, 0x70, 0x77, 0x32, 0xf1, 0x13, 0x64, 0xb8, 0x76, 0x4f,
|
||||
0xf7, 0x53, 0x44, 0x16, 0xee, 0x62, 0xb2, 0x8b, 0x3d, 0x37, 0xad, 0x9e, 0xda, 0x74, 0xd5, 0x2e,
|
||||
0x88, 0xc5, 0xc8, 0x74, 0x28, 0x11, 0x54, 0x71, 0x56, 0x65, 0x6b, 0x5d, 0xf1, 0xba, 0xbb, 0xc6,
|
||||
0xb3, 0xff, 0x28, 0xcd, 0xce, 0xae, 0x44, 0x47, 0x7b, 0x11, 0x1d, 0xfd, 0x3d, 0x44, 0x83, 0xbd,
|
||||
0x88, 0x3e, 0x9e, 0xb8, 0x77, 0x26, 0x1a, 0xee, 0x45, 0xf4, 0x71, 0x3f, 0xd9, 0x99, 0x68, 0xb9,
|
||||
0x17, 0xd1, 0xf9, 0xdf, 0x43, 0xb4, 0xda, 0x8b, 0xe8, 0xe3, 0xce, 0xbb, 0xbb, 0x4d, 0xdf, 0x64,
|
||||
0xbb, 0xd3, 0x8c, 0x9f, 0xa0, 0xb9, 0xe9, 0x91, 0x66, 0x74, 0x04, 0x40, 0x8b, 0xb4, 0x6b, 0xda,
|
||||
0x98, 0x3e, 0x61, 0xb8, 0x8e, 0xa8, 0x1e, 0x08, 0xf3, 0x8b, 0x4b, 0xc8, 0x40, 0xdd, 0x59, 0x14,
|
||||
0xbe, 0xcf, 0xc2, 0xe8, 0xda, 0x43, 0x15, 0x19, 0xf2, 0xe4, 0xba, 0x35, 0x3f, 0x4b, 0xa8, 0xc6,
|
||||
0xac, 0x7b, 0x6a, 0x9e, 0x7f, 0xd6, 0x3d, 0xb4, 0xf8, 0xd8, 0x39, 0xb1, 0x15, 0xf7, 0x25, 0x36,
|
||||
0x6d, 0xb0, 0xda, 0xe8, 0x70, 0xf7, 0x9d, 0xca, 0xfb, 0x76, 0xd2, 0xb1, 0x53, 0xd8, 0x5c, 0x71,
|
||||
0x82, 0xe6, 0xbf, 0x64, 0x6b, 0x5a, 0x50, 0x48, 0xd0, 0x6a, 0xae, 0xda, 0x35, 0xcd, 0x85, 0xdb,
|
||||
0xe4, 0x86, 0xff, 0xf8, 0x15, 0x46, 0xba, 0xc5, 0xbf, 0x83, 0x46, 0xce, 0xa7, 0xad, 0x0e, 0xd1,
|
||||
0x56, 0xbe, 0xbf, 0x68, 0x1d, 0xac, 0x3b, 0xc3, 0x59, 0x94, 0xb5, 0x5b, 0x6f, 0x5f, 0x5f, 0xb4,
|
||||
0xba, 0x2d, 0xb4, 0xcc, 0xad, 0x43, 0x86, 0x24, 0x1a, 0xcf, 0x2e, 0xa5, 0xf5, 0x4d, 0x17, 0x59,
|
||||
0x46, 0x59, 0xd8, 0x66, 0xad, 0xde, 0xfa, 0x9c, 0x54, 0xef, 0x5e, 0x4f, 0xda, 0xec, 0x94, 0xc1,
|
||||
0x69, 0xbc, 0x44, 0xd3, 0x5a, 0xeb, 0x06, 0x87, 0xab, 0xf9, 0x8f, 0x62, 0xfe, 0xe3, 0xd6, 0xfc,
|
||||
0x5b, 0x31, 0xff, 0x76, 0x6b, 0xfe, 0x95, 0x98, 0x17, 0x6d, 0x15, 0x15, 0x31, 0x34, 0x18, 0x6b,
|
||||
0x51, 0x3e, 0x09, 0xb0, 0x68, 0x69, 0xb8, 0xe4, 0xbc, 0x4d, 0xaf, 0xb3, 0x76, 0x59, 0x67, 0xed,
|
||||
0xcd, 0x25, 0x5f, 0xb4, 0xed, 0x67, 0x6b, 0x9a, 0xe7, 0x02, 0x61, 0xd5, 0x22, 0xac, 0x01, 0xef,
|
||||
0x05, 0x60, 0x55, 0xe6, 0x1f, 0x22, 0x17, 0x55, 0x1f, 0xdf, 0xbe, 0x5a, 0x1d, 0x45, 0x8a, 0xee,
|
||||
0xb8, 0x3b, 0xea, 0x26, 0xdd, 0xb8, 0x3b, 0xeb, 0x7e, 0xed, 0xf2, 0x93, 0xe9, 0xc4, 0xe3, 0x05,
|
||||
0xed, 0x1d, 0xdf, 0xa7, 0x5b, 0x8a, 0xf1, 0xb9, 0x18, 0x2f, 0x3c, 0xdd, 0xb2, 0x86, 0x89, 0xc7,
|
||||
0xda, 0xfe, 0x38, 0xcd, 0x71, 0x4e, 0x99, 0xfc, 0x60, 0x77, 0x86, 0xb1, 0x87, 0x97, 0x9c, 0x0c,
|
||||
0x67, 0xde, 0xe2, 0x87, 0xb6, 0x26, 0xe3, 0xe8, 0xf6, 0x95, 0x7f, 0xc5, 0x3f, 0xe0, 0xbb, 0xe2,
|
||||
0xdf, 0x34, 0xec, 0xd0, 0xb8, 0xbc, 0x4a, 0xaa, 0x60, 0xd2, 0x4e, 0xbe, 0xb3, 0x3b, 0xcb, 0xc0,
|
||||
0x2f, 0x23, 0x49, 0x1d, 0x14, 0xde, 0xa2, 0x3b, 0xf6, 0xaa, 0xee, 0xc8, 0x9b, 0x0d, 0x47, 0x68,
|
||||
0xf7, 0xbf, 0x0c, 0x19, 0x40, 0x03, 0xe0, 0x2b, 0x00, 0x8b, 0x6d, 0x80, 0x0e, 0xc0, 0x4c, 0x00,
|
||||
0xaa, 0x3a, 0xc0, 0x10, 0x80, 0xaf, 0x00, 0x2c, 0xea, 0x00, 0x13, 0x80, 0x0a, 0x80, 0xd9, 0x36,
|
||||
0xc0, 0x12, 0xc4, 0x09, 0xf0, 0x15, 0xea, 0x6a, 0x36, 0xf6, 0xc5, 0x56, 0x4f, 0x3e, 0xde, 0x6a,
|
||||
0xa7, 0x47, 0x43, 0xf2, 0xaf, 0x86, 0x96, 0xcf, 0x1a, 0x46, 0x3d, 0xe3, 0xa6, 0x79, 0x73, 0xb6,
|
||||
0x65, 0xd4, 0x3b, 0xd6, 0x41, 0xf2, 0x5a, 0xf0, 0x33, 0x0f, 0x8e, 0xed, 0x9d, 0x93, 0x34, 0x2f,
|
||||
0xa3, 0xf3, 0xa8, 0xaa, 0x92, 0x6c, 0x5c, 0x02, 0x91, 0x4e, 0xcb, 0xad, 0x32, 0x7d, 0x49, 0x07,
|
||||
0x4f, 0x96, 0x4e, 0xc3, 0xa4, 0x9c, 0xa5, 0xfe, 0x8d, 0xd7, 0xca, 0xf2, 0x2c, 0x6a, 0x09, 0x78,
|
||||
0x31, 0x1e, 0x3d, 0x8e, 0x30, 0x29, 0x1f, 0x87, 0xa7, 0x9f, 0x1e, 0x85, 0x57, 0xe9, 0xe5, 0x13,
|
||||
0xf0, 0xb3, 0x27, 0xe0, 0xa7, 0x0f, 0xc1, 0x21, 0xf7, 0xe2, 0x48, 0x67, 0xe7, 0x38, 0x0a, 0xa4,
|
||||
0x87, 0xd9, 0x19, 0xa5, 0x79, 0xf0, 0xa5, 0xf5, 0x88, 0x42, 0x04, 0xc2, 0xed, 0x81, 0xf0, 0xb3,
|
||||
0xc5, 0xda, 0xcb, 0x1e, 0x51, 0x92, 0x58, 0xc4, 0xae, 0x34, 0x1a, 0x0e, 0xf8, 0xb0, 0xde, 0x36,
|
||||
0x4b, 0xb4, 0xa6, 0x6b, 0x3e, 0xac, 0x0a, 0xb1, 0xa4, 0xe1, 0xaf, 0x0f, 0x2b, 0xf6, 0x2e, 0xb6,
|
||||
0x39, 0x78, 0x58, 0x8d, 0x6b, 0xb1, 0x83, 0x05, 0x1c, 0x7c, 0x1a, 0x8e, 0x04, 0x02, 0x9d, 0xec,
|
||||
0xbd, 0x76, 0x3a, 0x3d, 0x56, 0x3b, 0x3f, 0xfa, 0x27, 0x83, 0xf0, 0xa4, 0xee, 0x74, 0xd0, 0x85,
|
||||
0x3e, 0x89, 0xae, 0xdb, 0x45, 0x14, 0x76, 0xc7, 0x45, 0x14, 0x65, 0xdd, 0x11, 0x55, 0x3d, 0x9e,
|
||||
0x20, 0xc6, 0x23, 0x8f, 0x46, 0x7f, 0xb5, 0x19, 0xe4, 0xe8, 0xc8, 0xe9, 0xfc, 0x45, 0x88, 0x47,
|
||||
0x47, 0x9a, 0x4d, 0x99, 0x96, 0xae, 0x6d, 0x5e, 0x3c, 0x7f, 0x71, 0xd8, 0x56, 0xaf, 0xc5, 0xc1,
|
||||
0xff, 0x10, 0x4b, 0x3a, 0x4a, 0x95, 0x9f, 0x57, 0x05, 0xdc, 0xb6, 0x0d, 0x34, 0xa5, 0x4c, 0x93,
|
||||
0x20, 0x6a, 0x6b, 0x9d, 0x1a, 0xcd, 0x14, 0xb0, 0xc2, 0x0f, 0xdb, 0x2c, 0x01, 0x75, 0xc4, 0xfd,
|
||||
0x4f, 0x0b, 0xb3, 0x91, 0x5f, 0xc8, 0x04, 0x49, 0x50, 0x48, 0xda, 0xad, 0xc3, 0xd1, 0xc9, 0x21,
|
||||
0x92, 0xff, 0xe1, 0x9a, 0x45, 0x86, 0x7e, 0xd8, 0xea, 0x34, 0xb2, 0x3b, 0x65, 0xba, 0x03, 0x1c,
|
||||
0x1a, 0x46, 0x79, 0x78, 0x23, 0x04, 0x1e, 0xf9, 0xc1, 0x97, 0x71, 0x91, 0xcf, 0xb3, 0xd0, 0x5b,
|
||||
0x91, 0xaa, 0x45, 0x74, 0xb7, 0x16, 0xcd, 0xdd, 0x5a, 0x24, 0xb3, 0x8b, 0x91, 0x77, 0xe7, 0xbb,
|
||||
0xa1, 0xc6, 0xd7, 0x4d, 0xed, 0xb2, 0x9c, 0xb0, 0x9d, 0xb7, 0x37, 0x0a, 0xcf, 0xd2, 0x26, 0x3a,
|
||||
0x8e, 0x4f, 0x6b, 0x50, 0xf5, 0x20, 0x48, 0xb8, 0x2f, 0xaf, 0xf2, 0x10, 0xb2, 0xee, 0xc4, 0x33,
|
||||
0x24, 0x60, 0x6d, 0xed, 0x03, 0x6c, 0x29, 0x56, 0xac, 0x41, 0xfa, 0x1d, 0xd0, 0x5d, 0x9f, 0xbe,
|
||||
0x67, 0x0b, 0x7f, 0xd7, 0x2d, 0xf4, 0x6f, 0xe1, 0xc2, 0x3f, 0xb9, 0xc7, 0xf1, 0xf7, 0xe3, 0xc2,
|
||||
0x27, 0xe7, 0xad, 0xc6, 0x4d, 0x95, 0xd5, 0xca, 0xf9, 0x46, 0xe5, 0xf1, 0xec, 0x72, 0x2b, 0x40,
|
||||
0xda, 0x0f, 0x98, 0x48, 0x04, 0xce, 0x40, 0xe4, 0xa1, 0x38, 0x8f, 0xb7, 0x77, 0xbf, 0xb3, 0xca,
|
||||
0x36, 0xd7, 0x64, 0xa6, 0xc5, 0x53, 0xd8, 0x47, 0xda, 0x3d, 0x71, 0x77, 0x31, 0xbe, 0x10, 0x17,
|
||||
0x5c, 0x4d, 0xee, 0x37, 0x85, 0xe3, 0xc2, 0x53, 0x5b, 0xc3, 0xfa, 0xbd, 0x95, 0xca, 0x3b, 0xd1,
|
||||
0x3a, 0x86, 0x4e, 0xa1, 0x70, 0x7f, 0xad, 0x3f, 0xbf, 0x7a, 0x73, 0xc9, 0xae, 0x57, 0xd9, 0xf5,
|
||||
0xad, 0x77, 0x0f, 0x5f, 0x87, 0x25, 0xe5, 0xdc, 0xcc, 0xf3, 0x64, 0xed, 0xaf, 0xbf, 0xf0, 0x8a,
|
||||
0xaf, 0xb3, 0x0e, 0x8f, 0xc5, 0xe1, 0x7d, 0xcd, 0x6e, 0xc6, 0xb0, 0x8f, 0xd4, 0xce, 0x7d, 0x40,
|
||||
0x95, 0x01, 0x8f, 0x69, 0x8b, 0xfb, 0xc0, 0xac, 0x5d, 0x98, 0x26, 0x59, 0xdb, 0xb6, 0xba, 0xc0,
|
||||
0x91, 0x35, 0x30, 0x7c, 0xd9, 0xe4, 0xf7, 0x62, 0xfc, 0xee, 0xfc, 0x95, 0x50, 0x49, 0x40, 0x85,
|
||||
0xe0, 0x60, 0x89, 0x77, 0xe7, 0x47, 0x76, 0xed, 0x39, 0xc0, 0x53, 0x5b, 0x77, 0xe2, 0xbf, 0x22,
|
||||
0x99, 0x51, 0x1b, 0x59, 0x17, 0x96, 0x22, 0xe5, 0xec, 0xbc, 0x7d, 0xcd, 0x72, 0x01, 0x95, 0xdb,
|
||||
0x37, 0x42, 0x6b, 0xeb, 0xf3, 0x40, 0x63, 0xba, 0x73, 0x78, 0x4d, 0x1c, 0x37, 0xe6, 0x60, 0xa7,
|
||||
0xe6, 0x52, 0xed, 0x0e, 0xca, 0xb1, 0x6e, 0x6d, 0xe1, 0xe8, 0x56, 0x5d, 0x88, 0xb3, 0x97, 0xd5,
|
||||
0xa6, 0xf6, 0xf3, 0xa5, 0xaf, 0xd6, 0x37, 0x19, 0xf0, 0xb4, 0xef, 0xcf, 0x5e, 0x7a, 0x1a, 0x3c,
|
||||
0x8d, 0xde, 0xb0, 0x6e, 0x1d, 0xef, 0xa4, 0x89, 0x77, 0x22, 0xf0, 0x4e, 0xb6, 0xf1, 0xde, 0x34,
|
||||
0xf1, 0x2e, 0x05, 0xde, 0x25, 0xe1, 0xd5, 0x39, 0x39, 0x87, 0x43, 0x94, 0xd4, 0x4f, 0x30, 0x9e,
|
||||
0x48, 0x12, 0x36, 0x5a, 0xf9, 0xce, 0xd9, 0xb9, 0xb7, 0xda, 0xb7, 0x21, 0xd0, 0xb6, 0x8f, 0x9d,
|
||||
0x7d, 0x78, 0x08, 0xef, 0xe0, 0x8e, 0xcb, 0xfd, 0x82, 0x96, 0x7d, 0xd3, 0xb1, 0x1c, 0x2c, 0xe9,
|
||||
0xd7, 0x07, 0x76, 0xff, 0x56, 0x36, 0x73, 0x1c, 0x82, 0x38, 0x08, 0x5f, 0xdd, 0xdf, 0x05, 0x94,
|
||||
0x55, 0xbc, 0x0d, 0x48, 0x32, 0x2a, 0x0d, 0xac, 0x41, 0x28, 0x47, 0x71, 0x87, 0x61, 0x14, 0x81,
|
||||
0xd7, 0xea, 0x95, 0x82, 0x16, 0x56, 0x8d, 0xe2, 0xcd, 0xd5, 0xde, 0xba, 0x9f, 0x6a, 0x76, 0x50,
|
||||
0x9c, 0x1f, 0x8e, 0xb5, 0xc5, 0x50, 0x78, 0x2f, 0x43, 0x2b, 0xba, 0xf7, 0xb0, 0xc4, 0x79, 0x6d,
|
||||
0x78, 0xef, 0x79, 0x7b, 0xd3, 0xbb, 0x1d, 0x2c, 0xb7, 0xbb, 0x37, 0xee, 0xb9, 0x4d, 0x05, 0x35,
|
||||
0x3c, 0xf8, 0x62, 0x7c, 0xca, 0x7e, 0xde, 0xa0, 0x8b, 0xb5, 0x67, 0x78, 0xb0, 0x78, 0x42, 0x29,
|
||||
0x58, 0x1b, 0xe2, 0x14, 0x86, 0x38, 0x6c, 0x5c, 0x61, 0xad, 0xbb, 0xff, 0xd3, 0x8b, 0x35, 0xe8,
|
||||
0xa2, 0x01, 0x6a, 0x6f, 0xdd, 0xa5, 0x91, 0xc7, 0x9c, 0xbe, 0xe1, 0x1e, 0x83, 0x37, 0x79, 0x0c,
|
||||
0xe3, 0xab, 0x46, 0x43, 0x7d, 0x38, 0xa3, 0x80, 0x45, 0xc6, 0x21, 0x3f, 0x74, 0x1e, 0x32, 0x0e,
|
||||
0xd9, 0xf7, 0xb1, 0xd1, 0x59, 0x9f, 0x6d, 0x1f, 0xa8, 0x59, 0xeb, 0x13, 0xcc, 0xa9, 0xa7, 0x7e,
|
||||
0xff, 0xf1, 0x94, 0xc8, 0x34, 0xbb, 0xfc, 0x2d, 0xb8, 0xd6, 0xda, 0x6a, 0xf6, 0x37, 0x70, 0xed,
|
||||
0xee, 0x7a, 0xe3, 0x0e, 0x5c, 0x7b, 0x58, 0x0c, 0x5e, 0xe5, 0x45, 0x87, 0x83, 0x9e, 0x02, 0x4d,
|
||||
0xc5, 0xa8, 0x5b, 0x78, 0x7e, 0x31, 0x66, 0x77, 0x16, 0x74, 0xfc, 0xef, 0xe1, 0x90, 0x83, 0x03,
|
||||
0xc1, 0x66, 0x4a, 0xe3, 0x53, 0xa3, 0xda, 0x94, 0xce, 0xa7, 0x26, 0xdd, 0x12, 0x87, 0x22, 0x9e,
|
||||
0xdf, 0xfc, 0x55, 0x8f, 0xd2, 0x0d, 0x93, 0x38, 0xf6, 0x16, 0xf2, 0x3a, 0xed, 0xd5, 0xa6, 0x83,
|
||||
0xcd, 0x0f, 0x1c, 0xc1, 0xaa, 0xf7, 0x69, 0x2f, 0xe4, 0xa0, 0xd3, 0xb3, 0x7b, 0x04, 0x3f, 0xd4,
|
||||
0x7a, 0xfa, 0xf0, 0x96, 0x65, 0x1e, 0xda, 0x84, 0x2e, 0xc7, 0x27, 0x5e, 0xb9, 0x4a, 0xfe, 0x4b,
|
||||
0x1c, 0xc8, 0x30, 0xdd, 0x5b, 0x0c, 0x8b, 0x82, 0x7d, 0x05, 0xed, 0x02, 0x67, 0x83, 0xb1, 0xf8,
|
||||
0x1e, 0x77, 0x86, 0xa3, 0x91, 0xf8, 0x1e, 0xb1, 0xa0, 0x2f, 0x3c, 0xcf, 0x5b, 0xd0, 0x16, 0xa3,
|
||||
0x91, 0x3c, 0x1e, 0xf3, 0x4d, 0x24, 0xcc, 0x8f, 0x57, 0xf3, 0x6d, 0xad, 0x67, 0x74, 0x0e, 0x8b,
|
||||
0x42, 0x1e, 0x8d, 0x36, 0xd0, 0xd1, 0x1a, 0xaa, 0x13, 0x74, 0x3c, 0x96, 0x8b, 0x62, 0xc8, 0x0e,
|
||||
0xed, 0x93, 0x23, 0x62, 0xe8, 0x10, 0xb9, 0x71, 0x8d, 0x3c, 0x39, 0xd6, 0x30, 0x25, 0xd3, 0x14,
|
||||
0x43, 0x29, 0x51, 0xc6, 0x1a, 0xa7, 0x48, 0x6f, 0x32, 0x6c, 0x9c, 0x22, 0xbd, 0xb2, 0x11, 0xa6,
|
||||
0xe7, 0xed, 0x84, 0x82, 0x53, 0x9c, 0x09, 0xef, 0xf1, 0x99, 0x4f, 0x0f, 0x39, 0xcb, 0xab, 0x87,
|
||||
0xbc, 0xe4, 0xe3, 0x96, 0x03, 0xd5, 0x1c, 0xe4, 0x6c, 0xab, 0x9f, 0x5e, 0x03, 0x4e, 0x5a, 0x5b,
|
||||
0x87, 0xc2, 0xcd, 0x66, 0x2c, 0x28, 0xee, 0x38, 0xd2, 0xfc, 0xe4, 0xb7, 0xf6, 0x3a, 0xbf, 0x36,
|
||||
0x52, 0xf9, 0x6f, 0xf5, 0x80, 0x3b, 0xf9, 0x8d, 0x07, 0x1c, 0xde, 0xeb, 0x54, 0x8e, 0xbc, 0xaa,
|
||||
0xf1, 0x63, 0xe1, 0x99, 0xb6, 0x15, 0xcc, 0x67, 0xba, 0x00, 0xe8, 0xdb, 0x80, 0x0b, 0x01, 0x58,
|
||||
0xc5, 0xf8, 0x1d, 0x86, 0x3e, 0xd6, 0xcf, 0x9d, 0x67, 0x2c, 0x96, 0xef, 0xe0, 0x88, 0x9f, 0xf9,
|
||||
0xe2, 0x19, 0x50, 0x23, 0xaf, 0x75, 0x94, 0xcf, 0x68, 0xfa, 0xf8, 0x75, 0x51, 0xe4, 0x85, 0x44,
|
||||
0x97, 0x31, 0xc8, 0x4d, 0x68, 0xd0, 0xcb, 0xea, 0xd9, 0x51, 0x4f, 0xc0, 0x5a, 0xc3, 0x28, 0xf5,
|
||||
0xe2, 0xd9, 0x8f, 0xec, 0x10, 0x3b, 0x60, 0xe5, 0x7d, 0x18, 0x47, 0x64, 0x2c, 0x4c, 0xbe, 0xe8,
|
||||
0xfd, 0xab, 0xcc, 0xb3, 0xde, 0xcc, 0x4f, 0x91, 0xd7, 0xa2, 0xf2, 0xc5, 0x40, 0x4c, 0x44, 0x71,
|
||||
0x8c, 0xfa, 0x5f, 0xbe, 0xc0, 0x69, 0x60, 0x12, 0x21, 0x00, 0xa2, 0xd2, 0x3b, 0xa6, 0xf4, 0xf8,
|
||||
0x0c, 0x5f, 0x4a, 0xfe, 0xa5, 0xb3, 0x8c, 0xd2, 0xda, 0x85, 0x12, 0xe5, 0x6d, 0xf1, 0x33, 0x30,
|
||||
0xc1, 0x69, 0x07, 0x62, 0x5b, 0x2c, 0xa6, 0x21, 0x56, 0x53, 0xc0, 0x5e, 0xaf, 0x7e, 0x03, 0x67,
|
||||
0x1c, 0x11, 0x40, 0x59, 0x91, 0x1e, 0xb0, 0x91, 0xa0, 0x8b, 0x2e, 0xae, 0x68, 0x27, 0x52, 0x82,
|
||||
0xc3, 0x46, 0x67, 0x79, 0x7d, 0xb8, 0x16, 0x54, 0xe2, 0x0e, 0xf8, 0xcf, 0x56, 0xeb, 0x30, 0x39,
|
||||
0x6c, 0xfd, 0xb3, 0x75, 0xdc, 0x3a, 0x4c, 0x7f, 0x4f, 0xfe, 0x38, 0x6c, 0x49, 0x6d, 0x36, 0xd3,
|
||||
0xa9, 0x49, 0x7d, 0x7b, 0xd0, 0xe0, 0xf1, 0x1a, 0x6a, 0xb8, 0x73, 0xcf, 0xf7, 0x63, 0x3c, 0x4b,
|
||||
0x06, 0x74, 0x0d, 0x48, 0xa2, 0x41, 0xa9, 0xf4, 0xa3, 0x77, 0xaa, 0xa4, 0x51, 0x36, 0xae, 0x26,
|
||||
0xe2, 0xb6, 0xab, 0xa3, 0x04, 0x3e, 0x53, 0xd6, 0xe6, 0xb7, 0xd6, 0x6d, 0xd9, 0x3b, 0xb7, 0x47,
|
||||
0x3d, 0xf1, 0xd7, 0x02, 0xd2, 0x11, 0x2b, 0x35, 0xc7, 0x83, 0x22, 0xcf, 0xab, 0x25, 0xbf, 0xe3,
|
||||
0x1f, 0x3c, 0x0f, 0xdd, 0x91, 0xa1, 0xa9, 0x43, 0x7e, 0xfb, 0x3e, 0x78, 0xae, 0x8e, 0x8c, 0xc0,
|
||||
0x0a, 0x87, 0xfc, 0x5e, 0x7c, 0xf0, 0x5c, 0x0b, 0xf5, 0xbe, 0xa1, 0x0d, 0xf9, 0x8d, 0xf5, 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, 0xe9, 0x2d, 0xc9, 0x06, 0xfe, 0xbc, 0xca, 0x87, 0x57, 0x49, 0x58, 0x4d, 0x06, 0x8e, 0xba,
|
||||
0xb8, 0x1a, 0x6e, 0xce, 0x53, 0xfc, 0xc7, 0xef, 0x01, 0x0c, 0xd0, 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, 0x18, 0x64,
|
||||
0x3a, 0x60, 0x5f, 0x29, 0x2a, 0x43, 0x5b, 0x06, 0xa0, 0x4b, 0x0f, 0x9c, 0xa5, 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, 0x43, 0xe7,
|
||||
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, 0xc4, 0x5a, 0xe5, 0x12, 0xdb, 0x16, 0x47, 0x68, 0x20, 0x75, 0x6f,
|
||||
0xa2, 0x34, 0xcd, 0xaf, 0x3a, 0xb4, 0xcb, 0xc7, 0xe5, 0xee, 0xcb, 0x70, 0xc0, 0x66, 0x6b, 0xde,
|
||||
0xee, 0xb1, 0x86, 0x9d, 0xcf, 0xd9, 0xaa, 0x57, 0x7b, 0xac, 0x62, 0x27, 0x7d, 0x5a, 0xf4, 0x69,
|
||||
0x8f, 0x45, 0x57, 0x93, 0xa4, 0xe2, 0xab, 0xde, 0xed, 0xb4, 0x8a, 0x2e, 0x16, 0xf2, 0x82, 0x7e,
|
||||
0xd9, 0x17, 0x0a, 0x11, 0xd7, 0x0c, 0xc1, 0x8d, 0xcf, 0xef, 0x1a, 0xba, 0x8b, 0x24, 0x47, 0x04,
|
||||
0xaf, 0xe5, 0x3e, 0xdf, 0x69, 0x5b, 0x6c, 0x72, 0x53, 0x13, 0xfb, 0x74, 0x0f, 0x09, 0x90, 0x66,
|
||||
0xbe, 0xce, 0xf3, 0xa4, 0xe4, 0x52, 0x5c, 0xec, 0xb1, 0x72, 0x65, 0x51, 0xa5, 0xca, 0xf3, 0xb4,
|
||||
0xfc, 0x8f, 0x7d, 0xeb, 0xf2, 0x9b, 0xd4, 0xfe, 0x7e, 0x5f, 0x5f, 0xa2, 0x9b, 0x91, 0x65, 0x9c,
|
||||
0x67, 0x95, 0x1c, 0xfb, 0xd3, 0x24, 0xbd, 0x59, 0x85, 0xef, 0x9b, 0xac, 0xd3, 0x7d, 0x17, 0xa5,
|
||||
0x8b, 0xa8, 0x4a, 0x02, 0xbf, 0x5b, 0x22, 0x32, 0xe5, 0x32, 0x2a, 0x92, 0x78, 0x58, 0x45, 0xd7,
|
||||
0x95, 0xec, 0xa7, 0xc9, 0x38, 0x1b, 0x04, 0x11, 0xfd, 0xb1, 0xc9, 0x63, 0x4e, 0xcf, 0x37, 0xa3,
|
||||
0xbc, 0xd4, 0xe1, 0x44, 0x3b, 0xeb, 0x90, 0xa4, 0xf0, 0x14, 0x29, 0x45, 0xad, 0x27, 0x91, 0x22,
|
||||
0x9a, 0x45, 0x7e, 0x35, 0xc8, 0x72, 0xf1, 0x55, 0x87, 0xf9, 0x55, 0xe5, 0x07, 0x13, 0x6a, 0xb1,
|
||||
0x06, 0x71, 0x72, 0x1d, 0x85, 0xc3, 0x7a, 0xc6, 0xa1, 0x24, 0xd6, 0xb9, 0xa5, 0xbf, 0x8b, 0x59,
|
||||
0xd6, 0x68, 0xdc, 0x26, 0x71, 0xe1, 0x4f, 0xa3, 0xa5, 0xe8, 0xce, 0x07, 0xd4, 0x9c, 0x0f, 0x47,
|
||||
0x79, 0x11, 0x22, 0xa9, 0xa8, 0xfb, 0x65, 0x97, 0xe1, 0x03, 0x19, 0x50, 0x50, 0xb3, 0x29, 0x01,
|
||||
0xfc, 0xc7, 0x09, 0xef, 0xb6, 0x5c, 0x8c, 0xd9, 0x9f, 0xdb, 0x08, 0xa9, 0x42, 0x96, 0x47, 0x45,
|
||||
0x4a, 0xd3, 0x37, 0xd4, 0x34, 0x75, 0x81, 0xde, 0x71, 0xcf, 0xf4, 0x98, 0x64, 0xb3, 0x79, 0xb5,
|
||||
0xdc, 0x4f, 0xe8, 0x07, 0x7c, 0x63, 0xe3, 0x11, 0xb7, 0xa3, 0x79, 0x55, 0xe5, 0x59, 0xdd, 0xf1,
|
||||
0x6a, 0x66, 0x6f, 0x98, 0x88, 0x0b, 0x23, 0xb4, 0xaf, 0x58, 0xc1, 0x44, 0x82, 0x92, 0x92, 0x50,
|
||||
0xaa, 0xe3, 0x8b, 0xa0, 0x18, 0xe5, 0xd8, 0x74, 0x3a, 0xd0, 0xa0, 0xd3, 0xbf, 0x9b, 0x5f, 0x5e,
|
||||
0xa6, 0x77, 0xe1, 0xb7, 0xda, 0x81, 0xdf, 0xbf, 0x9b, 0x3b, 0x66, 0xa3, 0xdf, 0xd9, 0x1f, 0x18,
|
||||
0x66, 0xf3, 0xe9, 0x28, 0x2a, 0xfe, 0xf8, 0xbb, 0x38, 0xe5, 0x4e, 0x64, 0x44, 0xd3, 0x3a, 0x0d,
|
||||
0x96, 0x7c, 0xff, 0x58, 0xca, 0x57, 0xd1, 0xe8, 0x4b, 0x82, 0xc0, 0x9e, 0x21, 0xe6, 0x30, 0x17,
|
||||
0x44, 0x3c, 0x52, 0x84, 0xcb, 0xcb, 0x26, 0x04, 0x51, 0xef, 0xae, 0x1b, 0xc4, 0x79, 0x30, 0x2f,
|
||||
0x97, 0xf9, 0xbc, 0xa2, 0xc8, 0x1f, 0xdc, 0x87, 0x31, 0x58, 0x6d, 0x5d, 0x82, 0x9f, 0xa8, 0x90,
|
||||
0x8b, 0x79, 0x96, 0xf9, 0xa3, 0x34, 0x92, 0xe1, 0xfd, 0xc1, 0x97, 0x87, 0x8a, 0x75, 0x30, 0x2f,
|
||||
0x4a, 0x08, 0x37, 0xcb, 0x93, 0xed, 0x14, 0x53, 0x93, 0x68, 0x07, 0x6a, 0xd5, 0x04, 0x3a, 0xdc,
|
||||
0xd3, 0xe3, 0x37, 0x11, 0xb6, 0xca, 0xc9, 0xda, 0x56, 0x6d, 0xe7, 0xe8, 0x3e, 0xb7, 0x42, 0x93,
|
||||
0xd3, 0xc7, 0x15, 0xc9, 0x72, 0x3d, 0x7c, 0xfa, 0x5e, 0xce, 0xa7, 0xf9, 0x9f, 0x32, 0x1b, 0xfc,
|
||||
0xb7, 0x54, 0x53, 0x23, 0xf0, 0xbf, 0x56, 0xcb, 0x2e, 0xe2, 0x97, 0xdf, 0x2a, 0x37, 0xcb, 0xa3,
|
||||
0x33, 0xbf, 0xa0, 0xbf, 0xa0, 0xe5, 0x21, 0x20, 0x5a, 0xd1, 0x3a, 0xe0, 0xce, 0xcc, 0x43, 0x4c,
|
||||
0x50, 0xf2, 0x95, 0x51, 0xc9, 0xa3, 0xa2, 0x1e, 0x78, 0xcf, 0x9f, 0x54, 0xae, 0x58, 0x39, 0x87,
|
||||
0xe1, 0xf7, 0x5e, 0xc9, 0xed, 0xb1, 0xb7, 0x56, 0x6b, 0x26, 0xa1, 0x43, 0x02, 0x3b, 0x1b, 0x88,
|
||||
0x33, 0x82, 0x94, 0x84, 0xde, 0x24, 0x4f, 0xa1, 0x8b, 0x7f, 0x21, 0xb3, 0xb0, 0x19, 0x46, 0x95,
|
||||
0xca, 0x77, 0x2f, 0x28, 0xcb, 0xe3, 0x15, 0xfe, 0x51, 0x8f, 0xff, 0x8d, 0x34, 0x35, 0x02, 0x52,
|
||||
0x9e, 0xb1, 0x3f, 0x49, 0x58, 0xff, 0x59, 0xaa, 0x14, 0xd0, 0x6f, 0xfd, 0xde, 0xe7, 0xcf, 0xa8,
|
||||
0x9d, 0x49, 0xf6, 0x99, 0x16, 0x7f, 0xfe, 0xf8, 0xfa, 0xe5, 0x4f, 0xbf, 0x7d, 0xfe, 0x4c, 0x84,
|
||||
0x66, 0x7e, 0x26, 0x30, 0xe8, 0x0f, 0x01, 0x8e, 0x3f, 0xf0, 0x13, 0xa2, 0xa2, 0x28, 0xd8, 0x1c,
|
||||
0x30, 0x42, 0x59, 0x8c, 0x25, 0x46, 0xc7, 0xbb, 0x5b, 0x19, 0xb9, 0xb8, 0xea, 0x4a, 0x0a, 0x75,
|
||||
0x98, 0x2f, 0xa2, 0x22, 0x86, 0xe6, 0x07, 0x93, 0x24, 0x0c, 0x23, 0x1c, 0xc7, 0xa2, 0xa2, 0xc4,
|
||||
0x0a, 0x4f, 0x53, 0x34, 0xe9, 0x7a, 0x9a, 0x66, 0xa5, 0x37, 0xa9, 0xaa, 0xd9, 0xa0, 0xd7, 0xbb,
|
||||
0xba, 0xba, 0x52, 0xae, 0x0c, 0x25, 0x2f, 0xc6, 0x3d, 0x1d, 0x27, 0x98, 0x1e, 0xa8, 0x80, 0x56,
|
||||
0x18, 0xc5, 0xe5, 0xb1, 0xd4, 0xeb, 0x7d, 0x60, 0x4d, 0x08, 0xfd, 0x19, 0x76, 0xa9, 0x04, 0xf9,
|
||||
0xb4, 0x17, 0xa3, 0x11, 0x04, 0x27, 0x37, 0xd3, 0x51, 0x9e, 0x92, 0x5a, 0xd2, 0xac, 0x90, 0x67,
|
||||
0x64, 0x5f, 0x99, 0x5f, 0x2b, 0x48, 0x8b, 0x24, 0xba, 0x7a, 0x95, 0xe3, 0xf4, 0xa8, 0x4a, 0xaa,
|
||||
0xa4, 0xa9, 0xba, 0xc9, 0x1e, 0xad, 0xe3, 0x23, 0xfa, 0x8d, 0x41, 0x0a, 0xbd, 0xd6, 0xcf, 0xa6,
|
||||
0x63, 0x2b, 0xa6, 0x64, 0x6b, 0xa6, 0x62, 0x06, 0x32, 0x9e, 0x9a, 0xe1, 0x48, 0xaa, 0xac, 0x5b,
|
||||
0x8a, 0x2d, 0x6b, 0x9a, 0x62, 0xda, 0x1a, 0xff, 0xa6, 0xc7, 0x42, 0x36, 0x6d, 0x55, 0x71, 0x02,
|
||||
0x75, 0x85, 0xc7, 0x10, 0x74, 0x06, 0x93, 0xd6, 0x58, 0x25, 0x1b, 0x72, 0x90, 0xb4, 0x06, 0x2d,
|
||||
0xc4, 0x52, 0x89, 0x2d, 0x75, 0xe5, 0x1a, 0x7c, 0xb3, 0xfe, 0x4f, 0x30, 0xd6, 0x23, 0xce, 0xee,
|
||||
0xf0, 0xe7, 0xf6, 0x75, 0xac, 0x96, 0xc1, 0xbc, 0x62, 0xf5, 0xc1, 0x9f, 0xe6, 0xba, 0xb2, 0xe1,
|
||||
0x2a, 0xae, 0x69, 0xca, 0x7a, 0x5f, 0x53, 0x2c, 0x03, 0x1b, 0xea, 0x8a, 0xd9, 0x97, 0x81, 0x67,
|
||||
0xe9, 0xce, 0xea, 0x25, 0x26, 0x35, 0xdb, 0x51, 0x5c, 0x7b, 0x35, 0xe2, 0x0b, 0xb0, 0x89, 0x63,
|
||||
0x2a, 0x86, 0x6b, 0x49, 0xba, 0xad, 0x38, 0x16, 0x38, 0xb2, 0xa1, 0x82, 0xbe, 0x23, 0xf5, 0xfb,
|
||||
0x8a, 0xdd, 0xc7, 0xb6, 0x06, 0xb0, 0x5c, 0x53, 0x32, 0x5d, 0x45, 0xb3, 0x64, 0xc0, 0x5c, 0xcd,
|
||||
0x82, 0x54, 0xd8, 0xa8, 0x4f, 0xdc, 0x1b, 0x58, 0x0a, 0x65, 0xba, 0xb6, 0x62, 0xeb, 0xa6, 0xac,
|
||||
0x19, 0xb6, 0x62, 0xa9, 0x9a, 0x84, 0x69, 0xcb, 0x92, 0x4d, 0x45, 0x35, 0x4c, 0x49, 0xef, 0x2b,
|
||||
0x8e, 0x6a, 0x49, 0x86, 0x62, 0x3b, 0x86, 0x84, 0xcd, 0x1c, 0x52, 0x58, 0x5f, 0xd1, 0x0d, 0xb3,
|
||||
0x94, 0xf9, 0x24, 0xc7, 0x90, 0xf9, 0xa4, 0x40, 0x81, 0x8c, 0x24, 0x97, 0x65, 0x49, 0xa6, 0xa6,
|
||||
0xd8, 0x16, 0xf1, 0xd1, 0x57, 0xfa, 0xaa, 0x8e, 0xa5, 0xd0, 0xc0, 0x66, 0x68, 0x68, 0xae, 0xa2,
|
||||
0xea, 0x3a, 0x59, 0xd5, 0x01, 0x51, 0x15, 0x1a, 0x07, 0xa7, 0x3a, 0x78, 0x32, 0x0c, 0x20, 0xd6,
|
||||
0x9f, 0x25, 0x7b, 0xca, 0x0d, 0xb8, 0xcc, 0x9e, 0xcc, 0x92, 0xb6, 0xa2, 0x39, 0x7d, 0xd9, 0xc5,
|
||||
0xb6, 0x16, 0x54, 0xd3, 0x57, 0x8c, 0xbe, 0xa0, 0xa2, 0xc9, 0x9c, 0x08, 0x89, 0x07, 0xb1, 0x74,
|
||||
0x2e, 0x97, 0xac, 0x6b, 0x8a, 0x6e, 0x43, 0xa7, 0x8e, 0xa2, 0x3b, 0x8e, 0x60, 0x5e, 0x16, 0xf2,
|
||||
0x11, 0x86, 0x2e, 0xd0, 0x25, 0xc2, 0x70, 0x05, 0x3a, 0x97, 0xae, 0xcf, 0xd1, 0x2d, 0xa6, 0x63,
|
||||
0x13, 0x36, 0x37, 0x14, 0x8d, 0x71, 0xde, 0x57, 0x4c, 0x28, 0x1e, 0x0a, 0x77, 0x74, 0xae, 0x53,
|
||||
0x03, 0x6f, 0xe8, 0xd4, 0x74, 0x5d, 0xc9, 0x82, 0xdf, 0x68, 0xb6, 0x64, 0xf7, 0x15, 0x4d, 0xe3,
|
||||
0x2b, 0xfb, 0x16, 0x5b, 0xa2, 0x43, 0x0d, 0x62, 0xc8, 0x8d, 0xe5, 0x70, 0x1f, 0x87, 0x87, 0x70,
|
||||
0xdf, 0xa0, 0xbd, 0x20, 0x80, 0xaa, 0x0b, 0xcb, 0x4b, 0xc2, 0x55, 0xb8, 0x73, 0x48, 0xec, 0x65,
|
||||
0x0b, 0xe7, 0x90, 0x9a, 0xce, 0xc1, 0x47, 0x35, 0x7f, 0xec, 0xf1, 0x20, 0x3b, 0xde, 0x8e, 0x36,
|
||||
0xba, 0x32, 0xda, 0x21, 0xca, 0x5c, 0xd7, 0x81, 0x17, 0x3b, 0xd0, 0xa7, 0x3e, 0x91, 0xfb, 0xb6,
|
||||
0xf3, 0x54, 0xa8, 0x95, 0xf7, 0x86, 0xd6, 0x84, 0x56, 0xf2, 0x00, 0x02, 0xa1, 0x4d, 0x9c, 0x69,
|
||||
0x9b, 0x38, 0x2b, 0xe5, 0xda, 0xcc, 0xe3, 0x91, 0xc5, 0x79, 0xb2, 0x6c, 0xe3, 0xff, 0x1d, 0x4f,
|
||||
0x86, 0xda, 0x7f, 0x8c, 0x27, 0xfd, 0x5b, 0x79, 0xd2, 0xbf, 0x89, 0xa7, 0xbe, 0x4d, 0x91, 0x64,
|
||||
0x39, 0x94, 0x20, 0x4d, 0x5d, 0x31, 0x4c, 0x4a, 0x40, 0x34, 0x29, 0x1b, 0xc8, 0x18, 0xe4, 0x4f,
|
||||
0xf4, 0x4d, 0x8f, 0xb2, 0x36, 0x21, 0xad, 0x67, 0x25, 0xbe, 0x01, 0x03, 0x49, 0x1b, 0x50, 0x6d,
|
||||
0x62, 0x83, 0xf6, 0x27, 0xa7, 0xa6, 0x5b, 0x36, 0x97, 0x1c, 0x1e, 0xcf, 0x25, 0x67, 0x02, 0x38,
|
||||
0xd6, 0x86, 0xd3, 0x92, 0x4f, 0x6c, 0x24, 0xda, 0x3c, 0xe4, 0x1a, 0x48, 0xae, 0x4d, 0x6c, 0xd4,
|
||||
0x26, 0x3f, 0x2a, 0xab, 0x28, 0x06, 0xf7, 0xc8, 0xaa, 0x6d, 0x64, 0xc5, 0xbc, 0x40, 0xb8, 0x57,
|
||||
0xe8, 0xf2, 0x5e, 0xa1, 0x91, 0xff, 0xd9, 0x22, 0xf7, 0x51, 0xe9, 0x2d, 0x4d, 0xff, 0x3f, 0x94,
|
||||
0xde, 0xe9, 0xab, 0x4f, 0x4b, 0xff, 0xa4, 0xa5, 0xb5, 0x1d, 0x2d, 0xbd, 0xf6, 0xf1, 0xff, 0x91,
|
||||
0xac, 0x0f, 0xe5, 0xb1, 0x69, 0x4e, 0x97, 0xc4, 0x4f, 0xe6, 0x31, 0x4b, 0x37, 0xc1, 0x34, 0xcd,
|
||||
0x12, 0xd7, 0xaa, 0xa2, 0xf5, 0x5d, 0x62, 0x1b, 0x49, 0xd3, 0xb5, 0x1d, 0xd9, 0x32, 0x91, 0xc1,
|
||||
0x61, 0x5b, 0x0c, 0x55, 0x17, 0xb5, 0xc5, 0x32, 0x50, 0x45, 0x4a, 0xf1, 0x46, 0x51, 0x51, 0x51,
|
||||
0x44, 0x57, 0x23, 0x81, 0x44, 0x25, 0x48, 0xb3, 0x14, 0x1d, 0xc9, 0x1a, 0xe5, 0x41, 0xc7, 0xf6,
|
||||
0xaa, 0x46, 0xb4, 0x6d, 0xc5, 0x75, 0x91, 0xc6, 0xa1, 0x19, 0x0b, 0x85, 0xc2, 0x30, 0x58, 0x39,
|
||||
0x37, 0x51, 0x75, 0x6d, 0xd4, 0x00, 0x83, 0x55, 0x68, 0x07, 0xcd, 0x93, 0x45, 0x35, 0xd9, 0x55,
|
||||
0x0c, 0xdd, 0x62, 0x39, 0xde, 0xd0, 0x0d, 0x09, 0x05, 0x4d, 0xb5, 0x54, 0xaa, 0x48, 0x26, 0xfa,
|
||||
0x06, 0xd4, 0x12, 0xdb, 0x94, 0x2d, 0x4b, 0x31, 0x49, 0x1a, 0xd4, 0x12, 0x13, 0x64, 0x40, 0x5a,
|
||||
0x87, 0xd6, 0x5c, 0x14, 0x16, 0x14, 0x28, 0xc5, 0x45, 0xe5, 0xd6, 0x55, 0x86, 0xa1, 0x2a, 0x86,
|
||||
0x61, 0x53, 0x47, 0xe0, 0xa2, 0xcd, 0x40, 0xfd, 0xd2, 0xf5, 0x12, 0x95, 0x90, 0x2a, 0x37, 0x8a,
|
||||
0x04, 0x4a, 0x95, 0xa1, 0xa8, 0x36, 0x4a, 0xbb, 0x03, 0x2e, 0x11, 0xa1, 0x60, 0x4b, 0xc5, 0x24,
|
||||
0x9a, 0x03, 0x03, 0x2d, 0x8d, 0xe9, 0xa0, 0x76, 0xba, 0x92, 0x06, 0x8d, 0xa3, 0x42, 0xaf, 0x87,
|
||||
0xae, 0xc1, 0x8d, 0x8b, 0x22, 0x85, 0xa2, 0xd4, 0xc7, 0x04, 0xc4, 0x05, 0x9b, 0x06, 0x5e, 0x8d,
|
||||
0x27, 0x2a, 0x9c, 0xa9, 0x99, 0xa4, 0x79, 0xec, 0xdf, 0xef, 0xc3, 0x96, 0x16, 0x76, 0xd0, 0x56,
|
||||
0x3b, 0xf0, 0x0d, 0x1d, 0x70, 0xad, 0xa9, 0x7d, 0xd4, 0x62, 0xa8, 0x80, 0xb8, 0xd6, 0x0c, 0x74,
|
||||
0x13, 0xa6, 0xed, 0x0a, 0xa6, 0x38, 0x87, 0xe4, 0x32, 0x1a, 0xf5, 0x0c, 0x00, 0x9b, 0x4c, 0x0e,
|
||||
0x53, 0x08, 0x15, 0xd0, 0xae, 0x0e, 0xf2, 0x1e, 0x59, 0xa1, 0x6f, 0x50, 0xa1, 0x74, 0x4c, 0x28,
|
||||
0x51, 0x85, 0x0c, 0x8e, 0xd0, 0x8c, 0x2d, 0x14, 0x65, 0x91, 0x12, 0x35, 0xdb, 0x96, 0x4c, 0xf8,
|
||||
0x10, 0x7a, 0x20, 0xa8, 0xc0, 0x42, 0x7c, 0x40, 0x3c, 0x98, 0x66, 0xa5, 0xee, 0x95, 0xfa, 0x5d,
|
||||
0x15, 0x75, 0x13, 0xba, 0x80, 0x8c, 0xae, 0x43, 0xfd, 0x99, 0x62, 0x50, 0x69, 0xdf, 0x32, 0xa4,
|
||||
0x18, 0xff, 0xf9, 0x33, 0xd4, 0x8c, 0x0e, 0xaa, 0x4f, 0xf8, 0x8e, 0x4b, 0xc9, 0x0e, 0xd5, 0xb8,
|
||||
0x6f, 0x6a, 0x64, 0x5b, 0xd7, 0x41, 0x3e, 0x07, 0x15, 0x0d, 0x60, 0x1d, 0x3e, 0xa6, 0xa2, 0x39,
|
||||
0x5b, 0x8d, 0x4d, 0x9d, 0xf6, 0x25, 0x25, 0xe9, 0x36, 0x78, 0x83, 0x85, 0x75, 0xaa, 0xd4, 0x16,
|
||||
0x78, 0x24, 0xaf, 0x68, 0x3c, 0x35, 0xc7, 0x65, 0x8d, 0x95, 0x8a, 0xe4, 0x0d, 0x4d, 0x6a, 0xa6,
|
||||
0x68, 0x03, 0xac, 0xd5, 0x2e, 0xab, 0x5d, 0x65, 0x0b, 0xd3, 0xc4, 0xac, 0x4b, 0x4d, 0x04, 0x9a,
|
||||
0x4c, 0xd2, 0x3b, 0xda, 0x33, 0x97, 0x01, 0x35, 0x34, 0xae, 0x16, 0x48, 0xae, 0x86, 0x78, 0xbb,
|
||||
0xd4, 0x78, 0x21, 0xb2, 0x74, 0xe8, 0x1a, 0xab, 0x55, 0x6a, 0x14, 0x11, 0xe5, 0x60, 0xdd, 0x80,
|
||||
0xd5, 0x90, 0x39, 0xa8, 0x24, 0xb9, 0xe8, 0x78, 0x6c, 0x97, 0xbd, 0xfa, 0x62, 0x92, 0x9a, 0x27,
|
||||
0x72, 0x70, 0x7b, 0x3d, 0xe6, 0x8b, 0x28, 0x99, 0x82, 0x45, 0xcd, 0xd0, 0x60, 0x5d, 0x00, 0x55,
|
||||
0x98, 0x12, 0xdd, 0x4c, 0x93, 0x81, 0x1d, 0x82, 0x38, 0xc8, 0xc7, 0x3b, 0xc4, 0xb0, 0x01, 0x53,
|
||||
0x91, 0x5b, 0xa9, 0x20, 0xd3, 0xb7, 0xac, 0x00, 0x11, 0xa0, 0xa9, 0x14, 0xc6, 0x26, 0xc2, 0xd0,
|
||||
0x91, 0x55, 0xf4, 0x6b, 0xba, 0x6c, 0x93, 0xaf, 0xc9, 0xd4, 0x7a, 0xc9, 0xb0, 0xbe, 0xdb, 0x67,
|
||||
0x99, 0xc5, 0x51, 0x0d, 0xb2, 0xb3, 0x46, 0xf9, 0x1b, 0x76, 0x31, 0xa9, 0xd5, 0x83, 0xc3, 0x20,
|
||||
0xa8, 0x11, 0xf9, 0xba, 0x46, 0x28, 0xae, 0x8e, 0xa4, 0x88, 0xa8, 0x40, 0x43, 0x6e, 0x93, 0x6f,
|
||||
0xea, 0x3a, 0x01, 0x5c, 0xea, 0x8e, 0x29, 0x0f, 0x1a, 0x26, 0xb9, 0x23, 0x9c, 0x19, 0x7a, 0x70,
|
||||
0x75, 0xf8, 0x1d, 0x19, 0xcf, 0x65, 0xed, 0x23, 0xfc, 0x4c, 0x8c, 0xe0, 0xe8, 0xae, 0x4b, 0x1a,
|
||||
0xb6, 0x6c, 0xa6, 0x24, 0x62, 0x80, 0x14, 0x8b, 0xd6, 0xce, 0x6c, 0x3e, 0xe1, 0xdf, 0x3a, 0xe5,
|
||||
0x4d, 0xec, 0xac, 0x92, 0x9f, 0xc2, 0xaa, 0xeb, 0xe5, 0x62, 0x33, 0xbc, 0x34, 0xc3, 0x90, 0xa8,
|
||||
0x4f, 0xa7, 0xee, 0x8e, 0x22, 0x55, 0x02, 0x44, 0x17, 0xec, 0xe8, 0x82, 0x37, 0x24, 0x1e, 0x0d,
|
||||
0x51, 0x45, 0x3e, 0xa5, 0x53, 0xee, 0x37, 0x55, 0x47, 0x76, 0xc8, 0x6b, 0x2c, 0x2e, 0x9b, 0x26,
|
||||
0x44, 0xa5, 0x68, 0x33, 0x0c, 0x83, 0xb6, 0x75, 0x1d, 0x17, 0xd1, 0xe6, 0xc2, 0x59, 0x6d, 0x2a,
|
||||
0x69, 0x92, 0x46, 0x34, 0x98, 0x66, 0xf0, 0x62, 0xed, 0x3b, 0x0e, 0x29, 0x64, 0x6f, 0x83, 0xb9,
|
||||
0x79, 0x1f, 0xfb, 0x23, 0xe8, 0xe8, 0x68, 0x20, 0x46, 0xe8, 0xb9, 0x01, 0x2b, 0x65, 0x16, 0xb9,
|
||||
0x20, 0x67, 0xc8, 0x0c, 0xe0, 0x30, 0x80, 0xa9, 0x06, 0x44, 0xa4, 0xcf, 0x62, 0x5d, 0xef, 0x53,
|
||||
0x48, 0x21, 0xc7, 0xea, 0x24, 0xb3, 0x6d, 0x38, 0xb2, 0xc6, 0x05, 0x62, 0xc4, 0xfa, 0x92, 0xb0,
|
||||
0x0d, 0xb7, 0x94, 0x24, 0x6c, 0xc3, 0x2d, 0x25, 0x35, 0xd8, 0x47, 0x80, 0x71, 0xe3, 0x30, 0x4b,
|
||||
0x49, 0xdc, 0x3a, 0xcc, 0x52, 0x12, 0xb7, 0x0e, 0x57, 0x87, 0xc4, 0xcc, 0x63, 0x30, 0x53, 0xb1,
|
||||
0xd6, 0x1d, 0x49, 0x8f, 0xeb, 0x53, 0x62, 0xda, 0x5d, 0x0d, 0xb8, 0x81, 0x44, 0xdb, 0xbd, 0x32,
|
||||
0x94, 0x54, 0x33, 0x11, 0x1d, 0xd5, 0xc8, 0x48, 0xb6, 0xcc, 0x6d, 0xc3, 0x0c, 0x45, 0x41, 0xb4,
|
||||
0x31, 0xb4, 0xcc, 0xd5, 0xc6, 0xec, 0x84, 0x00, 0x81, 0x69, 0x74, 0x66, 0x27, 0x93, 0x82, 0xa1,
|
||||
0xe6, 0x36, 0xcc, 0x36, 0xdc, 0x50, 0x36, 0xcb, 0x42, 0x14, 0xd1, 0xdc, 0x52, 0x52, 0xc3, 0x0d,
|
||||
0x35, 0xe2, 0xce, 0xa5, 0x88, 0x84, 0xa5, 0x58, 0xde, 0x23, 0xeb, 0x90, 0xa5, 0xa4, 0x95, 0xba,
|
||||
0x6c, 0xfe, 0x32, 0x49, 0xcd, 0xb4, 0x71, 0x5f, 0x65, 0x09, 0x71, 0x6d, 0x29, 0x64, 0x59, 0x66,
|
||||
0x02, 0x31, 0x2a, 0x61, 0x1a, 0x6e, 0x24, 0x36, 0x0f, 0xf5, 0x73, 0x0b, 0x06, 0x20, 0xe7, 0x30,
|
||||
0x2b, 0x69, 0x94, 0x6b, 0x6d, 0xd3, 0xe2, 0x56, 0xb2, 0x38, 0x21, 0x97, 0x5b, 0xc9, 0x95, 0x84,
|
||||
0x5d, 0x98, 0x95, 0x74, 0x89, 0xec, 0x62, 0x09, 0x23, 0x09, 0xce, 0x0d, 0x69, 0xc5, 0xb9, 0xc6,
|
||||
0x92, 0x0b, 0x33, 0x12, 0xb1, 0x89, 0x52, 0xc0, 0x8c, 0xa4, 0x3a, 0x5c, 0x19, 0x92, 0x70, 0x5a,
|
||||
0x32, 0x8c, 0xce, 0xad, 0x64, 0x33, 0x6d, 0x22, 0xa3, 0x33, 0x3b, 0xf5, 0x57, 0xa3, 0x55, 0x10,
|
||||
0xad, 0x6c, 0x54, 0xb7, 0x4d, 0xf3, 0xc9, 0xec, 0x43, 0x59, 0x92, 0xdb, 0x86, 0x19, 0x4a, 0x2c,
|
||||
0x17, 0x86, 0x92, 0x98, 0x71, 0x1c, 0x6e, 0x29, 0x89, 0x1b, 0x87, 0x59, 0x4a, 0xf0, 0x63, 0x0a,
|
||||
0xe6, 0x98, 0x6d, 0x6c, 0x61, 0x29, 0xc9, 0xe4, 0x59, 0x95, 0x5b, 0x8a, 0x0b, 0xb8, 0x32, 0x94,
|
||||
0xc4, 0x4d, 0xc3, 0x83, 0x08, 0x76, 0x72, 0xa1, 0x59, 0x6e, 0x27, 0xe1, 0xd8, 0xc2, 0x52, 0xb2,
|
||||
0xb0, 0x0d, 0xb7, 0x94, 0x08, 0x0f, 0x61, 0x29, 0xb9, 0x61, 0xa9, 0x52, 0xd8, 0x07, 0xc7, 0xea,
|
||||
0xda, 0x3c, 0xce, 0xd3, 0x3c, 0x86, 0x24, 0xb2, 0x94, 0xc4, 0x43, 0x48, 0xe2, 0x21, 0x24, 0xd5,
|
||||
0x29, 0xb9, 0x22, 0xbd, 0x09, 0x53, 0x89, 0xf4, 0xc6, 0x4d, 0x25, 0x37, 0x58, 0x67, 0xd9, 0xcd,
|
||||
0xe2, 0x86, 0xb2, 0x64, 0x61, 0x1b, 0x6e, 0x29, 0xb9, 0xa6, 0x0c, 0x5d, 0x16, 0xc6, 0x61, 0x96,
|
||||
0x92, 0x1b, 0xb6, 0x91, 0xff, 0x5d, 0xda, 0x15, 0xf5, 0xc6, 0x6d, 0x23, 0xe1, 0xbf, 0x42, 0xdc,
|
||||
0xbd, 0xf4, 0x80, 0xca, 0x15, 0x29, 0x91, 0xa2, 0x8a, 0x34, 0x40, 0x93, 0xbb, 0xb4, 0x05, 0x2e,
|
||||
0x81, 0x11, 0x07, 0xd7, 0xdc, 0xd3, 0x61, 0x23, 0x3b, 0x89, 0x91, 0x8d, 0x6d, 0x58, 0x4e, 0xda,
|
||||
0xe4, 0xd7, 0xdf, 0x7c, 0xdf, 0x8c, 0x76, 0x25, 0xed, 0xca, 0x51, 0x93, 0x07, 0xef, 0x2e, 0x2d,
|
||||
0x69, 0x48, 0x0e, 0x67, 0x86, 0x33, 0xdf, 0x8c, 0xa4, 0x11, 0x73, 0xa5, 0x35, 0x28, 0x91, 0x69,
|
||||
0xcc, 0xd8, 0xda, 0xd9, 0x12, 0x95, 0xce, 0x2c, 0x9d, 0xae, 0x8d, 0x59, 0xbb, 0xe9, 0x42, 0x9b,
|
||||
0x48, 0x63, 0xa1, 0x92, 0x1a, 0xb8, 0x61, 0xa1, 0x38, 0x9c, 0x41, 0xbd, 0x6d, 0x6d, 0x74, 0xa5,
|
||||
0x0a, 0x5b, 0x1b, 0x5d, 0xa9, 0x9d, 0x89, 0x30, 0x63, 0x1e, 0x48, 0x17, 0x2b, 0x95, 0xcc, 0xc4,
|
||||
0xe9, 0x4a, 0x15, 0x63, 0xe1, 0x6e, 0xd4, 0xc2, 0x65, 0x5b, 0x29, 0xb5, 0x70, 0x71, 0x6c, 0xc8,
|
||||
0x06, 0x6d, 0xc9, 0x7d, 0x01, 0xcc, 0x43, 0x6d, 0xdd, 0x44, 0xbd, 0xc4, 0x91, 0x92, 0x98, 0x1d,
|
||||
0x6e, 0xa5, 0x81, 0x29, 0x1c, 0xb0, 0x4c, 0x19, 0xbe, 0x9a, 0x8c, 0x14, 0xfb, 0x04, 0x1b, 0x9f,
|
||||
0x9f, 0x4a, 0x68, 0x60, 0x0e, 0x7a, 0x04, 0x42, 0x11, 0x69, 0x7a, 0x64, 0xcf, 0x14, 0x0d, 0xaa,
|
||||
0x82, 0x62, 0x52, 0xe2, 0x4b, 0xb5, 0x5e, 0x9c, 0x37, 0xd9, 0x9c, 0x21, 0xac, 0x00, 0x13, 0x1a,
|
||||
0x59, 0x85, 0x00, 0xc1, 0x91, 0x88, 0xbf, 0x24, 0x74, 0x91, 0x1b, 0x42, 0x09, 0xa1, 0xd5, 0xbd,
|
||||
0xa7, 0x4e, 0x45, 0x14, 0xff, 0x84, 0xa6, 0xb0, 0x6c, 0x70, 0x7a, 0x2d, 0x9b, 0x34, 0xdc, 0xbb,
|
||||
0x26, 0x5a, 0x43, 0x76, 0x79, 0x9f, 0x83, 0xa2, 0x46, 0xa9, 0x15, 0x47, 0x07, 0x0e, 0x61, 0x4d,
|
||||
0x6f, 0x16, 0xfe, 0x52, 0x85, 0x7d, 0x5b, 0x7f, 0x37, 0x70, 0xd0, 0x54, 0x9f, 0x80, 0x6e, 0x04,
|
||||
0x76, 0xc6, 0xcb, 0xbd, 0x03, 0xad, 0x4c, 0xb9, 0x6f, 0x68, 0xca, 0x1a, 0xe1, 0x70, 0x90, 0xab,
|
||||
0x2a, 0xd0, 0x4f, 0x29, 0x38, 0x1b, 0x8d, 0x8d, 0xad, 0x86, 0x77, 0x04, 0xe6, 0x07, 0x48, 0x12,
|
||||
0x66, 0x24, 0x2e, 0x9a, 0xcc, 0x45, 0x2c, 0xb8, 0xb5, 0x74, 0xba, 0x12, 0x8f, 0xa8, 0x86, 0x2a,
|
||||
0x33, 0xbc, 0xcd, 0x7e, 0x38, 0xda, 0xe9, 0xfc, 0x0b, 0x63, 0x86, 0xce, 0xbf, 0x20, 0x37, 0x52,
|
||||
0x31, 0xed, 0x51, 0x19, 0xe0, 0xc0, 0x8d, 0xa0, 0x0c, 0xa8, 0x75, 0xd0, 0x03, 0x03, 0xb4, 0x61,
|
||||
0x4c, 0x50, 0x1f, 0x3f, 0x15, 0x63, 0x66, 0x18, 0x1b, 0xd4, 0xf0, 0x0b, 0x23, 0x38, 0xff, 0xc2,
|
||||
0x98, 0x31, 0x22, 0x35, 0xcc, 0xbf, 0x30, 0x6e, 0x28, 0x03, 0x0a, 0xe5, 0xc6, 0x74, 0x6d, 0x94,
|
||||
0x01, 0x4e, 0xb9, 0xa1, 0xf3, 0x77, 0xd3, 0xf9, 0x5b, 0xb3, 0x1f, 0x18, 0x50, 0x0c, 0xfc, 0x50,
|
||||
0x69, 0x30, 0x6e, 0x75, 0xc6, 0x01, 0x78, 0xc4, 0x58, 0x52, 0x8a, 0x83, 0x23, 0x3b, 0x6a, 0xeb,
|
||||
0xd2, 0x16, 0x40, 0x19, 0xe0, 0xc8, 0x8d, 0xc8, 0x51, 0x33, 0x08, 0x29, 0x9b, 0x60, 0x0d, 0x5b,
|
||||
0xcf, 0xd2, 0x29, 0x27, 0x8c, 0x03, 0x53, 0x41, 0xd0, 0xdf, 0x8d, 0x79, 0x57, 0xca, 0x81, 0x22,
|
||||
0xb0, 0x33, 0xe3, 0x80, 0xb2, 0x83, 0x0c, 0xa8, 0x1c, 0xd9, 0x51, 0x2b, 0x03, 0x9c, 0x71, 0xc3,
|
||||
0x46, 0x63, 0x63, 0x23, 0x03, 0x1c, 0xb9, 0x61, 0x02, 0xde, 0xb8, 0x09, 0x3b, 0xdc, 0x20, 0x0e,
|
||||
0xc5, 0xa0, 0x0d, 0xaa, 0x1c, 0xc5, 0xe4, 0x70, 0xd3, 0x71, 0xfe, 0xa6, 0x1b, 0xce, 0xd4, 0xc1,
|
||||
0xb8, 0x31, 0xed, 0x51, 0x19, 0xa0, 0xca, 0xa1, 0x0c, 0xa8, 0x8b, 0x31, 0x03, 0xac, 0x31, 0x88,
|
||||
0x83, 0xce, 0xd9, 0x8d, 0x99, 0x61, 0x9f, 0x6a, 0xc2, 0xca, 0xb6, 0x50, 0x75, 0x30, 0x66, 0xa8,
|
||||
0x3a, 0x18, 0x2f, 0x75, 0xfe, 0xa6, 0x1c, 0xc6, 0x00, 0x55, 0x0e, 0x37, 0x5d, 0x1b, 0x65, 0x80,
|
||||
0x2a, 0x87, 0x9b, 0xa8, 0xc3, 0x30, 0x7f, 0x6b, 0x1e, 0x8b, 0xf1, 0x61, 0x41, 0x52, 0x92, 0x80,
|
||||
0xa6, 0xfb, 0xb2, 0x10, 0xf7, 0xcb, 0x4a, 0xbe, 0x30, 0xcf, 0x45, 0x39, 0x50, 0xd3, 0x55, 0x63,
|
||||
0x39, 0xba, 0x2f, 0x5b, 0xfc, 0x7e, 0x69, 0xb7, 0xee, 0xbe, 0xe8, 0x71, 0xf5, 0x8b, 0xee, 0xf2,
|
||||
0x8a, 0x00, 0xe2, 0xed, 0xc5, 0xe6, 0x76, 0x0d, 0x9c, 0x39, 0x01, 0xe5, 0xb1, 0xb5, 0x12, 0x4e,
|
||||
0x3f, 0x89, 0xb2, 0xa5, 0x78, 0xca, 0x08, 0xf6, 0x26, 0xc0, 0xc2, 0x88, 0xa0, 0xe5, 0x84, 0x2c,
|
||||
0xde, 0x74, 0x38, 0xc1, 0x06, 0x08, 0x44, 0x39, 0xcb, 0x8e, 0xa0, 0xb8, 0x79, 0x90, 0xe5, 0xf2,
|
||||
0x01, 0x4e, 0xad, 0x97, 0x78, 0x83, 0xdc, 0x4b, 0xb5, 0xb8, 0xc1, 0xb2, 0xb9, 0x62, 0xb3, 0x44,
|
||||
0x60, 0x8b, 0x6f, 0xd9, 0xa5, 0x12, 0x02, 0x8a, 0x40, 0xc0, 0xdf, 0xe7, 0x9d, 0x15, 0xa9, 0x24,
|
||||
0x2c, 0xcd, 0xb2, 0x1b, 0xc8, 0x35, 0x4d, 0x44, 0x1c, 0xcf, 0x60, 0x49, 0xf6, 0x85, 0xa1, 0x19,
|
||||
0x2a, 0x19, 0x55, 0x26, 0xab, 0x6b, 0xdd, 0x03, 0xbc, 0xc4, 0xcc, 0x11, 0x11, 0xa6, 0xf4, 0x05,
|
||||
0xa7, 0x43, 0x3e, 0xed, 0x37, 0xc4, 0x50, 0xd4, 0x10, 0x53, 0xae, 0x08, 0x16, 0x42, 0x31, 0xb0,
|
||||
0xd5, 0x47, 0xc4, 0xa0, 0x1e, 0x0a, 0xd2, 0x8a, 0xd3, 0x25, 0xbb, 0x6a, 0x88, 0x9e, 0xbe, 0x44,
|
||||
0x43, 0x3d, 0xad, 0xc5, 0x50, 0xd4, 0x70, 0x50, 0x2a, 0x84, 0xf0, 0x51, 0x7c, 0x4d, 0xd9, 0xd6,
|
||||
0x52, 0x39, 0xec, 0x04, 0x40, 0x60, 0xa2, 0xb8, 0x84, 0x12, 0xc9, 0x9a, 0x49, 0x4f, 0x08, 0x01,
|
||||
0x1a, 0x64, 0x0a, 0xec, 0xc4, 0x3a, 0x29, 0x6e, 0x22, 0x4a, 0x51, 0x37, 0x4e, 0x42, 0xe7, 0x2c,
|
||||
0xfe, 0xbe, 0x75, 0xa7, 0xbd, 0x97, 0xbb, 0xa6, 0x4d, 0xa3, 0xd4, 0xa1, 0x0f, 0xd3, 0x71, 0xa3,
|
||||
0xe9, 0xc8, 0x31, 0xd1, 0x17, 0xc4, 0x9e, 0xe8, 0x19, 0x46, 0x20, 0x66, 0xba, 0xce, 0xca, 0x13,
|
||||
0x67, 0x3c, 0x41, 0xe8, 0x8f, 0x7c, 0x47, 0x12, 0xad, 0x8e, 0xe2, 0xf7, 0xc3, 0xb7, 0x80, 0xeb,
|
||||
0x2c, 0x2b, 0x5b, 0xa7, 0x81, 0xd9, 0x6e, 0x60, 0xb6, 0x87, 0x25, 0x80, 0xcb, 0x56, 0x8a, 0x96,
|
||||
0x32, 0x2d, 0x51, 0xd2, 0x75, 0x00, 0x7a, 0xde, 0xc0, 0xac, 0xe9, 0x4a, 0xba, 0x61, 0x25, 0x2b,
|
||||
0xf8, 0x3b, 0x62, 0xfb, 0x11, 0x2b, 0x6a, 0x14, 0x41, 0x51, 0x50, 0xb9, 0xd0, 0xc6, 0xe7, 0xa7,
|
||||
0x36, 0x05, 0xe8, 0x47, 0x47, 0xd1, 0x68, 0x33, 0xd4, 0x31, 0xc0, 0x41, 0x83, 0xff, 0x96, 0x7c,
|
||||
0x6d, 0x0d, 0xfd, 0x84, 0x7d, 0x89, 0x10, 0x1c, 0x4e, 0xbb, 0x12, 0x27, 0x21, 0xc0, 0x91, 0x90,
|
||||
0xfd, 0x2a, 0x20, 0xcd, 0x20, 0xff, 0xaf, 0x64, 0xb8, 0x95, 0x4c, 0x19, 0x8e, 0x9b, 0x44, 0xd3,
|
||||
0xd9, 0x33, 0x74, 0x17, 0xeb, 0x02, 0x30, 0x48, 0x0c, 0xe2, 0x49, 0x8a, 0xc2, 0x25, 0xf1, 0x30,
|
||||
0xe8, 0x8f, 0x0b, 0x5f, 0xe0, 0xe5, 0x89, 0xad, 0x8c, 0x50, 0x98, 0xf6, 0xa4, 0xca, 0x20, 0x5d,
|
||||
0x01, 0x12, 0x01, 0x52, 0x07, 0xe6, 0xd9, 0xc9, 0xc5, 0x70, 0xb2, 0x84, 0xcd, 0x70, 0xd1, 0x11,
|
||||
0xd7, 0x07, 0xc0, 0xc7, 0xda, 0xb1, 0xcc, 0x1f, 0x51, 0x40, 0xbd, 0x6b, 0x0f, 0x03, 0x29, 0x87,
|
||||
0x79, 0x15, 0x9c, 0x4f, 0xd2, 0xf9, 0x4c, 0x3e, 0x73, 0x83, 0x0c, 0x0c, 0x37, 0x4c, 0xb1, 0x6f,
|
||||
0x31, 0x21, 0x11, 0xd2, 0x00, 0xd0, 0x6a, 0x2b, 0x65, 0x71, 0x25, 0xac, 0x6f, 0xc1, 0x52, 0x40,
|
||||
0x7d, 0xe2, 0x24, 0x01, 0x78, 0x94, 0x51, 0x21, 0xad, 0x22, 0x04, 0x22, 0x80, 0x8c, 0x5a, 0x61,
|
||||
0x1b, 0xb6, 0x24, 0xa0, 0x2c, 0x11, 0x68, 0xc0, 0x53, 0x8d, 0xde, 0x8e, 0x15, 0x7a, 0xac, 0x43,
|
||||
0x3e, 0xa6, 0x8e, 0x09, 0x09, 0xad, 0x4a, 0x36, 0x5d, 0xe0, 0x31, 0x1e, 0x7d, 0x59, 0x1f, 0xd6,
|
||||
0xe7, 0xd0, 0x5e, 0x61, 0x32, 0xfa, 0xbb, 0xcd, 0xed, 0x0a, 0x8b, 0xd1, 0x08, 0x61, 0x64, 0x68,
|
||||
0xf6, 0x36, 0xa3, 0x8c, 0xb4, 0x19, 0x08, 0xf7, 0x3c, 0x13, 0x4b, 0x22, 0x1b, 0x21, 0x8a, 0x77,
|
||||
0x89, 0x70, 0x64, 0x2b, 0x3a, 0xd9, 0xd2, 0x7b, 0x45, 0x82, 0xaa, 0xf5, 0x61, 0x68, 0x3b, 0x6b,
|
||||
0xc3, 0xa5, 0x01, 0xbd, 0x9a, 0xbb, 0xbd, 0xb0, 0xd8, 0x7b, 0xa6, 0x9f, 0x90, 0xb0, 0x68, 0x80,
|
||||
0x9e, 0x08, 0xd1, 0xe4, 0x81, 0x45, 0xb4, 0xb2, 0x4b, 0x89, 0xd0, 0x34, 0xf4, 0xbe, 0x4b, 0xf4,
|
||||
0x16, 0x4f, 0x40, 0x57, 0xf8, 0x08, 0x7c, 0x22, 0xca, 0x35, 0xed, 0x56, 0xb4, 0x92, 0xb9, 0xad,
|
||||
0x16, 0x03, 0x03, 0x1b, 0xe4, 0x1c, 0x09, 0xfa, 0xf4, 0x3b, 0x76, 0x12, 0xf9, 0x34, 0x42, 0x46,
|
||||
0x3f, 0x5b, 0x6e, 0x38, 0x1e, 0x0d, 0xe0, 0x24, 0xa1, 0xa1, 0x8a, 0xb7, 0xbe, 0xee, 0x3d, 0x6c,
|
||||
0x4f, 0x50, 0x84, 0x2d, 0x10, 0x9c, 0x63, 0xc6, 0xab, 0xae, 0xf2, 0x16, 0x94, 0x31, 0x1d, 0x74,
|
||||
0x14, 0xa1, 0xb6, 0x01, 0x07, 0x43, 0x4d, 0xe8, 0xb0, 0xab, 0xe9, 0x64, 0x67, 0x62, 0x7a, 0x58,
|
||||
0x59, 0x22, 0xc2, 0xb0, 0x35, 0xc2, 0x2c, 0x4c, 0x85, 0xad, 0xde, 0xc3, 0xc2, 0x06, 0x71, 0x4d,
|
||||
0xa0, 0xb6, 0x7a, 0xc8, 0xe9, 0xa1, 0xad, 0xd2, 0x73, 0x46, 0xcf, 0x59, 0x6f, 0x4e, 0x7b, 0xeb,
|
||||
0x5a, 0x0d, 0xe2, 0xc4, 0xc9, 0xa6, 0x8c, 0x84, 0x1a, 0x91, 0x7d, 0x05, 0xdf, 0x0c, 0x43, 0x54,
|
||||
0xe7, 0x3a, 0xf7, 0x0a, 0x73, 0x81, 0x95, 0x55, 0xa5, 0xf3, 0x72, 0x3a, 0xaf, 0xed, 0xc0, 0x0f,
|
||||
0x67, 0xfc, 0x70, 0xca, 0x2e, 0x67, 0xec, 0xea, 0xc0, 0x6a, 0x20, 0x57, 0x00, 0xea, 0xa8, 0xdf,
|
||||
0x50, 0x25, 0x78, 0x76, 0xe4, 0xb1, 0x53, 0x1e, 0xcb, 0x9a, 0xd7, 0x1e, 0x71, 0xb8, 0x27, 0xca,
|
||||
0x90, 0x24, 0x40, 0x11, 0x53, 0x52, 0x11, 0x22, 0x11, 0xb5, 0xe3, 0x6f, 0xdd, 0x25, 0x81, 0x89,
|
||||
0x23, 0x04, 0x41, 0xf2, 0x26, 0xc3, 0xef, 0x97, 0xa1, 0x53, 0xf5, 0x20, 0x20, 0xa4, 0x20, 0x02,
|
||||
0x02, 0x83, 0x53, 0x03, 0xb9, 0x0c, 0x90, 0xa1, 0x04, 0x24, 0x20, 0x46, 0xac, 0x44, 0x44, 0x9c,
|
||||
0x23, 0xe6, 0xe4, 0xa4, 0xd2, 0xe0, 0x4b, 0x4e, 0x81, 0xa9, 0xc0, 0x82, 0x61, 0xe7, 0x6c, 0x10,
|
||||
0xd1, 0x09, 0xb7, 0x24, 0x90, 0xda, 0x7a, 0xd8, 0x5f, 0xa6, 0x00, 0xf5, 0x3b, 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, 0x4b, 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, 0xef, 0xd4,
|
||||
0x45, 0x73, 0x4c, 0x81, 0xd7, 0x8a, 0x24, 0x88, 0x53, 0xc9, 0xc5, 0x8f, 0x9c, 0x92, 0xb3, 0x29,
|
||||
0x19, 0x1f, 0x9c, 0xf1, 0xc1, 0x29, 0x9b, 0x80, 0x11, 0x90, 0x4d, 0x9d, 0x74, 0x15, 0x10, 0xbb,
|
||||
0x97, 0x19, 0x44, 0x10, 0x54, 0x93, 0x9d, 0xc6, 0x5b, 0x6d, 0xac, 0x41, 0x1a, 0x6f, 0xaf, 0xfb,
|
||||
0x7e, 0x4d, 0xbe, 0xa0, 0x56, 0xf7, 0x34, 0x56, 0x62, 0xe9, 0xb6, 0x21, 0x8b, 0xdc, 0xb4, 0x40,
|
||||
0x73, 0xf1, 0x0d, 0xb9, 0x04, 0x56, 0xcc, 0x4f, 0xa7, 0xbf, 0xe1, 0xda, 0x95, 0xd8, 0x03, 0xaa,
|
||||
0x44, 0x56, 0xb6, 0x44, 0x8f, 0xf5, 0x53, 0x8f, 0x59, 0x83, 0xc7, 0x65, 0xb3, 0xde, 0x1a, 0x31,
|
||||
0xe0, 0xdf, 0x13, 0xe2, 0xc3, 0xff, 0xbb, 0x62, 0xdf, 0xcb, 0x31, 0x1a, 0xb0, 0x42, 0x6c, 0xba,
|
||||
0xd1, 0x79, 0x6e, 0x18, 0x87, 0xd3, 0x73, 0xb6, 0xd3, 0x4e, 0xf2, 0xbc, 0xd3, 0x6e, 0x44, 0xa2,
|
||||
0x39, 0x4a, 0x42, 0x58, 0x20, 0x22, 0x8e, 0x89, 0x7a, 0xd1, 0x43, 0xac, 0x59, 0xdd, 0x32, 0xab,
|
||||
0x00, 0x41, 0x61, 0xa3, 0xf7, 0x95, 0x4a, 0x11, 0xb3, 0xde, 0x7a, 0xa4, 0xc0, 0x91, 0x76, 0x3b,
|
||||
0xed, 0x35, 0xbb, 0x79, 0xef, 0x4a, 0x78, 0x4f, 0x5e, 0x5c, 0x90, 0x11, 0x7d, 0xbf, 0x48, 0xdf,
|
||||
0x2b, 0xfd, 0x6e, 0x3c, 0xf3, 0x63, 0xeb, 0x50, 0x6d, 0x67, 0x5c, 0xcd, 0x2b, 0x44, 0x64, 0x73,
|
||||
0x7b, 0x7b, 0xfd, 0x07, 0x8b, 0x84, 0x8b, 0xee, 0xf2, 0xb6, 0xdb, 0x5e, 0xac, 0x10, 0x17, 0xc3,
|
||||
0xce, 0x99, 0xf2, 0x10, 0x95, 0xe9, 0x46, 0x18, 0x3a, 0x32, 0x1c, 0x53, 0xf0, 0xdc, 0x19, 0x78,
|
||||
0x3e, 0xb4, 0x7b, 0x03, 0xe4, 0x1d, 0x01, 0xf9, 0x68, 0x87, 0x51, 0x5e, 0xa0, 0xa7, 0x0f, 0xdf,
|
||||
0x4a, 0x66, 0xdf, 0x1e, 0x80, 0x7b, 0xbb, 0x4c, 0xa9, 0xb4, 0x07, 0xbd, 0x4c, 0x2f, 0x0b, 0xc5,
|
||||
0x94, 0x7c, 0x28, 0x86, 0xeb, 0x26, 0xe9, 0x80, 0xbc, 0x4b, 0x07, 0xec, 0x4e, 0x9b, 0x4c, 0x22,
|
||||
0xec, 0x32, 0x00, 0x76, 0xd9, 0x30, 0x87, 0x59, 0x2f, 0x9f, 0x27, 0x2e, 0xb7, 0x65, 0x92, 0x4a,
|
||||
0x4d, 0x1c, 0x15, 0xe3, 0x8c, 0x52, 0xc1, 0xcf, 0xde, 0xfe, 0x57, 0x8c, 0xfe, 0xa7, 0x9f, 0xe2,
|
||||
0x00, 0xd8, 0xc5, 0xda, 0x76, 0xe3, 0x13, 0x95, 0x44, 0xbf, 0x94, 0xa1, 0x3a, 0x16, 0x4e, 0x79,
|
||||
0x19, 0x16, 0xd1, 0x53, 0x4f, 0x08, 0x70, 0x1b, 0xc4, 0x3f, 0x14, 0x5e, 0xe1, 0x93, 0x62, 0x15,
|
||||
0x4d, 0xbd, 0x47, 0x8a, 0x97, 0x07, 0x8d, 0x28, 0xdd, 0x5e, 0xf5, 0x4d, 0xf0, 0xe6, 0x5a, 0x23,
|
||||
0xc6, 0x15, 0x79, 0x1e, 0x38, 0xa6, 0x09, 0xf9, 0xc2, 0xf4, 0x36, 0x06, 0x66, 0x90, 0xba, 0xa1,
|
||||
0x2e, 0xe0, 0xde, 0x92, 0x83, 0x79, 0x81, 0xd1, 0xdb, 0xc2, 0x2e, 0xdf, 0x1a, 0x39, 0x67, 0xe4,
|
||||
0xbb, 0xfd, 0x48, 0xe2, 0xf1, 0x91, 0x14, 0x35, 0x47, 0xc9, 0xcf, 0x82, 0x4a, 0xd6, 0x50, 0xaf,
|
||||
0x12, 0x8c, 0x38, 0x94, 0x91, 0x8d, 0xbe, 0x18, 0x6b, 0x99, 0x1d, 0x2a, 0x1a, 0xb2, 0xa6, 0x18,
|
||||
0xf3, 0x46, 0xf6, 0x01, 0xb3, 0x42, 0xf2, 0x83, 0x5d, 0x05, 0xd5, 0x36, 0xff, 0x17, 0x94, 0x8b,
|
||||
0x25, 0xef, 0xeb, 0xb5, 0x2b, 0xc3, 0x67, 0x47, 0x3c, 0x60, 0xda, 0x55, 0x4c, 0xd4, 0x6b, 0x29,
|
||||
0x37, 0xb5, 0x53, 0xaf, 0x62, 0xaa, 0x5f, 0x33, 0x05, 0xa8, 0x8b, 0x99, 0x7e, 0xcd, 0x14, 0x28,
|
||||
0xb9, 0xa9, 0x7e, 0xcd, 0xd4, 0x2f, 0xcf, 0xd4, 0x32, 0xcc, 0xd4, 0x37, 0xb8, 0xa9, 0x7e, 0xcd,
|
||||
0x94, 0x3f, 0xb8, 0x99, 0x7e, 0xcd, 0x14, 0x28, 0x17, 0x53, 0xfd, 0x2a, 0xee, 0xd5, 0xaf, 0x99,
|
||||
0x8e, 0x1c, 0x51, 0xa6, 0xfe, 0x50, 0x6d, 0x4c, 0xbf, 0xa6, 0xba, 0x79, 0x24, 0xdb, 0xdb, 0x1f,
|
||||
0xd1, 0xd7, 0x65, 0xfd, 0x6a, 0x72, 0xa2, 0x74, 0x0d, 0xfa, 0x35, 0x15, 0xa2, 0x91, 0x86, 0x8d,
|
||||
0xb7, 0xb6, 0xbc, 0xdb, 0x1e, 0x47, 0x9b, 0x6b, 0x53, 0x1c, 0xd7, 0xb0, 0xb9, 0x82, 0x0d, 0x2a,
|
||||
0x32, 0x2b, 0xbd, 0x71, 0xa3, 0x72, 0xa0, 0x7d, 0x59, 0xc2, 0xb8, 0xa4, 0x46, 0x35, 0x6c, 0x50,
|
||||
0xb0, 0x62, 0xae, 0x61, 0xa3, 0xa1, 0xc4, 0xe3, 0x43, 0x71, 0x23, 0x15, 0x73, 0x63, 0x15, 0x73,
|
||||
0x13, 0x15, 0x9b, 0xef, 0x63, 0x7b, 0x0d, 0x1b, 0xf3, 0x66, 0xd0, 0x2f, 0xf7, 0x55, 0xfa, 0x75,
|
||||
0x7b, 0xdd, 0xbd, 0xbb, 0x58, 0x83, 0x84, 0x24, 0xc4, 0x81, 0x4e, 0x8b, 0x1b, 0x8b, 0x46, 0x64,
|
||||
0x8c, 0x05, 0x11, 0x48, 0x06, 0xc4, 0x86, 0x59, 0x46, 0xcf, 0x0c, 0x51, 0xee, 0xf7, 0x4d, 0x67,
|
||||
0xff, 0xc2, 0xb7, 0xd3, 0x7f, 0xbb, 0xe1, 0xdf, 0xfb, 0xe6, 0x70, 0xc6, 0x67, 0xeb, 0x82, 0x25,
|
||||
0x41, 0x93, 0xa2, 0x94, 0x83, 0xc2, 0x9b, 0x7e, 0x5e, 0x6e, 0x73, 0x4f, 0x0d, 0xca, 0x41, 0xed,
|
||||
0x12, 0x3f, 0x8e, 0x49, 0x20, 0x56, 0x15, 0xc9, 0x28, 0xd6, 0x7c, 0x24, 0x96, 0xdb, 0x95, 0x0c,
|
||||
0x3f, 0x59, 0x3b, 0x81, 0x18, 0x8b, 0xbe, 0x44, 0x52, 0x5f, 0x02, 0x41, 0xa7, 0x04, 0x52, 0xfa,
|
||||
0x29, 0x51, 0x40, 0x8c, 0x1a, 0x79, 0x06, 0x89, 0xc1, 0xda, 0x48, 0x07, 0x4c, 0x3c, 0xcf, 0x26,
|
||||
0x33, 0x92, 0x0a, 0x48, 0x21, 0xd4, 0x99, 0x22, 0x02, 0x42, 0x55, 0xd0, 0x92, 0xbf, 0x80, 0xa2,
|
||||
0x44, 0x58, 0x98, 0xa1, 0xdd, 0x9c, 0x64, 0x40, 0x4c, 0xc8, 0xfc, 0xb4, 0xa8, 0xa9, 0x40, 0xb9,
|
||||
0x09, 0x40, 0x8e, 0x98, 0x92, 0xab, 0xa2, 0x96, 0x88, 0x34, 0x84, 0xa1, 0x86, 0x2f, 0x71, 0xac,
|
||||
0xbd, 0x38, 0x3e, 0x35, 0xcb, 0x34, 0x2b, 0x91, 0x18, 0x91, 0xd4, 0x56, 0xab, 0x40, 0x35, 0x95,
|
||||
0xd2, 0x30, 0xea, 0x2e, 0x80, 0x77, 0x78, 0xa4, 0xef, 0xc4, 0x2e, 0x64, 0x09, 0x0e, 0xab, 0xa0,
|
||||
0xb5, 0x38, 0xa8, 0x44, 0xc9, 0x94, 0xb2, 0x8c, 0x72, 0x40, 0xa6, 0x31, 0xc4, 0xf5, 0xf6, 0xf8,
|
||||
0x8d, 0x44, 0x81, 0x4c, 0x00, 0xe5, 0x0c, 0xf8, 0xfd, 0xf9, 0x69, 0xa8, 0x51, 0x24, 0x82, 0xc0,
|
||||
0x5d, 0xfa, 0x8b, 0x08, 0xb2, 0x23, 0xbe, 0x2d, 0xab, 0xdf, 0x6a, 0x9a, 0xb5, 0x2e, 0x44, 0x95,
|
||||
0x43, 0x0e, 0x28, 0x17, 0x09, 0x15, 0x53, 0xb7, 0x48, 0x7a, 0xd4, 0x12, 0x5e, 0x10, 0xf1, 0x0a,
|
||||
0x88, 0xfd, 0x4a, 0x8d, 0x20, 0x64, 0xc5, 0x23, 0xb3, 0x1e, 0x88, 0xf5, 0x1a, 0xe0, 0x8c, 0x55,
|
||||
0x64, 0x56, 0x14, 0x91, 0x1f, 0x00, 0x0a, 0x04, 0x34, 0xf0, 0xf0, 0xc1, 0x8c, 0x84, 0xf0, 0x41,
|
||||
0x62, 0x9d, 0x8a, 0xde, 0x6c, 0xac, 0xc1, 0xd2, 0xa2, 0x6a, 0x08, 0x60, 0x37, 0x25, 0xb1, 0xb7,
|
||||
0x94, 0x18, 0x39, 0x0a, 0x3b, 0x1a, 0x24, 0x0f, 0x6b, 0x2d, 0x04, 0x55, 0x34, 0x4d, 0x86, 0xde,
|
||||
0x60, 0x25, 0x2b, 0x9a, 0xf4, 0x93, 0x94, 0x83, 0x22, 0x21, 0xd2, 0x81, 0xac, 0x0a, 0x4c, 0x25,
|
||||
0x62, 0x86, 0x34, 0x7c, 0x21, 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, 0xa5, 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, 0x0c, 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, 0x27, 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, 0x7d, 0xa1,
|
||||
0x2e, 0x4c, 0x02, 0x5a, 0x60, 0x84, 0xd5, 0x70, 0x4a, 0xd0, 0x2b, 0x58, 0x26, 0x5d, 0xb3, 0x78,
|
||||
0x0a, 0x09, 0x52, 0xec, 0x1a, 0x48, 0x7f, 0xb3, 0xac, 0x57, 0xbb, 0x0d, 0x36, 0x0a, 0xcf, 0x94,
|
||||
0x88, 0x96, 0x54, 0x34, 0x62, 0x42, 0x64, 0xf4, 0x29, 0x27, 0xcc, 0x85, 0x59, 0x80, 0x06, 0x59,
|
||||
0x00, 0x4c, 0xac, 0x42, 0x5a, 0x3c, 0x8b, 0x82, 0xf0, 0x13, 0xc2, 0x81, 0xe2, 0x2c, 0xe0, 0x24,
|
||||
0x28, 0x88, 0x93, 0x21, 0x5b, 0x0a, 0xa7, 0xc4, 0x0e, 0x13, 0x91, 0x31, 0xcd, 0x4c, 0x98, 0x36,
|
||||
0x0d, 0x33, 0x8f, 0x15, 0xcb, 0xa9, 0x1a, 0x74, 0xab, 0x2d, 0x85, 0x30, 0x4b, 0xa7, 0x0a, 0x22,
|
||||
0x8a, 0xd4, 0x70, 0x57, 0xaa, 0x59, 0xa5, 0xd0, 0x94, 0x44, 0x31, 0x91, 0x4d, 0x93, 0x21, 0xb6,
|
||||
0x2e, 0x13, 0xec, 0xa9, 0x01, 0x49, 0xef, 0x96, 0x7c, 0x10, 0x81, 0x3a, 0x11, 0xa1, 0xae, 0x1a,
|
||||
0xfa, 0x3b, 0xa2, 0xa7, 0x09, 0xd6, 0x32, 0x6a, 0xb6, 0xc3, 0x84, 0x49, 0x85, 0x8b, 0xf9, 0x3f,
|
||||
0x11, 0xf4, 0x3a, 0x02, 0x25, 0x07, 0xcc, 0x82, 0xca, 0x8f, 0xb6, 0x84, 0x68, 0x0e, 0x12, 0xaa,
|
||||
0x02, 0x5b, 0x69, 0xc4, 0x0e, 0x34, 0x0a, 0x55, 0xae, 0xb2, 0xbe, 0xc8, 0x9d, 0x4b, 0x6c, 0x06,
|
||||
0x88, 0x45, 0x65, 0x3e, 0x68, 0x5e, 0x34, 0xd5, 0x34, 0x0f, 0xb1, 0xe1, 0x6a, 0x01, 0xc7, 0x85,
|
||||
0x70, 0x00, 0x0f, 0x00, 0x98, 0xa2, 0xaa, 0x54, 0xed, 0x54, 0x4b, 0x14, 0x05, 0x63, 0x85, 0x21,
|
||||
0x4a, 0xb0, 0x55, 0x89, 0xf5, 0xee, 0x01, 0x94, 0x65, 0x7d, 0xac, 0x69, 0x3a, 0xfb, 0x51, 0x8b,
|
||||
0x6d, 0xb5, 0xc4, 0xf0, 0xa9, 0x8f, 0x2d, 0x83, 0x59, 0xb1, 0xf5, 0xb0, 0xac, 0x9d, 0x44, 0xfe,
|
||||
0xa8, 0x13, 0x83, 0x05, 0x52, 0x93, 0x95, 0x6b, 0x82, 0xa8, 0xf4, 0x01, 0xcb, 0x46, 0x51, 0x09,
|
||||
0x98, 0xc4, 0x8a, 0x89, 0xc6, 0x20, 0x93, 0x8f, 0x9a, 0xcb, 0x01, 0xa6, 0x0e, 0xfc, 0xc3, 0x7b,
|
||||
0x82, 0x7b, 0x31, 0xd1, 0x96, 0x7b, 0x61, 0x4a, 0x14, 0xb1, 0x89, 0x2d, 0xeb, 0xce, 0x2a, 0x45,
|
||||
0x6e, 0xc0, 0xbe, 0x44, 0x20, 0x2b, 0xcb, 0xfc, 0x51, 0x2b, 0x5e, 0x11, 0x6a, 0x4f, 0x0d, 0xb2,
|
||||
0xc5, 0x01, 0xc5, 0x57, 0x2e, 0x0b, 0x0b, 0x64, 0xbb, 0xe9, 0x64, 0x12, 0x8d, 0xb8, 0x7c, 0x58,
|
||||
0xa4, 0x08, 0x26, 0xd1, 0x11, 0xf1, 0xdc, 0x17, 0x71, 0x85, 0x57, 0x02, 0xa8, 0x1d, 0x90, 0xf1,
|
||||
0xe0, 0x96, 0x00, 0x96, 0xc6, 0x43, 0x33, 0x98, 0x02, 0xaf, 0x54, 0x15, 0x30, 0x0c, 0xec, 0xd4,
|
||||
0xc2, 0xe4, 0x96, 0x15, 0x45, 0x80, 0x94, 0x33, 0x0b, 0x81, 0x50, 0xc9, 0x58, 0x81, 0xc9, 0x28,
|
||||
0x16, 0x6e, 0x39, 0x3b, 0x00, 0xfa, 0x98, 0x6d, 0xe5, 0xe3, 0xe7, 0xa7, 0x4d, 0xc3, 0xe2, 0x2a,
|
||||
0x17, 0x31, 0x43, 0x00, 0x43, 0x80, 0x5f, 0xc5, 0x28, 0x8a, 0x3f, 0xde, 0x42, 0x07, 0x80, 0x29,
|
||||
0x52, 0x26, 0x22, 0xb7, 0x3f, 0x60, 0xca, 0x50, 0xb4, 0xa1, 0x5d, 0x92, 0xbf, 0xc8, 0x1a, 0xc9,
|
||||
0xfa, 0x7a, 0xe8, 0x77, 0x05, 0x7b, 0x85, 0xc2, 0x02, 0x16, 0x02, 0x12, 0xc2, 0x6e, 0xe0, 0x3a,
|
||||
0x54, 0x5c, 0x53, 0xd1, 0x65, 0x58, 0x73, 0x99, 0x4c, 0xf2, 0x19, 0x88, 0x2f, 0xd2, 0xcc, 0x91,
|
||||
0x59, 0x1a, 0x61, 0x0c, 0x3a, 0xe0, 0x27, 0x2a, 0x95, 0x70, 0xb6, 0x68, 0x85, 0xee, 0x2a, 0x38,
|
||||
0x81, 0x67, 0x73, 0x27, 0x68, 0x81, 0xee, 0xa3, 0xd8, 0x3f, 0x0e, 0xbd, 0x48, 0x9f, 0x8d, 0x90,
|
||||
0xda, 0xb7, 0x50, 0xbb, 0x55, 0x2a, 0xec, 0x89, 0x28, 0xdd, 0x04, 0x2c, 0x31, 0x5f, 0xac, 0x83,
|
||||
0x6f, 0x46, 0x93, 0x09, 0xcc, 0xa7, 0x7b, 0xec, 0x66, 0xd0, 0x4f, 0xb1, 0x06, 0x11, 0x05, 0x55,
|
||||
0x40, 0xf2, 0x51, 0x5f, 0x24, 0x3b, 0x46, 0x86, 0xa3, 0x5e, 0x06, 0xea, 0x77, 0x24, 0xae, 0xc9,
|
||||
0x8d, 0x55, 0x7c, 0x94, 0x1a, 0x9b, 0xb4, 0xec, 0xee, 0x0a, 0xc3, 0xe9, 0x39, 0xbb, 0x6b, 0xd6,
|
||||
0xa0, 0xd5, 0x9f, 0xae, 0xba, 0x2f, 0x78, 0x75, 0x72, 0x26, 0x9f, 0xcd, 0xa5, 0xe1, 0xad, 0x84,
|
||||
0x12, 0x34, 0xc9, 0x35, 0x98, 0xd9, 0x9a, 0xcb, 0xfd, 0x05, 0x44, 0x4a, 0x56, 0x3f, 0x57, 0x94,
|
||||
0x66, 0xf9, 0x42, 0x79, 0x1d, 0x92, 0x57, 0x25, 0x90, 0x53, 0x6e, 0x44, 0x2d, 0x6e, 0x33, 0x28,
|
||||
0x51, 0xd4, 0xc5, 0xdc, 0x80, 0x08, 0xac, 0x48, 0x91, 0xe8, 0x0e, 0x73, 0xf0, 0xb2, 0x15, 0xe9,
|
||||
0x97, 0xf8, 0x4d, 0xb9, 0xd4, 0x9c, 0x09, 0x53, 0x4d, 0x44, 0x5e, 0x40, 0x48, 0x5b, 0xd0, 0xdb,
|
||||
0xc0, 0xed, 0x14, 0x66, 0x58, 0x78, 0x02, 0xb3, 0x82, 0x8c, 0x79, 0x82, 0x8b, 0x08, 0xec, 0x31,
|
||||
0xb3, 0x82, 0x33, 0x69, 0x26, 0xca, 0xc2, 0xd1, 0x13, 0xbd, 0xeb, 0x04, 0x95, 0x6b, 0x30, 0x72,
|
||||
0x89, 0xb5, 0x24, 0xb1, 0x6d, 0xf4, 0x84, 0xec, 0xf4, 0xec, 0xe1, 0x0c, 0x9c, 0xad, 0xc7, 0x0b,
|
||||
0x3b, 0x1b, 0xc4, 0x31, 0x84, 0x06, 0xb0, 0x30, 0xef, 0x3c, 0xa1, 0x67, 0x80, 0x21, 0x24, 0xdc,
|
||||
0xe4, 0xc2, 0x64, 0xcc, 0xae, 0xed, 0x5b, 0x8d, 0xe8, 0x50, 0x80, 0x19, 0xb4, 0xac, 0x0c, 0x9b,
|
||||
0x23, 0x7d, 0x36, 0xad, 0x49, 0xad, 0x60, 0xcb, 0x7d, 0x4b, 0x96, 0x45, 0x99, 0xaa, 0x7e, 0xad,
|
||||
0x60, 0xf2, 0x04, 0x34, 0x3c, 0x16, 0x4c, 0xc4, 0xed, 0x38, 0x6b, 0xfa, 0x8d, 0x00, 0xd9, 0x76,
|
||||
0x94, 0x45, 0x5d, 0x02, 0xcb, 0xe2, 0x0e, 0x2c, 0x9b, 0xfb, 0x41, 0x26, 0x50, 0x41, 0x63, 0xf0,
|
||||
0xc4, 0xe2, 0x65, 0xb1, 0xa4, 0x4c, 0x97, 0xb2, 0xc6, 0x0f, 0xde, 0x31, 0x38, 0x5f, 0xc1, 0x9a,
|
||||
0xd8, 0x32, 0x21, 0x32, 0xd5, 0x95, 0x21, 0xe7, 0xe1, 0x6c, 0x54, 0x08, 0x08, 0xc8, 0x7a, 0xc8,
|
||||
0x06, 0x59, 0xef, 0x94, 0xd5, 0x28, 0xd4, 0xd5, 0x3c, 0xd8, 0xd0, 0x56, 0xd6, 0x13, 0xc0, 0x8b,
|
||||
0xda, 0x81, 0xb1, 0xbe, 0x30, 0xd6, 0x17, 0x64, 0x7d, 0xf0, 0x5b, 0x65, 0xb9, 0x33, 0xce, 0x8b,
|
||||
0xff, 0x38, 0x02, 0x28, 0xdb, 0x31, 0x40, 0xd9, 0x2e, 0x03, 0x94, 0xdd, 0x18, 0xf7, 0x1c, 0xaf,
|
||||
0xda, 0x08, 0x40, 0x1c, 0xb3, 0xf0, 0xcb, 0x90, 0xec, 0x76, 0x9c, 0x0d, 0x5f, 0x81, 0xae, 0xf6,
|
||||
0xd6, 0x6e, 0x07, 0xef, 0x51, 0xa9, 0x50, 0x05, 0x4d, 0x1f, 0x3b, 0xe8, 0xa1, 0x53, 0x3d, 0xe4,
|
||||
0x3e, 0xd7, 0xa2, 0x94, 0x80, 0x7a, 0x18, 0x9c, 0x29, 0xa2, 0x53, 0x45, 0xe4, 0x7d, 0x45, 0xac,
|
||||
0x34, 0x6f, 0x74, 0xab, 0xa5, 0x26, 0xd6, 0x4e, 0x75, 0xcf, 0xa9, 0x26, 0x86, 0xa1, 0x39, 0xa8,
|
||||
0xa2, 0x53, 0x55, 0x2c, 0x54, 0x13, 0x9d, 0x69, 0x62, 0x61, 0x9a, 0x48, 0xdd, 0xca, 0xba, 0xdc,
|
||||
0x1e, 0xba, 0x85, 0x7b, 0xa3, 0x74, 0xb9, 0x75, 0x85, 0xb9, 0xde, 0x6b, 0x62, 0x53, 0x3e, 0x63,
|
||||
0xe7, 0xfd, 0xe6, 0xf6, 0xdd, 0x7a, 0xe4, 0x47, 0xc1, 0x0d, 0x2b, 0xdb, 0x5f, 0x57, 0xc0, 0x5c,
|
||||
0xf7, 0xb3, 0xa2, 0xe5, 0x7a, 0x06, 0x0c, 0x25, 0x94, 0xee, 0x93, 0x56, 0x35, 0x20, 0x42, 0x53,
|
||||
0xf0, 0x72, 0x77, 0x62, 0xaf, 0x04, 0xaa, 0x39, 0x22, 0x34, 0xb4, 0xbb, 0xdd, 0x90, 0xdc, 0xfd,
|
||||
0x10, 0x6e, 0xbf, 0x0a, 0xc2, 0xad, 0xdd, 0x14, 0xe4, 0xd9, 0x1d, 0x1e, 0x00, 0x2f, 0xa7, 0x35,
|
||||
0xd9, 0x33, 0x22, 0x73, 0x3c, 0xeb, 0xf3, 0x9e, 0x6b, 0x10, 0xc1, 0xaf, 0x87, 0x4d, 0x17, 0x51,
|
||||
0xda, 0x45, 0x90, 0xf6, 0x58, 0x24, 0x05, 0xdf, 0xa3, 0xa9, 0x39, 0x94, 0xc4, 0x38, 0xa7, 0x3c,
|
||||
0x80, 0x1a, 0xf7, 0x09, 0x83, 0x71, 0x11, 0xcb, 0xd4, 0x9a, 0x1e, 0xd5, 0xce, 0x23, 0xa9, 0x8f,
|
||||
0x62, 0xa6, 0x49, 0x28, 0xac, 0xa1, 0xc1, 0xb4, 0xef, 0xca, 0xca, 0x19, 0xf4, 0x3b, 0x77, 0x87,
|
||||
0xba, 0x39, 0xa6, 0x30, 0xc5, 0x7a, 0xf3, 0x51, 0x84, 0x35, 0x6e, 0x69, 0x9b, 0xea, 0xe1, 0x56,
|
||||
0x2b, 0xcb, 0x97, 0x14, 0xa3, 0x7c, 0x49, 0x31, 0xce, 0x97, 0xac, 0x46, 0x49, 0xcf, 0xaf, 0xff,
|
||||
0xb8, 0xfa, 0xab, 0x20, 0x69, 0x92, 0x90, 0x13, 0x37, 0x02, 0xe6, 0x59, 0x0a, 0x62, 0x56, 0xc7,
|
||||
0x3f, 0x93, 0x9d, 0xdc, 0x17, 0x53, 0x4d, 0x98, 0xab, 0xcc, 0x92, 0x2a, 0xed, 0x55, 0xcd, 0xc0,
|
||||
0xd1, 0x09, 0xc4, 0x9a, 0x67, 0x10, 0x6b, 0x98, 0x41, 0xac, 0x61, 0x0a, 0xb1, 0xd6, 0x33, 0x88,
|
||||
0x35, 0xcc, 0x20, 0xd6, 0x74, 0xf0, 0xff, 0x29, 0xc4, 0xda, 0x4c, 0x21, 0xd6, 0x5d, 0xaa, 0x02,
|
||||
0xc9, 0x59, 0x91, 0x66, 0xa6, 0xf2, 0x44, 0xf7, 0x27, 0xb7, 0xb3, 0x1c, 0x02, 0xa1, 0xfd, 0x12,
|
||||
0xfe, 0xd9, 0x0d, 0x77, 0xc2, 0x2c, 0xe2, 0xa0, 0xfd, 0xa2, 0x7a, 0x1c, 0x2d, 0xe8, 0x2a, 0x6b,
|
||||
0x6e, 0x48, 0xb9, 0x62, 0x91, 0xd8, 0x41, 0x06, 0x42, 0xe5, 0x3a, 0x1e, 0x4f, 0x6c, 0x8d, 0xb4,
|
||||
0x62, 0x01, 0x41, 0x3d, 0x00, 0x32, 0x3f, 0xee, 0x00, 0xd2, 0xe1, 0x3e, 0xe8, 0x83, 0x3b, 0x25,
|
||||
0xf5, 0xd6, 0xc4, 0x11, 0x6c, 0x3a, 0xba, 0x41, 0xf1, 0xe3, 0x04, 0x20, 0xf5, 0x2c, 0x59, 0x22,
|
||||
0xfd, 0x35, 0x68, 0xee, 0x38, 0x07, 0x61, 0xc8, 0x28, 0x61, 0xd2, 0x62, 0x0c, 0x93, 0xf6, 0xb6,
|
||||
0x41, 0x57, 0xa6, 0x2b, 0xdc, 0x6f, 0x78, 0x44, 0x79, 0xe3, 0xf6, 0xbc, 0x81, 0x7b, 0xe1, 0x0c,
|
||||
0x1d, 0xf5, 0xd4, 0x43, 0x8f, 0xbb, 0x68, 0x8f, 0xaa, 0xd6, 0x0f, 0x7a, 0x13, 0xfa, 0x03, 0xde,
|
||||
0x92, 0xfe, 0xe0, 0xfc, 0xf2, 0x23, 0xb4, 0xec, 0xee, 0xd5, 0x23, 0xbb, 0x4d, 0x1e, 0x8f, 0x06,
|
||||
0xc2, 0xc3, 0xb4, 0xec, 0xce, 0x78, 0x1c, 0x7b, 0xf3, 0xca, 0x5d, 0x5f, 0x75, 0xdb, 0xcb, 0xee,
|
||||
0xdd, 0x4f, 0x7c, 0xec, 0xeb, 0xc3, 0x07, 0x1f, 0xfa, 0x0b, 0xf7, 0x27, 0x5e, 0x3d, 0xf6, 0x23,
|
||||
0x5f, 0x2a, 0xf6, 0xf7, 0xf9, 0xfd, 0xea, 0xd2, 0x9f, 0x9c, 0xf2, 0xf0, 0x81, 0xdd, 0xf6, 0x6e,
|
||||
0x84, 0xde, 0x9f, 0x8f, 0x09, 0xf1, 0x71, 0xa9, 0xc7, 0x49, 0xe1, 0x66, 0xdc, 0xe3, 0x24, 0x6e,
|
||||
0xfa, 0x3d, 0x89, 0xc7, 0xff, 0xf9, 0x2e, 0x2c, 0x10, 0x60, 0xfd, 0xdb, 0x71, 0x0a, 0xaf, 0xff,
|
||||
0x9c, 0x50, 0xa8, 0x16, 0x28, 0xa0, 0x1c, 0xe6, 0x38, 0x81, 0xab, 0xed, 0x84, 0x40, 0xbd, 0x40,
|
||||
0x00, 0x37, 0xe2, 0x2d, 0x10, 0xe8, 0xc7, 0x6c, 0x78, 0xb6, 0xc4, 0x04, 0x84, 0x38, 0xc7, 0x09,
|
||||
0xf4, 0x77, 0x63, 0x02, 0x67, 0x4b, 0x04, 0xba, 0xeb, 0x37, 0x93, 0xeb, 0x65, 0xe5, 0x2f, 0x3f,
|
||||
0xee, 0x56, 0xbc, 0x3b, 0x1f, 0x56, 0x7c, 0x78, 0x7c, 0xda, 0xc3, 0x07, 0x78, 0xe4, 0x0f, 0x79,
|
||||
0x24, 0xdf, 0xff, 0xeb, 0xf4, 0xd5, 0x73, 0x8f, 0x5f, 0x4b, 0xc7, 0xaf, 0x6e, 0x77, 0xd7, 0xf5,
|
||||
0xdb, 0x9f, 0xed, 0xba, 0x1e, 0xd2, 0xc4, 0xa7, 0x45, 0xb8, 0xfd, 0xd3, 0x22, 0x1c, 0xdf, 0x1e,
|
||||
0xf7, 0xd3, 0x23, 0xa6, 0xb4, 0xae, 0x2e, 0xfa, 0x7e, 0x38, 0xf9, 0xbc, 0x57, 0x7a, 0x67, 0x3f,
|
||||
0xdb, 0x33, 0xec, 0x4a, 0xf7, 0xfe, 0xf2, 0x0a, 0x9f, 0x9b, 0x3f, 0xf1, 0x50, 0x7e, 0xd7, 0xdf,
|
||||
0x5d, 0xdc, 0xfc, 0xe4, 0x31, 0x31, 0x7d, 0x8f, 0x16, 0x1e, 0x4b, 0x3f, 0x1b, 0x33, 0x9e, 0x7c,
|
||||
0x3e, 0x1a, 0xc8, 0xf3, 0x15, 0x03, 0xf9, 0xdb, 0xf3, 0x8b, 0x73, 0xc7, 0x37, 0x61, 0xfc, 0xed,
|
||||
0x60, 0x24, 0xcf, 0xbf, 0x61, 0x24, 0xdb, 0x5f, 0xd6, 0x74, 0xfe, 0x0b, 0x1e, 0xf0, 0xb5, 0xd4,
|
||||
0xfd, 0x2f, 0xdf, 0xd2, 0xfd, 0xa3, 0x35, 0xdd, 0x3f, 0x12, 0xf2, 0x4b, 0xbd, 0x3f, 0xfa, 0x8a,
|
||||
0xde, 0xa7, 0x63, 0x78, 0xdb, 0x8f, 0xc6, 0xf3, 0xeb, 0x8a, 0xf1, 0xfc, 0x2a, 0xa3, 0x99, 0x0f,
|
||||
0xe3, 0xd7, 0x23, 0xc3, 0xf0, 0x3a, 0x88, 0xf2, 0xa4, 0x0c, 0x71, 0x34, 0x10, 0x7b, 0xf9, 0xc3,
|
||||
0x01, 0x2b, 0xce, 0x56, 0x74, 0x7d, 0xb6, 0xb9, 0xfb, 0x70, 0xbb, 0xe1, 0x13, 0x14, 0xe7, 0x23,
|
||||
0x38, 0xfb, 0xea, 0x11, 0xcc, 0xc6, 0xf1, 0xfb, 0x9a, 0x25, 0xf9, 0x1d, 0xcf, 0x41, 0x5b, 0x5a,
|
||||
0x93, 0xdf, 0xbf, 0x5e, 0x22, 0xee, 0xb6, 0x2f, 0x47, 0x06, 0x5c, 0xec, 0xfb, 0xbf, 0xf8, 0x20,
|
||||
0x49, 0x77, 0xba, 0xb9, 0xba, 0xd8, 0x52, 0x7f, 0xe5, 0x6f, 0x6f, 0x04, 0xdf, 0xdf, 0xee, 0x2c,
|
||||
0x08, 0x1f, 0xb4, 0x5d, 0xb4, 0xed, 0x92, 0x15, 0x41, 0x85, 0xd0, 0x82, 0x29, 0xbd, 0x9e, 0x53,
|
||||
0xf1, 0x0b, 0x44, 0x0e, 0x6a, 0x48, 0x16, 0x08, 0xbe, 0x7f, 0x3d, 0x25, 0x78, 0x3f, 0xbd, 0x71,
|
||||
0xda, 0x7c, 0x69, 0x84, 0x33, 0x82, 0x8b, 0xd3, 0xd4, 0x44, 0xe1, 0xd4, 0x5e, 0xee, 0xb9, 0xc6,
|
||||
0xc7, 0x71, 0xe9, 0x22, 0xbd, 0x78, 0x39, 0x5a, 0x87, 0x97, 0x58, 0x07, 0x7b, 0xe0, 0xe6, 0xf8,
|
||||
0xd1, 0x32, 0xf6, 0x2f, 0x6c, 0xb2, 0xbc, 0x74, 0x4f, 0xeb, 0xec, 0xe2, 0xce, 0xf5, 0x17, 0xdd,
|
||||
0xf5, 0xd5, 0xf9, 0xe6, 0xf6, 0x93, 0xd3, 0x37, 0x7a, 0xde, 0x5d, 0x8b, 0x85, 0xe5, 0x13, 0xca,
|
||||
0x54, 0x60, 0xec, 0xf7, 0x6e, 0x93, 0x39, 0xfb, 0xae, 0xfc, 0xc7, 0x43, 0x0a, 0xce, 0x83, 0x1f,
|
||||
0xf4, 0xd8, 0xc3, 0x2f, 0x5d, 0x20, 0x8c, 0x7b, 0x84, 0x87, 0xd9, 0xad, 0xbe, 0x40, 0x76, 0xd2,
|
||||
0xe7, 0x7c, 0x0b, 0xe2, 0xea, 0x2b, 0x64, 0xe7, 0x3c, 0xbd, 0xbd, 0x94, 0xf8, 0xf5, 0xd3, 0xea,
|
||||
0x4b, 0x64, 0xaf, 0x3c, 0xfb, 0x63, 0x73, 0xe3, 0x4e, 0x7f, 0x38, 0xdb, 0x5f, 0x23, 0x0c, 0xf8,
|
||||
0xc2, 0x65, 0x51, 0x2e, 0x13, 0xb6, 0x59, 0x6f, 0x60, 0xd7, 0x6c, 0xa8, 0x83, 0x12, 0xbc, 0xbe,
|
||||
0x79, 0xa9, 0x9b, 0xd5, 0x93, 0x4d, 0x7f, 0x87, 0x37, 0x9a, 0x9e, 0xea, 0xb3, 0x55, 0x8f, 0xaf,
|
||||
0xe4, 0x93, 0xd3, 0xd1, 0x4a, 0x9e, 0xae, 0x5e, 0xc9, 0x99, 0xd6, 0xbf, 0x5c, 0xa3, 0xf5, 0xa6,
|
||||
0x8c, 0x67, 0x37, 0x17, 0x17, 0xe7, 0x87, 0x6a, 0xff, 0x72, 0xad, 0xda, 0xbf, 0x3c, 0x62, 0xfd,
|
||||
0x7e, 0xfb, 0x0b, 0xfd, 0xe3, 0xcd, 0x9b, 0x57, 0xfd, 0xe5, 0xdd, 0xa7, 0x83, 0x31, 0xfc, 0xf6,
|
||||
0x35, 0x63, 0x98, 0x19, 0xa0, 0xd3, 0xa9, 0x01, 0x7a, 0xb2, 0xf9, 0x78, 0x7d, 0x0b, 0x63, 0x77,
|
||||
0x7a, 0x7b, 0xd1, 0x5f, 0xdc, 0xf5, 0x07, 0x46, 0xe8, 0xa6, 0xdf, 0xee, 0x56, 0x99, 0x8f, 0x7b,
|
||||
0xe7, 0xb3, 0xcd, 0x97, 0xcc, 0xd0, 0x0c, 0x2c, 0x59, 0x72, 0x0f, 0x6f, 0x46, 0xfa, 0x6e, 0xcf,
|
||||
0xd4, 0xff, 0x56, 0xab, 0x74, 0xd3, 0x5f, 0x1d, 0x12, 0xfd, 0x56, 0xcb, 0x74, 0x23, 0x9e, 0xd1,
|
||||
0x64, 0xf2, 0x7c, 0x23, 0xd4, 0x7d, 0x34, 0x47, 0xe1, 0xef, 0x8c, 0x24, 0x18, 0xab, 0x2b, 0x4f,
|
||||
0xc2, 0xbf, 0x99, 0x78, 0x3f, 0x71, 0xa3, 0x47, 0xf4, 0xd9, 0xf2, 0x7a, 0x2e, 0xaf, 0xb7, 0xe5,
|
||||
0xb5, 0xd5, 0xdd, 0x5b, 0xa7, 0xc7, 0x18, 0x8f, 0xdb, 0xf1, 0x1a, 0xaa, 0xb6, 0xb9, 0xb9, 0xd9,
|
||||
0x7e, 0x9a, 0x48, 0x16, 0x0f, 0x8b, 0xbf, 0xe8, 0xec, 0x21, 0xd1, 0xe6, 0x27, 0x3e, 0x7e, 0xa8,
|
||||
0xe6, 0xec, 0xfb, 0x15, 0x27, 0x3f, 0x91, 0x93, 0xed, 0x49, 0xc7, 0x4e, 0x54, 0xf9, 0xf8, 0x15,
|
||||
0x3c, 0xf3, 0x91, 0x9c, 0xf9, 0x6a, 0xe7, 0x4c, 0x9e, 0xec, 0x47, 0xfa, 0x09, 0x30, 0xc0, 0xdd,
|
||||
0xdb, 0xdb, 0xeb, 0x0f, 0x6f, 0xde, 0xba, 0x1b, 0x15, 0x31, 0xb7, 0x67, 0x43, 0xf7, 0xc9, 0x2b,
|
||||
0x81, 0x53, 0xbf, 0x9a, 0x0d, 0x34, 0xc4, 0x23, 0x0a, 0xc1, 0x28, 0x84, 0x23, 0x14, 0xe2, 0x51,
|
||||
0x0a, 0xdf, 0xbb, 0x77, 0x17, 0x17, 0x37, 0xee, 0x62, 0xd3, 0xbd, 0x75, 0xd8, 0x1d, 0xc7, 0xd4,
|
||||
0x5e, 0x18, 0xb5, 0x17, 0xc7, 0xc6, 0x13, 0xa2, 0x2a, 0x5e, 0x54, 0xcd, 0x4b, 0x11, 0xc1, 0x9e,
|
||||
0x11, 0x7d, 0xdf, 0xff, 0x78, 0x0f, 0x83, 0x1e, 0xff, 0x77, 0x27, 0x47, 0x7c, 0xa0, 0xf7, 0x68,
|
||||
0xdb, 0xba, 0xc7, 0xaa, 0x3e, 0x97, 0x13, 0x7f, 0xe6, 0xca, 0xbe, 0xba, 0xbe, 0xbe, 0xc3, 0x3b,
|
||||
0xa5, 0x5f, 0x5f, 0xbe, 0xd9, 0xdb, 0x53, 0x90, 0x98, 0x69, 0xf7, 0xb3, 0xa9, 0x76, 0xe3, 0x0d,
|
||||
0xbc, 0xe7, 0xee, 0xdf, 0x58, 0x98, 0x03, 0xc5, 0xbe, 0x9a, 0xc4, 0x27, 0x78, 0x2f, 0xc0, 0x5f,
|
||||
0x8c, 0x18, 0x77, 0x14, 0x7f, 0xb9, 0xdd, 0x9c, 0x7f, 0xd8, 0x6c, 0x65, 0x98, 0xe7, 0x97, 0xef,
|
||||
0x1d, 0x34, 0x60, 0x85, 0x70, 0x3d, 0x7b, 0xac, 0x17, 0xfb, 0x5e, 0xb6, 0x5a, 0x3e, 0x63, 0xd1,
|
||||
0x51, 0x38, 0xce, 0x07, 0x0f, 0xf0, 0x3b, 0x84, 0xf8, 0x51, 0xd8, 0xfd, 0x8f, 0xef, 0x5d, 0x10,
|
||||
0xe9, 0xe3, 0x51, 0x89, 0xf7, 0xde, 0xc8, 0x26, 0x33, 0x96, 0xb5, 0x9d, 0x8d, 0x7d, 0xb6, 0xc2,
|
||||
0xc6, 0xfe, 0x73, 0xc9, 0xbf, 0x7c, 0x66, 0x6b, 0x9c, 0xca, 0x89, 0xc8, 0xec, 0x95, 0x6f, 0x66,
|
||||
0xd0, 0x5f, 0xac, 0x31, 0xe8, 0x2f, 0x74, 0xb4, 0xfb, 0x30, 0xeb, 0x70, 0x57, 0x79, 0x71, 0xaf,
|
||||
0x45, 0x9f, 0xd8, 0x70, 0x35, 0x21, 0x3f, 0x20, 0xec, 0xdb, 0xfd, 0x47, 0x1f, 0x4a, 0xab, 0xe1,
|
||||
0xe6, 0x6b, 0x87, 0x17, 0x56, 0x6c, 0x5e, 0x5d, 0x7f, 0xb8, 0xfb, 0xf1, 0xd5, 0x76, 0x73, 0xf5,
|
||||
0x4e, 0xce, 0xd2, 0xe3, 0xf2, 0x03, 0x4f, 0xe5, 0xc3, 0x23, 0xfa, 0xf0, 0x32, 0xf3, 0xff, 0x03,
|
||||
0x5d, 0x2f, 0xbc, 0xe7, 0xe2, 0x7c, 0x00, 0x00,
|
||||
};
|
||||
1230
wled00/html_mobile.h
Normal file
1230
wled00/html_mobile.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Settings html
|
||||
*/
|
||||
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:3em}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) );}</style>
|
||||
)=====";
|
||||
|
||||
//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_settings0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WLED Settings</title>
|
||||
)=====";
|
||||
|
||||
const char PAGE_settings1[] PROGMEM = R"=====(
|
||||
body{text-align:center;background:var(--cCol);height:100%;margin:0;background-attachment:fixed}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:8vmin;height:13.86vh;width:95%;margin-top:2.4vh}</style>
|
||||
//settings menu
|
||||
const char PAGE_settings0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><title>WLED Settings</title>)=====";
|
||||
|
||||
const char PAGE_settings1[] PROGMEM = R"=====(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>
|
||||
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script>
|
||||
</head>
|
||||
<body>
|
||||
<body onload=BB()>
|
||||
<form action=/><button type=submit id=b>Back</button></form>
|
||||
<form action=/settings/wifi><button type=submit>WiFi Setup</button></form>
|
||||
<form action=/settings/leds><button type=submit>LED Preferences</button></form>
|
||||
<form action=/settings/ui><button type=submit>User Interface</button></form>
|
||||
@@ -23,17 +22,15 @@ body{text-align:center;background:var(--cCol);height:100%;margin:0;background-at
|
||||
<form action=/settings/time><button type=submit>Time & Macros</button></form>
|
||||
<form action=/settings/sec><button type=submit>Security & Updates</button></form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
|
||||
const char PAGE_settings_wifi0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<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;
|
||||
)=====";
|
||||
const char PAGE_settings_wifi1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
|
||||
//wifi settings
|
||||
const char PAGE_settings_wifi0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500">
|
||||
<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;)=====";
|
||||
|
||||
const char PAGE_settings_wifi1[] PROGMEM = R"=====(</head>
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
@@ -70,76 +67,112 @@ AP IP: <span class="sip"> Not active </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
|
||||
const char PAGE_settings_leds0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function GetV(){var d = document;
|
||||
)=====";
|
||||
const char PAGE_settings_leds1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
<body onload="GetV()">
|
||||
|
||||
//LED settings
|
||||
const char PAGE_settings_leds0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500">
|
||||
<title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function S(){GetV();UI();}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';}
|
||||
var val=Math.ceil((100+document.Sf.LC.value*55)/500)/2;
|
||||
val=(val>5)?Math.ceil(val):val;var s="";
|
||||
if (val<1.1){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;document.getElementById('ps2').innerHTML=val+"A = "+val*1000;
|
||||
}function GetV(){var d = document;)=====";
|
||||
|
||||
const char PAGE_settings_leds1[] PROGMEM = R"=====(</head>
|
||||
<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>
|
||||
LED count (max. 255): <input name="LC" type="number" min="1" max="255" required><br>
|
||||
<i>The default boot color is always saved in preset slot 0.</i><br>
|
||||
Alternatively, apply preset <input name="BP" type="number" min="0" max="25" required> at boot<br>
|
||||
LED count: <input name="LC" type="number" min="1" max="1200" oninput=UI() required><br>
|
||||
<i>Recommended power supply for brightest white:</i><br>
|
||||
<b><span id="psu">?</span></b><br><br>
|
||||
Maximum Current: <input name="MA" type="number" min="250" max="65000" required> mA<br>
|
||||
<i>Automatically limits brightness to stay close to the limit.<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>
|
||||
"65000" completely diasbles the power calculation.<br>
|
||||
(Current estimated usage: <span class="pow">unknown</span>)</i><br><br>
|
||||
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW" onchange=UI() id="rgbw"><br>
|
||||
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><br>
|
||||
Default RGB color:
|
||||
<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><br>
|
||||
<span class="wc">Default white value: <input name="CW" type="number" min="0" max="255" required><br>
|
||||
Auto-calculate white from RGB instead: <input type="checkbox" name="AW"><br></span>
|
||||
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br>
|
||||
Default white value (only RGBW, -1 to disable): <input name="CW" type="number" min="-1" max="255" required><br>
|
||||
Default effect ID: <input name="FX" type="number" min="0" max="57" required> <br>
|
||||
Default effect speed: <input name="SX" type="number" min="0" max="255" required> <br>
|
||||
Default effect intensity: <input name="IX" type="number" min="0" max="255" required> <br>
|
||||
Default secondary RGB(W):<br>
|
||||
Default effect ID: <input name="FX" type="number" min="0" max="57" required><br>
|
||||
Default effect speed: <input name="SX" type="number" min="0" max="255" required><br>
|
||||
Default effect intensity: <input name="IX" type="number" min="0" max="255" required><br>
|
||||
Default effect palette: <input name="FP" type="number" min="0" max="255" required><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>
|
||||
<input name="SW" type="number" min="0" max="255" required><br>
|
||||
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br>
|
||||
Turn on after power up/reset: <input type="checkbox" name="BO"><br>
|
||||
Use Gamma correction for brightness: <input type="checkbox" name="GB"><br>
|
||||
Use Gamma correction for color: <input type="checkbox" name="GC"><br>
|
||||
<span class="wc"><input name="SW" type="number" min="0" max="255" required></span><br>
|
||||
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br><br>
|
||||
Apply preset <input name="BP" type="number" min="0" max="25" required> at boot (0 uses defaults)<br>
|
||||
Save current preset cycle configuration 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="0" max="255" required> %
|
||||
<h3>Transitions</h3>
|
||||
Fade: <input type="checkbox" name="TF"><br>
|
||||
Sweep: <input type="checkbox" name="TS"> Invert direction: <input type="checkbox" name="TI"><br>
|
||||
Transition Delay: <input name="TD" maxlength="5" size="2"> ms
|
||||
Crossfade: <input type="checkbox" name="TF"><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">
|
||||
<h3>Timed light</h3>
|
||||
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>
|
||||
Fade down: <input type="checkbox" name="TW"><br>
|
||||
<h3>Advanced</h3>
|
||||
Palette blending:
|
||||
<select name="PB">
|
||||
<option value="0">Linear (wrap if moving)</option>
|
||||
<option value="1">Linear (always wrap)</option>
|
||||
<option value="2">Linear (never wrap)</option>
|
||||
<option value="3">None (not recommended)</option>
|
||||
</select><br>
|
||||
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
|
||||
Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
|
||||
WARLS offset: <input name="WO" type="number" min="-255" max="255" required><hr>
|
||||
Skip first LED: <input type="checkbox" name="SL"><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
|
||||
const char PAGE_settings_ui0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
//User Interface settings
|
||||
const char PAGE_settings_ui0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500">
|
||||
<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;
|
||||
)=====";
|
||||
const char PAGE_settings_ui1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
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;)=====";
|
||||
|
||||
const char PAGE_settings_ui1[] PROGMEM = R"=====(</head>
|
||||
<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>Web Setup</h2>
|
||||
Server description: <input name="DS" maxlength="32"><br>
|
||||
User Interface Mode:
|
||||
<select name="UI">
|
||||
<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()">
|
||||
@@ -150,13 +183,13 @@ Color Theme:
|
||||
<option value="4">Electric</option>
|
||||
<option value="5">Mint</option>
|
||||
<option value="6">Amber</option>
|
||||
<option value="7">Club</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">Placeholder</option>
|
||||
<option value="13">Christmas</option>
|
||||
<option value="14">The End</option>
|
||||
<option value="15" id="co">Custom</option>
|
||||
</select><br>
|
||||
@@ -173,23 +206,24 @@ 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>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
|
||||
const char PAGE_settings_sync0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html><head><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;
|
||||
)=====";
|
||||
const char PAGE_settings_sync1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
|
||||
//sync settings
|
||||
const char PAGE_settings_sync0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><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;)=====";
|
||||
|
||||
const char PAGE_settings_sync1[] PROGMEM = R"=====(</head>
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>Sync setup</h2>
|
||||
<h3>Button setup</h3>
|
||||
On/Off button enabled: <input type="checkbox" name="BT">
|
||||
On/Off button enabled: <input type="checkbox" name="BT"><br>
|
||||
Infrared receiver enabled: <input type="checkbox" name="IR"><br>
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
|
||||
<h3>WLED Broadcast</h3>
|
||||
UDP Port: <input name="UP" maxlength="5" size="4"><br>
|
||||
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
||||
@@ -197,12 +231,37 @@ Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
||||
Send notifications on button press: <input type="checkbox" name="SB"><br>
|
||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||
Send notifications twice: <input type="checkbox" name="S2">
|
||||
Send notifications twice: <input type="checkbox" name="S2"><br>
|
||||
<h3>Realtime</h3>
|
||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
||||
<i>E1.31 (sACN)</i><br>
|
||||
Use E1.31 multicast: <input type="checkbox" name="EM"><br>
|
||||
E1.31 start universe: <input name="EU" type="number" min="1" max="63999" required><br>
|
||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx</a>!<br><br>
|
||||
Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
||||
Force max brightness: <input type="checkbox" name="FB"><br>
|
||||
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
||||
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required><br>
|
||||
Enable UI access during realtime: <input type="checkbox" name="RU"> (can cause issues)
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||
Alexa invocation name: <input name="AI" maxlength="32"><br>
|
||||
Alexa invocation name: <input name="AI" maxlength="32">
|
||||
<h3>Blynk</h3>
|
||||
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
||||
This impacts the responsiveness of the ESP8266.</b><br>
|
||||
For best results, only use one of these services at a time.<br>
|
||||
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
|
||||
Device Auth token: <input name="BK" maxlength="33"><br>
|
||||
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
||||
<h3>MQTT</h3>
|
||||
Broker: <input name="MS" maxlength="32"><br>
|
||||
Device Topic: <input name="MD" maxlength="32"><br>
|
||||
Group Topic: <input name="MG" maxlength="32"><br>
|
||||
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
||||
<h3>Philips Hue</h3>
|
||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
|
||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||
Hue Bridge IP:<br>
|
||||
<input name="H0" type="number" min="0" max="255" required> .
|
||||
<input name="H1" type="number" min="0" max="255" required> .
|
||||
@@ -210,24 +269,24 @@ Hue Bridge IP:<br>
|
||||
<input name="H3" type="number" min="0" max="255" required><br>
|
||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||
(when first connecting)<br>
|
||||
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
|
||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||
Hue status: <span class="hms"> Internal ESP Error! </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
|
||||
const char PAGE_settings_time0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html><head><title>Time Settings</title>
|
||||
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){GetV();Cs();}function gId(s){return document.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 GetV(){var d = document;
|
||||
)=====";
|
||||
const char PAGE_settings_time1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
|
||||
//time and macro settings
|
||||
const char PAGE_settings_time0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><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";}}
|
||||
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 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]+=gId("W"+i+j).checked*m;m*=2;}gId("W"+i).value=a[i];}}function GetV(){)=====";
|
||||
|
||||
const char PAGE_settings_time1[] PROGMEM = R"=====(</head>
|
||||
<body onload="S()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<form id="form_s" name="Sf" method="post" onsubmit="Wd()">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>Time setup</h2>
|
||||
@@ -256,10 +315,9 @@ Current local time is <span class="times">unknown</span>.
|
||||
Clock Overlay:
|
||||
<select name="OL" onchange="Cs()">
|
||||
<option value="0" id="cn" selected>None</option>
|
||||
<option value="1">Static color</option>
|
||||
<option value="2" id="ca">Analog Clock</option>
|
||||
<option value="3">Single Digit Clock</option>
|
||||
<option value="4" id="cc">Cronixie Clock</option>
|
||||
<option value="1" id="ca">Analog Clock</option>
|
||||
<option value="2">Single Digit Clock</option>
|
||||
<option value="3" id="cc">Cronixie Clock</option>
|
||||
</select><br>
|
||||
<div id="coc">
|
||||
First LED: <input name="O1" type="number" min="0" max="255" required> Last LED: <input name="O2" type="number" min="0" max="255" required><br>
|
||||
@@ -273,7 +331,8 @@ Cronixie Display: <input name="CX" maxlength="6"><br>
|
||||
Cronixie Backlight: <input type="checkbox" name="CB"><br>
|
||||
</div>
|
||||
Countdown Mode: <input type="checkbox" name="CE"><br>
|
||||
Countdown Goal: Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
|
||||
Countdown Goal:<br>
|
||||
Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
|
||||
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
|
||||
<h3>Advanced Macros</h3>
|
||||
Define API macros here:<br>
|
||||
@@ -294,32 +353,34 @@ Define API macros here:<br>
|
||||
15: <input name="M15" maxlength="64"><br>
|
||||
16: <input name="M16" maxlength="64"><br><br>
|
||||
<i>Use 0 for the default action instead of a macro</i><br>
|
||||
Time controlled macros coming soon!<br>
|
||||
Boot Macro: <input name="MB" type="number" min="0" max="16" required><br>
|
||||
Alexa On/Off Macros: <input name="A0" type="number" min="0" max="16" required> <input name="A1" type="number" min="0" max="16" required><br>
|
||||
Button Macro: <input name="MP" type="number" min="0" max="16" required> Long Press: <input name="ML" type="number" min="0" max="16" required><br>
|
||||
Countdown-Over Macro: <input name="MC" type="number" min="0" max="16" required><br>
|
||||
Timed-Light-Over Macro: <input name="MN" type="number" min="0" max="16" required><hr>
|
||||
Timed-Light-Over Macro: <input name="MN" type="number" min="0" max="16" required><br>
|
||||
Time-Controlled Macros:<br>
|
||||
<div style="display: inline-block">
|
||||
<table id="TMT">
|
||||
</table></div><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
|
||||
const char PAGE_settings_sec0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
|
||||
//security settings and about
|
||||
const char PAGE_settings_sec0[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500">
|
||||
<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;
|
||||
)=====";
|
||||
const char PAGE_settings_sec1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
<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;)=====";
|
||||
|
||||
const char PAGE_settings_sec1[] PROGMEM = R"=====(</head>
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
|
||||
<h2>Security & Update setup</h2>
|
||||
Enable OTA lock: <input type="checkbox" name="NO"><br>
|
||||
Lock wireless (OTA) software update: <input type="checkbox" name="NO"><br>
|
||||
Passphrase: <input type="password" name="OP" maxlength="32"><br>
|
||||
To enable OTA, for security reasons you need to also enter the correct password!<br>
|
||||
The password should be changed when OTA is enabled.<br>
|
||||
@@ -336,19 +397,13 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
|
||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||
<h3>About</h3>
|
||||
<a href="https://github.com/Aircoookie/WLED">WLED</a> version 0.6.2<br>
|
||||
(c) 2016-2018 Christian Schwinne <br>
|
||||
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.3<br><br>
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||
(c) 2016-2019 Christian Schwinne <br>
|
||||
<i>Licensed under the MIT license</i><br><br>
|
||||
<i>Uses libraries:</i><br>
|
||||
<i>ESP8266/ESP32 Arduino Core</i><br>
|
||||
<i>(ESP32) <a href="https://github.com/bbx10/WebServer_tng">WebServer_tng</a> by bbx10</i><br>
|
||||
<i><a href="https://github.com/kitesurfer1404/WS2812FX">WS2812FX</a> by kitesurfer1404 (modified)</i><br>
|
||||
<i><a href="https://github.com/JChristensen/Timezone">Timezone</a> library by JChristensen</i><br>
|
||||
<i><a href="https://github.com/Aircoookie/Espalexa">Espalexa</a> by Aircoookie (modified)</i><br><br>
|
||||
<i>UI icons by <a href="https://linearicons.com">Linearicons</a> created by <a href="https://perxis.com">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
|
||||
Server message: <span class="msg"> Response error! </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
</html>)=====";
|
||||
185
wled00/htmls00.h
185
wled00/htmls00.h
File diff suppressed because one or more lines are too long
95
wled00/ir_codes.h
Normal file
95
wled00/ir_codes.h
Normal file
@@ -0,0 +1,95 @@
|
||||
//Infrared codes
|
||||
|
||||
//Add your custom codes here
|
||||
#define IRCUSTOM_ONOFF 0xA55AEA15 //Pioneer RC-975R "+FAV" button (example)
|
||||
#define IRCUSTOM_MACRO1 0xFFFFFFFF //placeholder, will never be checked for
|
||||
|
||||
//Infrared codes for 24-key remote from http://woodsgood.ca/projects/2015/02/13/rgb-led-strip-controllers-ir-codes/
|
||||
#define IR24_BRIGHTER 0xF700FF
|
||||
#define IR24_DARKER 0xF7807F
|
||||
#define IR24_OFF 0xF740BF
|
||||
#define IR24_ON 0xF7C03F
|
||||
#define IR24_RED 0xF720DF
|
||||
#define IR24_REDDISH 0xF710EF
|
||||
#define IR24_ORANGE 0xF730CF
|
||||
#define IR24_YELLOWISH 0xF708F7
|
||||
#define IR24_YELLOW 0xF728D7
|
||||
#define IR24_GREEN 0xF7A05F
|
||||
#define IR24_GREENISH 0xF7906F
|
||||
#define IR24_TURQUOISE 0xF7B04F
|
||||
#define IR24_CYAN 0xF78877
|
||||
#define IR24_AQUA 0xF7A857
|
||||
#define IR24_BLUE 0xF7609F
|
||||
#define IR24_DEEPBLUE 0xF750AF
|
||||
#define IR24_PURPLE 0xF7708F
|
||||
#define IR24_MAGENTA 0xF748B7
|
||||
#define IR24_PINK 0xF76897
|
||||
#define IR24_WHITE 0xF7E01F
|
||||
#define IR24_FLASH 0xF7D02F
|
||||
#define IR24_STROBE 0xF7F00F
|
||||
#define IR24_FADE 0xF7C837
|
||||
#define IR24_SMOOTH 0xF7E817
|
||||
|
||||
/* 44-key defs, to be done later
|
||||
#define IR44_BPlus 0xFF3AC5 //
|
||||
#define IR44_BMinus 0xFFBA45 //
|
||||
#define IR44_ON 0xFF827D //
|
||||
#define IR44_OFF 0xFF02FD //
|
||||
#define IR44_R 0xFF1AE5 //
|
||||
#define IR44_G 0xFF9A65 //
|
||||
#define IR44_B 0xFFA25D //
|
||||
#define IR44_W 0xFF22DD //
|
||||
#define IR44_B1 0xFF2AD5 //
|
||||
#define IR44_B2 0xFFAA55 //
|
||||
#define IR44_B3 0xFF926D //
|
||||
#define IR44_B4 0xFF12ED //
|
||||
#define IR44_B5 0xFF0AF5 //
|
||||
#define IR44_B6 0xFF8A75 //
|
||||
#define IR44_B7 0xFFB24D //
|
||||
#define IR44_B8 0xFF32CD //
|
||||
#define IR44_B9 0xFF38C7 //
|
||||
#define IR44_B10 0xFFB847 //
|
||||
#define IR44_B11 0xFF7887 //
|
||||
#define IR44_B12 0xFFF807 //
|
||||
#define IR44_B13 0xFF18E7 //
|
||||
#define IR44_B14 0xFF9867 //
|
||||
#define IR44_B15 0xFF58A7 //
|
||||
#define IR44_B16 0xFFD827 //
|
||||
#define IR44_UPR 0xFF28D7 //
|
||||
#define IR44_UPG 0xFFA857 //
|
||||
#define IR44_UPB 0xFF6897 //
|
||||
#define IR44_QUICK 0xFFE817 //
|
||||
#define IR44_DOWNR 0xFF08F7 //
|
||||
#define IR44_DOWNG 0xFF8877 //
|
||||
#define IR44_DOWNB 0xFF48B7 //
|
||||
#define IR44_SLOW 0xFFC837 //
|
||||
#define IR44_DIY1 0xFF30CF //
|
||||
#define IR44_DIY2 0xFFB04F //
|
||||
#define IR44_DIY3 0xFF708F //
|
||||
#define IR44_AUTO 0xFFF00F //
|
||||
#define IR44_DIY4 0xFF10EF //
|
||||
#define IR44_DIY5 0xFF906F //
|
||||
#define IR44_DIY6 0xFF50AF //
|
||||
#define IR44_FLASH 0xFFD02F //
|
||||
#define IR44_JUMP3 0xFF20DF //
|
||||
#define IR44_JUMP7 0xFFA05F //
|
||||
#define IR44_FADE3 0xFF609F //
|
||||
#define IR44_FADE7 0xFFE01F //
|
||||
*/
|
||||
|
||||
#define COLOR_RED 0xFF0000
|
||||
#define COLOR_REDDISH 0xFF7800
|
||||
#define COLOR_ORANGE 0xFFA000
|
||||
#define COLOR_YELLOWISH 0xFFC800
|
||||
#define COLOR_YELLOW 0xFFFF00
|
||||
#define COLOR_GREEN 0x00FF00
|
||||
#define COLOR_GREENISH 0x00FF78
|
||||
#define COLOR_TURQUOISE 0x00FFA0
|
||||
#define COLOR_CYAN 0x00FFDC
|
||||
#define COLOR_AQUA 0x00C8FF
|
||||
#define COLOR_BLUE 0x00A0FF
|
||||
#define COLOR_DEEPBLUE 0x0000FF
|
||||
#define COLOR_PURPLE 0xAA00FF
|
||||
#define COLOR_MAGENTA 0xFF00DC
|
||||
#define COLOR_PINK 0xFF00A0
|
||||
#define COLOR_WHITE 0xFFFFDC
|
||||
592
wled00/palettes.h
Normal file
592
wled00/palettes.h
Normal file
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Color palettes for FastLED effects (65-73).
|
||||
*/
|
||||
|
||||
// From ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
|
||||
// Unfortunaltely, these are stored in RAM!
|
||||
|
||||
// Gradient palette "ib_jul01_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ing/xmas/tn/ib_jul01.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 16 bytes of program space.
|
||||
|
||||
#ifndef PalettesWLED_h
|
||||
#define PalettesWLED_h
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( ib_jul01_gp ) {
|
||||
0, 194, 1, 1,
|
||||
94, 1, 29, 18,
|
||||
132, 57,131, 28,
|
||||
255, 113, 1, 1};
|
||||
|
||||
// Gradient palette "es_vintage_57_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_57.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_vintage_57_gp ) {
|
||||
0, 2, 1, 1,
|
||||
53, 18, 1, 0,
|
||||
104, 69, 29, 1,
|
||||
153, 167,135, 10,
|
||||
255, 46, 56, 4};
|
||||
|
||||
|
||||
// Gradient palette "es_vintage_01_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/vintage/tn/es_vintage_01.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 32 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_vintage_01_gp ) {
|
||||
0, 4, 1, 1,
|
||||
51, 16, 0, 1,
|
||||
76, 97,104, 3,
|
||||
101, 255,131, 19,
|
||||
127, 67, 9, 4,
|
||||
153, 16, 0, 1,
|
||||
229, 4, 1, 1,
|
||||
255, 4, 1, 1};
|
||||
|
||||
|
||||
// Gradient palette "es_rivendell_15_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/rivendell/tn/es_rivendell_15.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_rivendell_15_gp ) {
|
||||
0, 1, 14, 5,
|
||||
101, 16, 36, 14,
|
||||
165, 56, 68, 30,
|
||||
242, 150,156, 99,
|
||||
255, 150,156, 99};
|
||||
|
||||
|
||||
// Gradient palette "rgi_15_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ds/rgi/tn/rgi_15.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 36 bytes of program space.
|
||||
// Edited to be brighter
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( rgi_15_gp ) {
|
||||
0, 4, 1, 70,
|
||||
31, 55, 1, 30,
|
||||
63, 255, 4, 7,
|
||||
95, 59, 2, 29,
|
||||
127, 11, 3, 50,
|
||||
159, 39, 8, 60,
|
||||
191, 112, 19, 40,
|
||||
223, 78, 11, 39,
|
||||
255, 29, 8, 59};
|
||||
|
||||
|
||||
// Gradient palette "retro2_16_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ma/retro2/tn/retro2_16.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 8 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( retro2_16_gp ) {
|
||||
0, 188,135, 1,
|
||||
255, 46, 7, 1};
|
||||
|
||||
|
||||
// Gradient palette "Analogous_1_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/red/tn/Analogous_1.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Analogous_1_gp ) {
|
||||
0, 3, 0,255,
|
||||
63, 23, 0,255,
|
||||
127, 67, 0,255,
|
||||
191, 142, 0, 45,
|
||||
255, 255, 0, 0};
|
||||
|
||||
|
||||
// Gradient palette "es_pinksplash_08_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/pink_splash/tn/es_pinksplash_08.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_pinksplash_08_gp ) {
|
||||
0, 126, 11,255,
|
||||
127, 197, 1, 22,
|
||||
175, 210,157,172,
|
||||
221, 157, 3,112,
|
||||
255, 157, 3,112};
|
||||
|
||||
|
||||
// Gradient palette "es_ocean_breeze_036_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/ocean_breeze/tn/es_ocean_breeze_036.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 16 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_ocean_breeze_036_gp ) {
|
||||
0, 1, 6, 7,
|
||||
89, 1, 99,111,
|
||||
153, 144,209,255,
|
||||
255, 0, 73, 82};
|
||||
|
||||
|
||||
// Gradient palette "departure_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/mjf/tn/departure.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 88 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( departure_gp ) {
|
||||
0, 8, 3, 0,
|
||||
42, 23, 7, 0,
|
||||
63, 75, 38, 6,
|
||||
84, 169, 99, 38,
|
||||
106, 213,169,119,
|
||||
116, 255,255,255,
|
||||
138, 135,255,138,
|
||||
148, 22,255, 24,
|
||||
170, 0,255, 0,
|
||||
191, 0,136, 0,
|
||||
212, 0, 55, 0,
|
||||
255, 0, 55, 0};
|
||||
|
||||
|
||||
// Gradient palette "es_landscape_64_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_64.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 36 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_landscape_64_gp ) {
|
||||
0, 0, 0, 0,
|
||||
37, 2, 25, 1,
|
||||
76, 15,115, 5,
|
||||
127, 79,213, 1,
|
||||
128, 126,211, 47,
|
||||
130, 188,209,247,
|
||||
153, 144,182,205,
|
||||
204, 59,117,250,
|
||||
255, 1, 37,192};
|
||||
|
||||
|
||||
// Gradient palette "es_landscape_33_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/landscape/tn/es_landscape_33.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 24 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_landscape_33_gp ) {
|
||||
0, 1, 5, 0,
|
||||
19, 32, 23, 1,
|
||||
38, 161, 55, 1,
|
||||
63, 229,144, 1,
|
||||
66, 39,142, 74,
|
||||
255, 1, 4, 1};
|
||||
|
||||
|
||||
// Gradient palette "rainbowsherbet_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ma/icecream/tn/rainbowsherbet.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 28 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( rainbowsherbet_gp ) {
|
||||
0, 255, 33, 4,
|
||||
43, 255, 68, 25,
|
||||
86, 255, 7, 25,
|
||||
127, 255, 82,103,
|
||||
170, 255,255,242,
|
||||
209, 42,255, 22,
|
||||
255, 87,255, 65};
|
||||
|
||||
|
||||
// Gradient palette "gr65_hult_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/hult/tn/gr65_hult.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 24 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( gr65_hult_gp ) {
|
||||
0, 247,176,247,
|
||||
48, 255,136,255,
|
||||
89, 220, 29,226,
|
||||
160, 7, 82,178,
|
||||
216, 1,124,109,
|
||||
255, 1,124,109};
|
||||
|
||||
|
||||
// Gradient palette "gr64_hult_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/hult/tn/gr64_hult.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 32 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( gr64_hult_gp ) {
|
||||
0, 1,124,109,
|
||||
66, 1, 93, 79,
|
||||
104, 52, 65, 1,
|
||||
130, 115,127, 1,
|
||||
150, 52, 65, 1,
|
||||
201, 1, 86, 72,
|
||||
239, 0, 55, 45,
|
||||
255, 0, 55, 45};
|
||||
|
||||
|
||||
// Gradient palette "GMT_drywet_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/gmt/tn/GMT_drywet.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 28 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( GMT_drywet_gp ) {
|
||||
0, 47, 30, 2,
|
||||
42, 213,147, 24,
|
||||
84, 103,219, 52,
|
||||
127, 3,219,207,
|
||||
170, 1, 48,214,
|
||||
212, 1, 1,111,
|
||||
255, 1, 7, 33};
|
||||
|
||||
|
||||
// Gradient palette "ib15_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ing/general/tn/ib15.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 24 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( ib15_gp ) {
|
||||
0, 113, 91,147,
|
||||
72, 157, 88, 78,
|
||||
89, 208, 85, 33,
|
||||
107, 255, 29, 11,
|
||||
141, 137, 31, 39,
|
||||
255, 59, 33, 89};
|
||||
|
||||
|
||||
// Gradient palette "Tertiary_01_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/vermillion/tn/Tertiary_01.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Tertiary_01_gp ) {
|
||||
0, 0, 1,255,
|
||||
63, 3, 68, 45,
|
||||
127, 23,255, 0,
|
||||
191, 100, 68, 1,
|
||||
255, 255, 1, 4};
|
||||
|
||||
|
||||
// Gradient palette "lava_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/neota/elem/tn/lava.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 52 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( lava_gp ) {
|
||||
0, 0, 0, 0,
|
||||
46, 18, 0, 0,
|
||||
96, 113, 0, 0,
|
||||
108, 142, 3, 1,
|
||||
119, 175, 17, 1,
|
||||
146, 213, 44, 2,
|
||||
174, 255, 82, 4,
|
||||
188, 255,115, 4,
|
||||
202, 255,156, 4,
|
||||
218, 255,203, 4,
|
||||
234, 255,255, 4,
|
||||
244, 255,255, 71,
|
||||
255, 255,255,255};
|
||||
|
||||
|
||||
// Gradient palette "fierce_ice_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/neota/elem/tn/fierce-ice.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 28 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( fierce_ice_gp ) {
|
||||
0, 0, 0, 0,
|
||||
59, 0, 9, 45,
|
||||
119, 0, 38,255,
|
||||
149, 3,100,255,
|
||||
180, 23,199,255,
|
||||
217, 100,235,255,
|
||||
255, 255,255,255};
|
||||
|
||||
|
||||
// Gradient palette "Colorfull_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Colorfull.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 44 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Colorfull_gp ) {
|
||||
0, 10, 85, 5,
|
||||
25, 29,109, 18,
|
||||
60, 59,138, 42,
|
||||
93, 83, 99, 52,
|
||||
106, 110, 66, 64,
|
||||
109, 123, 49, 65,
|
||||
113, 139, 35, 66,
|
||||
116, 192,117, 98,
|
||||
124, 255,255,137,
|
||||
168, 100,180,155,
|
||||
255, 22,121,174};
|
||||
|
||||
|
||||
// Gradient palette "Pink_Purple_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Pink_Purple.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 44 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Pink_Purple_gp ) {
|
||||
0, 19, 2, 39,
|
||||
25, 26, 4, 45,
|
||||
51, 33, 6, 52,
|
||||
76, 68, 62,125,
|
||||
102, 118,187,240,
|
||||
109, 163,215,247,
|
||||
114, 217,244,255,
|
||||
122, 159,149,221,
|
||||
149, 113, 78,188,
|
||||
183, 128, 57,155,
|
||||
255, 146, 40,123};
|
||||
|
||||
|
||||
// Gradient palette "Sunset_Real_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 28 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) {
|
||||
0, 120, 0, 0,
|
||||
22, 179, 22, 0,
|
||||
51, 255,104, 0,
|
||||
85, 167, 22, 18,
|
||||
135, 100, 0,103,
|
||||
198, 16, 0,130,
|
||||
255, 0, 0,160};
|
||||
|
||||
|
||||
// Gradient palette "Sunset_Yellow_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Yellow.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 44 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Sunset_Yellow_gp ) {
|
||||
0, 10, 62,123,
|
||||
36, 56,130,103,
|
||||
87, 153,225, 85,
|
||||
100, 199,217, 68,
|
||||
107, 255,207, 54,
|
||||
115, 247,152, 57,
|
||||
120, 239,107, 61,
|
||||
128, 247,152, 57,
|
||||
180, 255,207, 54,
|
||||
223, 255,227, 48,
|
||||
255, 255,248, 42};
|
||||
|
||||
|
||||
// Gradient palette "Beech_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Beech.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 60 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Beech_gp ) {
|
||||
0, 255,252,214,
|
||||
12, 255,252,214,
|
||||
22, 255,252,214,
|
||||
26, 190,191,115,
|
||||
28, 137,141, 52,
|
||||
28, 112,255,205,
|
||||
50, 51,246,214,
|
||||
71, 17,235,226,
|
||||
93, 2,193,199,
|
||||
120, 0,156,174,
|
||||
133, 1,101,115,
|
||||
136, 1, 59, 71,
|
||||
136, 7,131,170,
|
||||
208, 1, 90,151,
|
||||
255, 0, 56,133};
|
||||
|
||||
|
||||
// Gradient palette "Another_Sunset_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Another_Sunset.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 32 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Another_Sunset_gp ) {
|
||||
0, 110, 49, 11,
|
||||
29, 55, 34, 10,
|
||||
68, 22, 22, 9,
|
||||
68, 239,124, 8,
|
||||
97, 220,156, 27,
|
||||
124, 203,193, 61,
|
||||
178, 33, 53, 56,
|
||||
255, 0, 1, 52};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Gradient palette "es_autumn_19_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/autumn/tn/es_autumn_19.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 52 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( es_autumn_19_gp ) {
|
||||
0, 26, 1, 1,
|
||||
51, 67, 4, 1,
|
||||
84, 118, 14, 1,
|
||||
104, 137,152, 52,
|
||||
112, 113, 65, 1,
|
||||
122, 133,149, 59,
|
||||
124, 137,152, 52,
|
||||
135, 113, 65, 1,
|
||||
142, 139,154, 46,
|
||||
163, 113, 13, 1,
|
||||
204, 55, 3, 1,
|
||||
249, 17, 1, 1,
|
||||
255, 17, 1, 1};
|
||||
|
||||
|
||||
// Gradient palette "BlacK_Blue_Magenta_White_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Blue_Magenta_White.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 28 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( BlacK_Blue_Magenta_White_gp ) {
|
||||
0, 0, 0, 0,
|
||||
42, 0, 0, 45,
|
||||
84, 0, 0,255,
|
||||
127, 42, 0,255,
|
||||
170, 255, 0,255,
|
||||
212, 255, 55,255,
|
||||
255, 255,255,255};
|
||||
|
||||
|
||||
// Gradient palette "BlacK_Magenta_Red_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Magenta_Red.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( BlacK_Magenta_Red_gp ) {
|
||||
0, 0, 0, 0,
|
||||
63, 42, 0, 45,
|
||||
127, 255, 0,255,
|
||||
191, 255, 0, 45,
|
||||
255, 255, 0, 0};
|
||||
|
||||
|
||||
// Gradient palette "BlacK_Red_Magenta_Yellow_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/BlacK_Red_Magenta_Yellow.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 28 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( BlacK_Red_Magenta_Yellow_gp ) {
|
||||
0, 0, 0, 0,
|
||||
42, 42, 0, 0,
|
||||
84, 255, 0, 0,
|
||||
127, 255, 0, 45,
|
||||
170, 255, 0,255,
|
||||
212, 255, 55, 45,
|
||||
255, 255,255, 0};
|
||||
|
||||
|
||||
// Gradient palette "Blue_Cyan_Yellow_gp", originally from
|
||||
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Blue_Cyan_Yellow.png.index.html
|
||||
// converted for FastLED with gammas (2.6, 2.2, 2.5)
|
||||
// Size: 20 bytes of program space.
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Blue_Cyan_Yellow_gp ) {
|
||||
0, 0, 0,255,
|
||||
63, 0, 55,255,
|
||||
127, 0,255,255,
|
||||
191, 42,255, 45,
|
||||
255, 255,255, 0};
|
||||
|
||||
|
||||
//Custom palette by Aircoookie
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Orange_Teal_gp ) {
|
||||
0, 0,150, 92,
|
||||
55, 0,150, 92,
|
||||
200, 255, 72, 0,
|
||||
255, 255, 72, 0};
|
||||
|
||||
//Custom palette by Aircoookie
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Tiamat_gp ) {
|
||||
0, 1, 2, 14, //gc
|
||||
33, 2, 5, 35, //gc from 47, 61,126
|
||||
100, 13,135, 92, //gc from 88,242,247
|
||||
120, 43,255,193, //gc from 135,255,253
|
||||
140, 247, 7,249, //gc from 252, 69,253
|
||||
160, 193, 17,208, //gc from 231, 96,237
|
||||
180, 39,255,154, //gc from 130, 77,213
|
||||
200, 4,213,236, //gc from 57,122,248
|
||||
220, 39,252,135, //gc from 177,254,255
|
||||
240, 193,213,253, //gc from 203,239,253
|
||||
255, 255,249,255};
|
||||
|
||||
//Custom palette by Aircoookie
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( April_Night_gp ) {
|
||||
0, 1, 5, 45, //deep blue
|
||||
10, 1, 5, 45,
|
||||
25, 5,169,175, //light blue
|
||||
40, 1, 5, 45,
|
||||
61, 1, 5, 45,
|
||||
76, 45,175, 31, //green
|
||||
91, 1, 5, 45,
|
||||
112, 1, 5, 45,
|
||||
127, 249,150, 5, //yellow
|
||||
143, 1, 5, 45,
|
||||
162, 1, 5, 45,
|
||||
178, 255,92, 0, //pastel orange
|
||||
193, 1, 5, 45,
|
||||
214, 1, 5, 45,
|
||||
229, 223, 45, 72, //pink
|
||||
244, 1, 5, 45,
|
||||
255, 1, 5, 45};
|
||||
|
||||
|
||||
// Single array of defined cpt-city color palettes.
|
||||
// This will let us programmatically choose one based on
|
||||
// a number, rather than having to activate each explicitly
|
||||
// by name every time.
|
||||
// Since it is const, this array could also be moved
|
||||
// into PROGMEM to save SRAM, but for simplicity of illustration
|
||||
// we'll keep it in a regular SRAM array.
|
||||
//
|
||||
// This list of color palettes acts as a "playlist"; you can
|
||||
// add or delete, or re-arrange as you wish.
|
||||
const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
|
||||
Sunset_Real_gp, //13-00 Sunset
|
||||
es_rivendell_15_gp, //14-01 Rivendell
|
||||
es_ocean_breeze_036_gp, //15-02 Breeze
|
||||
rgi_15_gp, //16-03 Red & Blue
|
||||
retro2_16_gp, //17-04 Yellowout
|
||||
Analogous_1_gp, //18-05 Analogous
|
||||
es_pinksplash_08_gp, //19-06 Splash
|
||||
Sunset_Yellow_gp, //20-07 Pastel
|
||||
Another_Sunset_gp, //21-08 Sunset2
|
||||
Beech_gp, //22-09 Beech
|
||||
es_vintage_01_gp, //23-10 Vintage
|
||||
departure_gp, //24-11 Departure
|
||||
es_landscape_64_gp, //25-12 Landscape
|
||||
es_landscape_33_gp, //26-13 Beach
|
||||
rainbowsherbet_gp, //27-14 Sherbet
|
||||
gr65_hult_gp, //28-15 Hult
|
||||
gr64_hult_gp, //29-16 Hult64
|
||||
GMT_drywet_gp, //30-17 Drywet
|
||||
ib_jul01_gp, //31-18 Jul
|
||||
es_vintage_57_gp, //32-19 Grintage
|
||||
ib15_gp, //33-20 Rewhi
|
||||
Tertiary_01_gp, //34-21 Tertiary
|
||||
lava_gp, //35-22 Fire
|
||||
fierce_ice_gp, //36-23 Icefire
|
||||
Colorfull_gp, //37-24 Cyane
|
||||
Pink_Purple_gp, //38-25 Light Pink
|
||||
es_autumn_19_gp, //39-26 Autumn
|
||||
BlacK_Blue_Magenta_White_gp, //40-27 Magenta
|
||||
BlacK_Magenta_Red_gp, //41-28 Magred
|
||||
BlacK_Red_Magenta_Yellow_gp, //42-29 Yelmag
|
||||
Blue_Cyan_Yellow_gp, //43-30 Yelblu
|
||||
Orange_Teal_gp, //44-31 Orange & Teal
|
||||
Tiamat_gp, //45-32 Tiamat
|
||||
April_Night_gp //46-33 April Night
|
||||
};
|
||||
|
||||
|
||||
// Count of how many cpt-city gradients are defined:
|
||||
const uint8_t gGradientPaletteCount =
|
||||
sizeof( gGradientPalettes) / sizeof( TProgmemRGBGradientPalettePtr );
|
||||
|
||||
#endif
|
||||
321
wled00/src/dependencies/blynk/Blynk/BlynkApi.h
Normal file
321
wled00/src/dependencies/blynk/Blynk/BlynkApi.h
Normal file
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
* @file BlynkApi.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief High-level functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkApi_h
|
||||
#define BlynkApi_h
|
||||
|
||||
#include "BlynkConfig.h"
|
||||
#include "BlynkDebug.h"
|
||||
#include "BlynkParam.h"
|
||||
#include "BlynkTimer.h"
|
||||
#include "BlynkHandlers.h"
|
||||
#include "BlynkProtocolDefs.h"
|
||||
|
||||
#if defined(BLYNK_EXPERIMENTAL)
|
||||
#include <Blynk/BlynkEveryN.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Represents high-level functions of Blynk
|
||||
*/
|
||||
template <class Proto>
|
||||
class BlynkApi
|
||||
{
|
||||
public:
|
||||
BlynkApi() {
|
||||
}
|
||||
|
||||
#ifdef DOXYGEN // These API here are only for the documentation
|
||||
|
||||
/**
|
||||
* Connects to the server.
|
||||
* Blocks until connected or timeout happens.
|
||||
* May take less or more then timeout value.
|
||||
*
|
||||
* @param timeout Connection timeout
|
||||
* @returns True if connected to the server
|
||||
*/
|
||||
bool connect(unsigned long timeout = BLYNK_TIMEOUT_MS*3);
|
||||
|
||||
/**
|
||||
* Disconnects from the server.
|
||||
* It will not try to reconnect, until connect() is called
|
||||
*/
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* @returns True if connected to the server
|
||||
*/
|
||||
bool connected();
|
||||
|
||||
/**
|
||||
* Performs Blynk-related housekeeping
|
||||
* and processes incoming commands
|
||||
*
|
||||
* @param available True if there is incoming data to process
|
||||
* Only used when user manages connection manually.
|
||||
*/
|
||||
bool run(bool available = false);
|
||||
|
||||
#endif // DOXYGEN
|
||||
|
||||
/**
|
||||
* Sends value to a Virtual Pin
|
||||
*
|
||||
* @param pin Virtual Pin number
|
||||
* @param data Value to be sent
|
||||
*/
|
||||
template <typename... Args>
|
||||
void virtualWrite(int pin, Args... values) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add("vw");
|
||||
cmd.add(pin);
|
||||
cmd.add_multi(values...);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends buffer to a Virtual Pin
|
||||
*
|
||||
* @param pin Virtual Pin number
|
||||
* @param buff Data buffer
|
||||
* @param len Length of data
|
||||
*/
|
||||
void virtualWriteBinary(int pin, const void* buff, size_t len) {
|
||||
char mem[8];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add("vw");
|
||||
cmd.add(pin);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE, 0, cmd.getBuffer(), cmd.getLength(), buff, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends BlynkParam to a Virtual Pin
|
||||
*
|
||||
* @param pin Virtual Pin number
|
||||
* @param param
|
||||
*/
|
||||
void virtualWrite(int pin, const BlynkParam& param) {
|
||||
virtualWriteBinary(pin, param.getBuffer(), param.getLength());
|
||||
}
|
||||
|
||||
void virtualWrite(int pin, const BlynkParamAllocated& param) {
|
||||
virtualWriteBinary(pin, param.getBuffer(), param.getLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests Server to re-send current values for all widgets.
|
||||
*/
|
||||
void syncAll() {
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE_SYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends internal command
|
||||
*/
|
||||
template <typename... Args>
|
||||
void sendInternal(Args... params) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add_multi(params...);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_INTERNAL, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests App or Server to re-send current value of a Virtual Pin.
|
||||
* This will probably cause user-defined BLYNK_WRITE handler to be called.
|
||||
*
|
||||
* @param pin Virtual Pin number
|
||||
*/
|
||||
template <typename... Args>
|
||||
void syncVirtual(Args... pins) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add("vr");
|
||||
cmd.add_multi(pins...);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE_SYNC, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tweets a message
|
||||
*
|
||||
* @param msg Text of the message
|
||||
*/
|
||||
template<typename T>
|
||||
void tweet(const T& msg) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(msg);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_TWEET, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a push notification to the App
|
||||
*
|
||||
* @param msg Text of the message
|
||||
*/
|
||||
template<typename T>
|
||||
void notify(const T& msg) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(msg);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_NOTIFY, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an SMS
|
||||
*
|
||||
* @param msg Text of the message
|
||||
*/
|
||||
template<typename T>
|
||||
void sms(const T& msg) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(msg);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_SMS, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an email message
|
||||
*
|
||||
* @param email Email to send to
|
||||
* @param subject Subject of message
|
||||
* @param msg Text of the message
|
||||
*/
|
||||
template <typename T1, typename T2>
|
||||
void email(const char* email, const T1& subject, const T2& msg) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(email);
|
||||
cmd.add(subject);
|
||||
cmd.add(msg);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_EMAIL, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an email message
|
||||
*
|
||||
* @param subject Subject of message
|
||||
* @param msg Text of the message
|
||||
*/
|
||||
template <typename T1, typename T2>
|
||||
void email(const T1& subject, const T2& msg) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(subject);
|
||||
cmd.add(msg);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_EMAIL, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets property of a Widget
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @param pin Virtual Pin number
|
||||
* @param property Property name ("label", "labels", "color", ...)
|
||||
* @param value Property value
|
||||
*/
|
||||
template <typename T, typename... Args>
|
||||
void setProperty(int pin, const T& property, Args... values) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(pin);
|
||||
cmd.add(property);
|
||||
cmd.add_multi(values...);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_PROPERTY, 0, cmd.getBuffer(), cmd.getLength()-1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void setProperty(int pin, const T& property, const BlynkParam& param) {
|
||||
char mem[32];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(pin);
|
||||
cmd.add(property);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_PROPERTY, 0, cmd.getBuffer(), cmd.getLength(), param.getBuffer(), param.getLength());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void setProperty(int pin, const T& property, const BlynkParamAllocated& param) {
|
||||
char mem[32];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(pin);
|
||||
cmd.add(property);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_PROPERTY, 0, cmd.getBuffer(), cmd.getLength(), param.getBuffer(), param.getLength());
|
||||
}
|
||||
|
||||
template <typename NAME>
|
||||
void logEvent(const NAME& event_name) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(event_name);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_EVENT_LOG, 0, cmd.getBuffer(), cmd.getLength());
|
||||
}
|
||||
|
||||
template <typename NAME, typename DESCR>
|
||||
void logEvent(const NAME& event_name, const DESCR& description) {
|
||||
char mem[BLYNK_MAX_SENDBYTES];
|
||||
BlynkParam cmd(mem, 0, sizeof(mem));
|
||||
cmd.add(event_name);
|
||||
cmd.add(description);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_EVENT_LOG, 0, cmd.getBuffer(), cmd.getLength());
|
||||
}
|
||||
|
||||
#if defined(BLYNK_EXPERIMENTAL)
|
||||
// Attention!
|
||||
// Every function in this section may be changed, removed or renamed.
|
||||
|
||||
/**
|
||||
* Refreshes value of a widget by running
|
||||
* user-defined BLYNK_READ handler of a pin.
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @param pin Virtual Pin number
|
||||
*/
|
||||
void refresh(int pin) {
|
||||
if (WidgetReadHandler handler = GetReadHandler(pin)) {
|
||||
BlynkReq req = { 0, BLYNK_SUCCESS, (uint8_t)pin };
|
||||
handler(req);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delays for N milliseconds, handling server communication in background.
|
||||
*
|
||||
* @experimental
|
||||
* @warning Should be used very carefully, especially on platforms with small RAM.
|
||||
*
|
||||
* @param ms Milliseconds to wait
|
||||
*/
|
||||
void delay(unsigned long ms) {
|
||||
uint16_t start = (uint16_t)micros();
|
||||
while (ms > 0) {
|
||||
static_cast<Proto*>(this)->run();
|
||||
#if !defined(BLYNK_NO_YIELD)
|
||||
yield();
|
||||
#endif
|
||||
if (((uint16_t)micros() - start) >= 1000) {
|
||||
ms--;
|
||||
start += 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void processCmd(const void* buff, size_t len);
|
||||
void sendInfo();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
199
wled00/src/dependencies/blynk/Blynk/BlynkApiArduino.h
Normal file
199
wled00/src/dependencies/blynk/Blynk/BlynkApiArduino.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @file BlynkApiArduino.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Mar 2015
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkApiArduino_h
|
||||
#define BlynkApiArduino_h
|
||||
|
||||
#include "BlynkApi.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef BLYNK_NO_INFO
|
||||
|
||||
template<class Proto>
|
||||
BLYNK_FORCE_INLINE
|
||||
void BlynkApi<Proto>::sendInfo() {}
|
||||
|
||||
#else
|
||||
|
||||
template<class Proto>
|
||||
BLYNK_FORCE_INLINE
|
||||
void BlynkApi<Proto>::sendInfo()
|
||||
{
|
||||
static const char profile[] BLYNK_PROGMEM = "blnkinf\0"
|
||||
#ifdef BOARD_FIRMWARE_VERSION
|
||||
BLYNK_PARAM_KV("ver" , BOARD_FIRMWARE_VERSION)
|
||||
BLYNK_PARAM_KV("blynk" , BLYNK_VERSION)
|
||||
#else
|
||||
BLYNK_PARAM_KV("ver" , BLYNK_VERSION)
|
||||
#endif
|
||||
#ifdef BOARD_TEMPLATE_ID
|
||||
BLYNK_PARAM_KV("tmpl" , BOARD_TEMPLATE_ID)
|
||||
#endif
|
||||
BLYNK_PARAM_KV("h-beat" , BLYNK_TOSTRING(BLYNK_HEARTBEAT))
|
||||
BLYNK_PARAM_KV("buff-in", BLYNK_TOSTRING(BLYNK_MAX_READBYTES))
|
||||
#ifdef BLYNK_INFO_DEVICE
|
||||
BLYNK_PARAM_KV("dev" , BLYNK_INFO_DEVICE)
|
||||
#endif
|
||||
#ifdef BLYNK_INFO_CPU
|
||||
BLYNK_PARAM_KV("cpu" , BLYNK_INFO_CPU)
|
||||
#endif
|
||||
#ifdef BLYNK_INFO_CONNECTION
|
||||
BLYNK_PARAM_KV("con" , BLYNK_INFO_CONNECTION)
|
||||
#endif
|
||||
BLYNK_PARAM_KV("build" , __DATE__ " " __TIME__)
|
||||
"\0"
|
||||
;
|
||||
const size_t profile_len = sizeof(profile)-8-2;
|
||||
|
||||
#ifdef BLYNK_HAS_PROGMEM
|
||||
char mem[profile_len];
|
||||
memcpy_P(mem, profile+8, profile_len);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_INTERNAL, 0, mem, profile_len);
|
||||
#else
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_INTERNAL, 0, profile+8, profile_len);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Check if analog pins can be referenced by name on this device
|
||||
#if defined(analogInputToDigitalPin)
|
||||
#define BLYNK_DECODE_PIN(it) (((it).asStr()[0] == 'A') ? analogInputToDigitalPin(atoi((it).asStr()+1)) : (it).asInt())
|
||||
#else
|
||||
#define BLYNK_DECODE_PIN(it) ((it).asInt())
|
||||
|
||||
#if defined(BLYNK_DEBUG_ALL)
|
||||
#pragma message "analogInputToDigitalPin not defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<class Proto>
|
||||
BLYNK_FORCE_INLINE
|
||||
void BlynkApi<Proto>::processCmd(const void* buff, size_t len)
|
||||
{
|
||||
BlynkParam param((void*)buff, len);
|
||||
BlynkParam::iterator it = param.begin();
|
||||
if (it >= param.end())
|
||||
return;
|
||||
const char* cmd = it.asStr();
|
||||
uint16_t cmd16;
|
||||
memcpy(&cmd16, cmd, sizeof(cmd16));
|
||||
if (++it >= param.end())
|
||||
return;
|
||||
|
||||
uint8_t pin = BLYNK_DECODE_PIN(it);
|
||||
|
||||
switch(cmd16) {
|
||||
|
||||
#ifndef BLYNK_NO_BUILTIN
|
||||
|
||||
case BLYNK_HW_PM: {
|
||||
while (it < param.end()) {
|
||||
pin = BLYNK_DECODE_PIN(it);
|
||||
++it;
|
||||
if (!strcmp(it.asStr(), "in")) {
|
||||
pinMode(pin, INPUT);
|
||||
} else if (!strcmp(it.asStr(), "out") || !strcmp(it.asStr(), "pwm")) {
|
||||
pinMode(pin, OUTPUT);
|
||||
#ifdef INPUT_PULLUP
|
||||
} else if (!strcmp(it.asStr(), "pu")) {
|
||||
pinMode(pin, INPUT_PULLUP);
|
||||
#endif
|
||||
#ifdef INPUT_PULLDOWN
|
||||
} else if (!strcmp(it.asStr(), "pd")) {
|
||||
pinMode(pin, INPUT_PULLDOWN);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG4(BLYNK_F("Invalid pin "), pin, BLYNK_F(" mode "), it.asStr());
|
||||
#endif
|
||||
}
|
||||
++it;
|
||||
}
|
||||
} break;
|
||||
case BLYNK_HW_DR: {
|
||||
char mem[16];
|
||||
BlynkParam rsp(mem, 0, sizeof(mem));
|
||||
rsp.add("dw");
|
||||
rsp.add(pin);
|
||||
rsp.add(digitalRead(pin));
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE, 0, rsp.getBuffer(), rsp.getLength()-1);
|
||||
} break;
|
||||
case BLYNK_HW_DW: {
|
||||
// Should be 1 parameter (value)
|
||||
if (++it >= param.end())
|
||||
return;
|
||||
|
||||
#ifdef ESP8266
|
||||
// Disable PWM...
|
||||
analogWrite(pin, 0);
|
||||
#endif
|
||||
#ifndef BLYNK_MINIMIZE_PINMODE_USAGE
|
||||
pinMode(pin, OUTPUT);
|
||||
#endif
|
||||
digitalWrite(pin, it.asInt() ? HIGH : LOW);
|
||||
} break;
|
||||
case BLYNK_HW_AR: {
|
||||
char mem[16];
|
||||
BlynkParam rsp(mem, 0, sizeof(mem));
|
||||
rsp.add("aw");
|
||||
rsp.add(pin);
|
||||
rsp.add(analogRead(pin));
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_HARDWARE, 0, rsp.getBuffer(), rsp.getLength()-1);
|
||||
} break;
|
||||
|
||||
// TODO: Remove workaround for ESP32
|
||||
#if !defined(ESP32)
|
||||
|
||||
case BLYNK_HW_AW: {
|
||||
// Should be 1 parameter (value)
|
||||
if (++it >= param.end())
|
||||
return;
|
||||
|
||||
#ifndef BLYNK_MINIMIZE_PINMODE_USAGE
|
||||
pinMode(pin, OUTPUT);
|
||||
#endif
|
||||
analogWrite(pin, it.asInt());
|
||||
} break;
|
||||
|
||||
#endif // TODO: Remove workaround for ESP32
|
||||
|
||||
#endif
|
||||
|
||||
case BLYNK_HW_VR: {
|
||||
BlynkReq req = { pin };
|
||||
WidgetReadHandler handler = GetReadHandler(pin);
|
||||
if (handler && (handler != BlynkWidgetRead)) {
|
||||
handler(req);
|
||||
} else {
|
||||
BlynkWidgetReadDefault(req);
|
||||
}
|
||||
} break;
|
||||
case BLYNK_HW_VW: {
|
||||
++it;
|
||||
char* start = (char*)it.asStr();
|
||||
BlynkParam param2(start, len - (start - (char*)buff));
|
||||
BlynkReq req = { pin };
|
||||
WidgetWriteHandler handler = GetWriteHandler(pin);
|
||||
if (handler && (handler != BlynkWidgetWrite)) {
|
||||
handler(req, param2);
|
||||
} else {
|
||||
BlynkWidgetWriteDefault(req, param2);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
BLYNK_LOG2(BLYNK_F("Invalid HW cmd: "), cmd);
|
||||
static_cast<Proto*>(this)->sendCmd(BLYNK_CMD_RESPONSE, static_cast<Proto*>(this)->msgIdOutOverride, NULL, BLYNK_ILLEGAL_COMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
128
wled00/src/dependencies/blynk/Blynk/BlynkArduinoClient.h
Normal file
128
wled00/src/dependencies/blynk/Blynk/BlynkArduinoClient.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* @file BlynkParam.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkArduinoClient_h
|
||||
#define BlynkArduinoClient_h
|
||||
|
||||
#include "BlynkApiArduino.h"
|
||||
#include "BlynkDebug.h"
|
||||
#include <Client.h>
|
||||
|
||||
#if defined(ESP8266) && !defined(BLYNK_NO_YIELD)
|
||||
#define YIELD_FIX() BLYNK_RUN_YIELD();
|
||||
#else
|
||||
#define YIELD_FIX()
|
||||
#endif
|
||||
|
||||
template <typename Client>
|
||||
class BlynkArduinoClientGen
|
||||
{
|
||||
public:
|
||||
BlynkArduinoClientGen(Client& c)
|
||||
: client(NULL), domain(NULL), port(0), isConn(false)
|
||||
{
|
||||
setClient(&c);
|
||||
}
|
||||
|
||||
BlynkArduinoClientGen()
|
||||
: client(NULL), domain(NULL), port(0), isConn(false)
|
||||
{}
|
||||
|
||||
void setClient(Client* c) {
|
||||
client = c;
|
||||
client->setTimeout(BLYNK_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
void begin(IPAddress a, uint16_t p) {
|
||||
domain = NULL;
|
||||
port = p;
|
||||
addr = a;
|
||||
}
|
||||
|
||||
void begin(const char* d, uint16_t p) {
|
||||
domain = d;
|
||||
port = p;
|
||||
}
|
||||
|
||||
bool connect() {
|
||||
if (domain) {
|
||||
BLYNK_LOG4(BLYNK_F("Connecting to "), domain, ':', port);
|
||||
|
||||
isConn = (1 == client->connect(domain, port));
|
||||
return isConn;
|
||||
} else { //if (uint32_t(addr) != 0) {
|
||||
BLYNK_LOG_IP("Connecting to ", addr);
|
||||
isConn = (1 == client->connect(addr, port));
|
||||
return isConn;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void disconnect() { isConn = false; client->stop(); }
|
||||
|
||||
#ifdef BLYNK_ENC28J60_FIX
|
||||
size_t read(void* buf, size_t len) {
|
||||
while (client->available() < len) { BLYNK_RUN_YIELD(); }
|
||||
return client->read((uint8_t*)buf, len);
|
||||
}
|
||||
#else
|
||||
size_t read(void* buf, size_t len) {
|
||||
size_t res = client->readBytes((char*)buf, len);
|
||||
YIELD_FIX();
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BLYNK_RETRY_SEND
|
||||
size_t write(const void* buf, size_t len) {
|
||||
size_t sent = 0;
|
||||
int retry = 0;
|
||||
while (sent < len && ++retry < 10) {
|
||||
size_t w = client->write((const uint8_t*)buf+sent, len-sent);
|
||||
if (w != 0 && w != -1) {
|
||||
sent += w;
|
||||
} else {
|
||||
BlynkDelay(50);
|
||||
#if defined(BLYNK_DEBUG) && defined(BLYNK_PRINT)
|
||||
BLYNK_PRINT_TIME();
|
||||
BLYNK_PRINT.print(BLYNK_F("Retry "));
|
||||
BLYNK_PRINT.print(retry);
|
||||
BLYNK_PRINT.print(BLYNK_F(" send: "));
|
||||
BLYNK_PRINT.print(sent);
|
||||
BLYNK_PRINT.print('/');
|
||||
BLYNK_PRINT.println(len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
#else
|
||||
size_t write(const void* buf, size_t len) {
|
||||
YIELD_FIX();
|
||||
size_t res = client->write((const uint8_t*)buf, len);
|
||||
YIELD_FIX();
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool connected() { YIELD_FIX(); return isConn && client->connected(); }
|
||||
int available() { YIELD_FIX(); return client->available(); }
|
||||
|
||||
protected:
|
||||
Client* client;
|
||||
IPAddress addr;
|
||||
const char* domain;
|
||||
uint16_t port;
|
||||
bool isConn;
|
||||
};
|
||||
|
||||
typedef BlynkArduinoClientGen<Client> BlynkArduinoClient;
|
||||
|
||||
#endif
|
||||
95
wled00/src/dependencies/blynk/Blynk/BlynkConfig.h
Normal file
95
wled00/src/dependencies/blynk/Blynk/BlynkConfig.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file BlynkConfig.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Configuration of different aspects of library
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkConfig_h
|
||||
#define BlynkConfig_h
|
||||
|
||||
#include "BlynkDetectDevice.h"
|
||||
|
||||
/***************************************************
|
||||
* Change these settings to match your need
|
||||
***************************************************/
|
||||
|
||||
#define BLYNK_DEFAULT_DOMAIN "blynk-cloud.com"
|
||||
#define BLYNK_DEFAULT_PORT 80
|
||||
#define BLYNK_DEFAULT_PORT_SSL 8441
|
||||
|
||||
/***************************************************
|
||||
* Professional settings
|
||||
***************************************************/
|
||||
// Library version.
|
||||
#define BLYNK_VERSION "0.5.3"
|
||||
|
||||
// Heartbeat period in seconds.
|
||||
#ifndef BLYNK_HEARTBEAT
|
||||
#define BLYNK_HEARTBEAT 10
|
||||
#endif
|
||||
|
||||
// Network timeout in milliseconds.
|
||||
#ifndef BLYNK_TIMEOUT_MS
|
||||
#define BLYNK_TIMEOUT_MS 2000UL
|
||||
#endif
|
||||
|
||||
// Limit the amount of outgoing commands per second.
|
||||
#ifndef BLYNK_MSG_LIMIT
|
||||
#define BLYNK_MSG_LIMIT 15
|
||||
#endif
|
||||
|
||||
// Limit the incoming command length.
|
||||
#ifndef BLYNK_MAX_READBYTES
|
||||
#define BLYNK_MAX_READBYTES 256
|
||||
#endif
|
||||
|
||||
// Limit the outgoing command length.
|
||||
#ifndef BLYNK_MAX_SENDBYTES
|
||||
#define BLYNK_MAX_SENDBYTES 128
|
||||
#endif
|
||||
|
||||
// Uncomment to use Let's Encrypt Root CA
|
||||
//#define BLYNK_SSL_USE_LETSENCRYPT
|
||||
|
||||
// Uncomment to disable built-in analog and digital operations.
|
||||
//#define BLYNK_NO_BUILTIN
|
||||
|
||||
// Uncomment to disable providing info about device to the server.
|
||||
//#define BLYNK_NO_INFO
|
||||
|
||||
// Uncomment to enable debug prints.
|
||||
//#define BLYNK_DEBUG
|
||||
|
||||
// Uncomment to force-enable 128 virtual pins
|
||||
//#define BLYNK_USE_128_VPINS
|
||||
|
||||
// Uncomment to disable fancy logo
|
||||
//#define BLYNK_NO_FANCY_LOGO
|
||||
|
||||
// Uncomment to enable 3D fancy logo
|
||||
//#define BLYNK_FANCY_LOGO_3D
|
||||
|
||||
// Uncomment to enable experimental functions.
|
||||
//#define BLYNK_EXPERIMENTAL
|
||||
|
||||
// Uncomment to disable all float/double usage
|
||||
//#define BLYNK_NO_FLOAT
|
||||
|
||||
// Uncomment to switch to direct-connect mode
|
||||
//#define BLYNK_USE_DIRECT_CONNECT
|
||||
|
||||
|
||||
// Uncomment to append command body to header (uses more RAM)
|
||||
//#define BLYNK_SEND_ATOMIC
|
||||
|
||||
// Split whole command into chunks (in bytes)
|
||||
//#define BLYNK_SEND_CHUNK 64
|
||||
|
||||
// Wait after sending each chunk (in milliseconds)
|
||||
//#define BLYNK_SEND_THROTTLE 10
|
||||
|
||||
#endif
|
||||
173
wled00/src/dependencies/blynk/Blynk/BlynkDateTime.h
Normal file
173
wled00/src/dependencies/blynk/Blynk/BlynkDateTime.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* @file BlynkDateTime.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
||||
* @date Aug 2016
|
||||
* @brief DateTime implementation
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkDateTime_h
|
||||
#define BlynkDateTime_h
|
||||
|
||||
typedef long blynk_time_t;
|
||||
|
||||
struct blynk_tm *blynk_gmtime_r(const blynk_time_t *time, struct blynk_tm *tm);
|
||||
blynk_time_t blynk_mk_gmtime(struct blynk_tm *tm);
|
||||
|
||||
struct blynk_tm {
|
||||
int8_t tm_sec;
|
||||
int8_t tm_min;
|
||||
int8_t tm_hour;
|
||||
int8_t tm_mday;
|
||||
int8_t tm_wday;
|
||||
int8_t tm_mon;
|
||||
int16_t tm_year;
|
||||
int16_t tm_yday;
|
||||
int16_t tm_isdst;
|
||||
};
|
||||
|
||||
class BlynkTime {
|
||||
|
||||
public:
|
||||
static const uint32_t MAX_TIME = 86400L;
|
||||
|
||||
BlynkTime() : mTime(-1) {}
|
||||
|
||||
BlynkTime(const BlynkTime& t) : mTime(t.mTime) {}
|
||||
|
||||
BlynkTime(long seconds) : mTime(seconds % MAX_TIME) {}
|
||||
|
||||
BlynkTime(int hour, int minute, int second)
|
||||
{
|
||||
mTime = (hour * 3600 + minute * 60 + second) % MAX_TIME;
|
||||
}
|
||||
|
||||
int second() const { return mTime % 60; }
|
||||
int minute() const { return (mTime / 60) % 60; }
|
||||
int hour() const { return mTime / 3600; }
|
||||
|
||||
int hour12() const {
|
||||
int h = hour();
|
||||
if (h == 0)
|
||||
return 12; // 12 midnight
|
||||
else if (h > 12)
|
||||
return h - 12;
|
||||
return h;
|
||||
}
|
||||
|
||||
bool isAM() const { return !isPM(); }
|
||||
bool isPM() const { return (hour() >= 12); }
|
||||
|
||||
void adjustSeconds(int sec) {
|
||||
if (isValid()) {
|
||||
mTime = (mTime + sec) % MAX_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
blynk_time_t getUnixOffset() const { return mTime; }
|
||||
|
||||
bool isValid() const { return mTime < MAX_TIME; }
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
bool operator == (const BlynkTime& t) const { return mTime == t.mTime; }
|
||||
bool operator >= (const BlynkTime& t) const { return mTime >= t.mTime; }
|
||||
bool operator <= (const BlynkTime& t) const { return mTime <= t.mTime; }
|
||||
bool operator > (const BlynkTime& t) const { return mTime > t.mTime; }
|
||||
bool operator < (const BlynkTime& t) const { return mTime < t.mTime; }
|
||||
|
||||
private:
|
||||
uint32_t mTime;
|
||||
};
|
||||
|
||||
class BlynkDateTime {
|
||||
|
||||
public:
|
||||
BlynkDateTime() : mTime(0) {}
|
||||
|
||||
BlynkDateTime(const BlynkDateTime& t)
|
||||
{
|
||||
mTime = t.mTime;
|
||||
blynk_gmtime_r(&mTime, &mTm);
|
||||
}
|
||||
|
||||
BlynkDateTime(blynk_time_t t)
|
||||
{
|
||||
mTime = t;
|
||||
blynk_gmtime_r(&mTime, &mTm);
|
||||
}
|
||||
|
||||
BlynkDateTime(int hour, int minute, int second, int day, int month, int year)
|
||||
{
|
||||
mTm.tm_hour = hour;
|
||||
mTm.tm_min = minute;
|
||||
mTm.tm_sec = second;
|
||||
|
||||
mTm.tm_mday = day;
|
||||
mTm.tm_mon = month - 1;
|
||||
mTm.tm_year = year - 1900;
|
||||
|
||||
mTm.tm_isdst = 0;
|
||||
|
||||
mTime = blynk_mk_gmtime(&mTm);
|
||||
}
|
||||
|
||||
int second() const { return mTm.tm_sec; }
|
||||
int minute() const { return mTm.tm_min; }
|
||||
int hour() const { return mTm.tm_hour; }
|
||||
int day() const { return mTm.tm_mday; }
|
||||
int month() const { return 1 + mTm.tm_mon; }
|
||||
int year() const { return 1900 + mTm.tm_year; }
|
||||
|
||||
int day_of_year() const { return 1 + mTm.tm_yday; }
|
||||
int day_of_week() const { return mTm.tm_wday == 0 ? 7 : mTm.tm_wday; }
|
||||
|
||||
/*int weak_of_year() const {
|
||||
int julian = day_of_year();
|
||||
int dow = day_of_week();
|
||||
int dowJan1 = BlynkDateTime(0,0,0, 1,1,year()).day_of_week();
|
||||
int weekNum = ((julian + 6) / 7);
|
||||
if (dow < dowJan1)
|
||||
++weekNum;
|
||||
return (weekNum);
|
||||
}*/
|
||||
|
||||
int hour12() const {
|
||||
int h = hour();
|
||||
if (h == 0)
|
||||
return 12; // 12 midnight
|
||||
else if (h > 12)
|
||||
return h - 12;
|
||||
return h;
|
||||
}
|
||||
|
||||
bool isAM() const { return !isPM(); }
|
||||
bool isPM() const { return (hour() >= 12); }
|
||||
|
||||
void adjustSeconds(int sec) {
|
||||
if (isValid()) {
|
||||
mTime += sec;
|
||||
blynk_gmtime_r(&mTime, &mTm);
|
||||
}
|
||||
}
|
||||
|
||||
//tm& getTm() { return mTm; }
|
||||
blynk_time_t getUnix() const { return mTime; }
|
||||
|
||||
bool isValid() const { return mTime != 0; }
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
bool operator == (const BlynkDateTime& t) const { return mTime == t.mTime; }
|
||||
bool operator >= (const BlynkDateTime& t) const { return mTime >= t.mTime; }
|
||||
bool operator <= (const BlynkDateTime& t) const { return mTime <= t.mTime; }
|
||||
bool operator > (const BlynkDateTime& t) const { return mTime > t.mTime; }
|
||||
bool operator < (const BlynkDateTime& t) const { return mTime < t.mTime; }
|
||||
|
||||
private:
|
||||
blynk_tm mTm;
|
||||
blynk_time_t mTime;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
278
wled00/src/dependencies/blynk/Blynk/BlynkDebug.cpp
Normal file
278
wled00/src/dependencies/blynk/Blynk/BlynkDebug.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/**
|
||||
* @file BlynkDebug.cpp
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Debug utilities for Arduino
|
||||
*/
|
||||
#include "BlynkDebug.h"
|
||||
|
||||
#if defined(ARDUINO) && defined(__AVR__) && defined(BLYNK_USE_AVR_WDT)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
BLYNK_CONSTRUCTOR
|
||||
static void BlynkSystemInit()
|
||||
{
|
||||
MCUSR = 0;
|
||||
wdt_disable();
|
||||
}
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
wdt_enable(WDTO_15MS);
|
||||
delay(50);
|
||||
void(*resetFunc)(void) = 0;
|
||||
resetFunc();
|
||||
for(;;) {} // To make compiler happy
|
||||
}
|
||||
|
||||
size_t BlynkFreeRam()
|
||||
{
|
||||
extern int __heap_start, *__brkval;
|
||||
int v;
|
||||
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined(ARDUINO) && defined(__AVR__)
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
void(*resetFunc)(void) = 0;
|
||||
resetFunc();
|
||||
for(;;) {}
|
||||
}
|
||||
|
||||
size_t BlynkFreeRam()
|
||||
{
|
||||
extern int __heap_start, *__brkval;
|
||||
int v;
|
||||
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined(ARDUINO) && defined(ESP8266)
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
size_t BlynkFreeRam()
|
||||
{
|
||||
return ESP.getFreeHeap();
|
||||
}
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
ESP.restart();
|
||||
for(;;) {}
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
size_t BlynkFreeRam()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
for(;;) {}
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined (ARDUINO_ARCH_ARC32)
|
||||
|
||||
millis_time_t BlynkMillis()
|
||||
{
|
||||
// TODO: Remove workaround for Intel Curie
|
||||
// https://forum.arduino.cc/index.php?topic=391836.0
|
||||
noInterrupts();
|
||||
uint64_t t = millis();
|
||||
interrupts();
|
||||
return t;
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
#define _BLYNK_USE_DEFAULT_RESET
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined(ARDUINO) && (defined(__STM32F1__) || defined(__STM32F3__))
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <libmaple/nvic.h>
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
nvic_sys_reset();
|
||||
for(;;) {}
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined (PARTICLE) || defined(SPARK)
|
||||
|
||||
#include "application.h"
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
System.reset();
|
||||
for(;;) {} // To make compiler happy
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined(__MBED__)
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
static Timer blynk_millis_timer;
|
||||
static Ticker blynk_waker;
|
||||
|
||||
static
|
||||
void blynk_wake() {
|
||||
//pc.puts("(...)");
|
||||
}
|
||||
|
||||
BLYNK_CONSTRUCTOR
|
||||
static void BlynkSystemInit()
|
||||
{
|
||||
blynk_waker.attach(&blynk_wake, 2.0);
|
||||
blynk_millis_timer.start();
|
||||
}
|
||||
|
||||
void BlynkDelay(millis_time_t ms)
|
||||
{
|
||||
wait_ms(ms);
|
||||
}
|
||||
|
||||
millis_time_t BlynkMillis()
|
||||
{
|
||||
return blynk_millis_timer.read_ms();
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
#define _BLYNK_USE_DEFAULT_RESET
|
||||
|
||||
#elif defined(LINUX) && defined(RASPBERRY)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <wiringPi.h>
|
||||
|
||||
BLYNK_CONSTRUCTOR
|
||||
static void BlynkSystemInit()
|
||||
{
|
||||
wiringPiSetupGpio();
|
||||
}
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
exit(1);
|
||||
for(;;) {} // To make compiler happy
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#elif defined(LINUX)
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static millis_time_t blynk_startup_time = 0;
|
||||
|
||||
BLYNK_CONSTRUCTOR
|
||||
static void BlynkSystemInit()
|
||||
{
|
||||
blynk_startup_time = BlynkMillis();
|
||||
}
|
||||
|
||||
void BlynkReset()
|
||||
{
|
||||
exit(1);
|
||||
for(;;) {} // To make compiler happy
|
||||
}
|
||||
|
||||
void BlynkDelay(millis_time_t ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
millis_time_t BlynkMillis()
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts );
|
||||
return ( ts.tv_sec * 1000 + ts.tv_nsec / 1000000L ) - blynk_startup_time;
|
||||
}
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
|
||||
#else
|
||||
|
||||
#if defined(BLYNK_DEBUG_ALL)
|
||||
#warning "Need to implement board-specific utilities"
|
||||
#endif
|
||||
|
||||
#define _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
#define _BLYNK_USE_DEFAULT_RESET
|
||||
#define _BLYNK_USE_DEFAULT_MILLIS
|
||||
#define _BLYNK_USE_DEFAULT_DELAY
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _BLYNK_USE_DEFAULT_DELAY
|
||||
void BlynkDelay(millis_time_t ms)
|
||||
{
|
||||
return delay(ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _BLYNK_USE_DEFAULT_MILLIS
|
||||
millis_time_t BlynkMillis()
|
||||
{
|
||||
return millis();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _BLYNK_USE_DEFAULT_FREE_RAM
|
||||
size_t BlynkFreeRam()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _BLYNK_USE_DEFAULT_RESET
|
||||
void BlynkReset()
|
||||
{
|
||||
for(;;) {} // To make compiler happy
|
||||
}
|
||||
#endif
|
||||
|
||||
void BlynkFatal()
|
||||
{
|
||||
BlynkDelay(10000L);
|
||||
BlynkReset();
|
||||
}
|
||||
|
||||
305
wled00/src/dependencies/blynk/Blynk/BlynkDebug.h
Normal file
305
wled00/src/dependencies/blynk/Blynk/BlynkDebug.h
Normal file
@@ -0,0 +1,305 @@
|
||||
/**
|
||||
* @file BlynkDebug.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Debug utilities
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkDebug_h
|
||||
#define BlynkDebug_h
|
||||
|
||||
#include "BlynkConfig.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#ifdef ESP8266
|
||||
extern "C" {
|
||||
#include "ets_sys.h"
|
||||
#include "os_type.h"
|
||||
#include "mem.h"
|
||||
}
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ARC32)
|
||||
typedef uint64_t millis_time_t;
|
||||
#else
|
||||
typedef uint32_t millis_time_t;
|
||||
#endif
|
||||
|
||||
void BlynkDelay(millis_time_t ms);
|
||||
millis_time_t BlynkMillis();
|
||||
size_t BlynkFreeRam();
|
||||
void BlynkReset() BLYNK_NORETURN;
|
||||
void BlynkFatal() BLYNK_NORETURN;
|
||||
|
||||
|
||||
#if defined(SPARK) || defined(PARTICLE)
|
||||
#include "application.h"
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO)
|
||||
#if ARDUINO >= 100
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LINUX)
|
||||
#if defined(RASPBERRY)
|
||||
#include <wiringPi.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BLYNK_RUN_YIELD)
|
||||
#if defined(BLYNK_NO_YIELD)
|
||||
#define BLYNK_RUN_YIELD() {}
|
||||
#elif defined(SPARK) || defined(PARTICLE)
|
||||
#define BLYNK_RUN_YIELD() { Particle.process(); }
|
||||
#elif !defined(ARDUINO) || (ARDUINO < 151)
|
||||
#define BLYNK_RUN_YIELD() {}
|
||||
#else
|
||||
#define BLYNK_RUN_YIELD() { BlynkDelay(0); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__)
|
||||
#include <avr/pgmspace.h>
|
||||
#define BLYNK_HAS_PROGMEM
|
||||
#define BLYNK_PROGMEM PROGMEM
|
||||
#define BLYNK_F(s) F(s)
|
||||
#define BLYNK_PSTR(s) PSTR(s)
|
||||
#else
|
||||
#define BLYNK_PROGMEM
|
||||
#define BLYNK_F(s) s
|
||||
#define BLYNK_PSTR(s) s
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_AVR_DIGISPARK
|
||||
typedef fstr_t __FlashStringHelper;
|
||||
#endif
|
||||
|
||||
#if defined(BLYNK_DEBUG_ALL) && !(__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||
#warning "Compiler features not enabled -> please contact yor board vendor to enable c++0x"
|
||||
#endif
|
||||
|
||||
// Diagnostic defines
|
||||
|
||||
#define BLYNK_FATAL(msg) { BLYNK_LOG1(msg); BlynkFatal(); }
|
||||
#define BLYNK_LOG_RAM() { BLYNK_LOG2(BLYNK_F("Free RAM: "), BlynkFreeRam()); }
|
||||
#define BLYNK_LOG_FN() BLYNK_LOG3(BLYNK_F(__FUNCTION__), '@', __LINE__);
|
||||
#define BLYNK_LOG_TROUBLE(t) BLYNK_LOG2(BLYNK_F("Trouble detected: http://docs.blynk.cc/#troubleshooting-"), t)
|
||||
|
||||
#ifndef BLYNK_PRINT
|
||||
#undef BLYNK_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef BLYNK_DEBUG_ALL
|
||||
#define BLYNK_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef BLYNK_PRINT
|
||||
|
||||
#if defined(ARDUINO) || defined(SPARK) || defined(PARTICLE)
|
||||
|
||||
#if defined(ARDUINO_ARCH_ARC32)
|
||||
// This will cause error - on purpose
|
||||
#define BLYNK_LOG(msg, ...) BLYNK_LOG_UNAVAILABLE(msg, ##__VA_ARGS__)
|
||||
#else
|
||||
#define BLYNK_LOG(msg, ...) blynk_dbg_print(BLYNK_PSTR(msg), ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define BLYNK_LOG1(p1) { BLYNK_LOG_TIME(); BLYNK_PRINT.println(p1); }
|
||||
#define BLYNK_LOG2(p1,p2) { BLYNK_LOG_TIME(); BLYNK_PRINT.print(p1); BLYNK_PRINT.println(p2); }
|
||||
#define BLYNK_LOG3(p1,p2,p3) { BLYNK_LOG_TIME(); BLYNK_PRINT.print(p1); BLYNK_PRINT.print(p2); BLYNK_PRINT.println(p3); }
|
||||
#define BLYNK_LOG4(p1,p2,p3,p4) { BLYNK_LOG_TIME(); BLYNK_PRINT.print(p1); BLYNK_PRINT.print(p2); BLYNK_PRINT.print(p3); BLYNK_PRINT.println(p4); }
|
||||
#define BLYNK_LOG6(p1,p2,p3,p4,p5,p6) { BLYNK_LOG_TIME(); BLYNK_PRINT.print(p1); BLYNK_PRINT.print(p2); BLYNK_PRINT.print(p3); BLYNK_PRINT.print(p4); BLYNK_PRINT.print(p5); BLYNK_PRINT.println(p6); }
|
||||
#define BLYNK_LOG_IP(msg, ip) { BLYNK_LOG_TIME(); BLYNK_PRINT.print(BLYNK_F(msg)); \
|
||||
BLYNK_PRINT.print(ip[0]); BLYNK_PRINT.print('.'); \
|
||||
BLYNK_PRINT.print(ip[1]); BLYNK_PRINT.print('.'); \
|
||||
BLYNK_PRINT.print(ip[2]); BLYNK_PRINT.print('.'); \
|
||||
BLYNK_PRINT.println(ip[3]); }
|
||||
#define BLYNK_LOG_IP_REV(msg, ip) { BLYNK_LOG_TIME(); BLYNK_PRINT.print(BLYNK_F(msg)); \
|
||||
BLYNK_PRINT.print(ip[3]); BLYNK_PRINT.print('.'); \
|
||||
BLYNK_PRINT.print(ip[2]); BLYNK_PRINT.print('.'); \
|
||||
BLYNK_PRINT.print(ip[1]); BLYNK_PRINT.print('.'); \
|
||||
BLYNK_PRINT.println(ip[0]); }
|
||||
|
||||
static
|
||||
void BLYNK_LOG_TIME() {
|
||||
BLYNK_PRINT.print('[');
|
||||
BLYNK_PRINT.print(BlynkMillis());
|
||||
BLYNK_PRINT.print(BLYNK_F("] "));
|
||||
}
|
||||
|
||||
#ifdef BLYNK_DEBUG
|
||||
#include <ctype.h>
|
||||
#define BLYNK_DBG_BREAK() { for(;;); }
|
||||
#define BLYNK_ASSERT(expr) { if(!(expr)) { BLYNK_LOG2(BLYNK_F("Assertion failed: "), BLYNK_F(#expr)); BLYNK_DBG_BREAK() } }
|
||||
|
||||
static
|
||||
void BLYNK_DBG_DUMP(const char* msg, const void* addr, size_t len) {
|
||||
if (len) {
|
||||
BLYNK_LOG_TIME();
|
||||
BLYNK_PRINT.print(msg);
|
||||
int l2 = len;
|
||||
const uint8_t* octets = (const uint8_t*)addr;
|
||||
bool prev_print = true;
|
||||
while (l2--) {
|
||||
const uint8_t c = *octets++ & 0xFF;
|
||||
if (c >= 32 && c < 127) {
|
||||
if (!prev_print) { BLYNK_PRINT.print(']'); }
|
||||
BLYNK_PRINT.print((char)c);
|
||||
prev_print = true;
|
||||
} else {
|
||||
BLYNK_PRINT.print(prev_print?'[':'|');
|
||||
if (c < 0x10) { BLYNK_PRINT.print('0'); }
|
||||
BLYNK_PRINT.print(c, HEX);
|
||||
prev_print = false;
|
||||
}
|
||||
}
|
||||
if (!prev_print) {
|
||||
BLYNK_PRINT.print(']');
|
||||
}
|
||||
BLYNK_PRINT.println();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(ARDUINO_ARCH_ARC32)
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
BLYNK_UNUSED
|
||||
void blynk_dbg_print(const char* BLYNK_PROGMEM fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char buff[128];
|
||||
BLYNK_PRINT.print('[');
|
||||
BLYNK_PRINT.print(BlynkMillis());
|
||||
BLYNK_PRINT.print(BLYNK_F("] "));
|
||||
#if defined(__AVR__)
|
||||
vsnprintf_P(buff, sizeof(buff), fmt, ap);
|
||||
#else
|
||||
vsnprintf(buff, sizeof(buff), fmt, ap);
|
||||
#endif
|
||||
BLYNK_PRINT.println(buff);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif // ARDUINO_ARCH_ARC32
|
||||
|
||||
#elif defined(__MBED__)
|
||||
|
||||
#define BLYNK_LOG(msg, ...) { BLYNK_PRINT.printf("[%ld] " msg "\n", BlynkMillis(), ##__VA_ARGS__); }
|
||||
#define BLYNK_LOG1(p1) { BLYNK_LOG(p1);}
|
||||
#define BLYNK_LOG2(p1,p2) { BLYNK_LOG(p1,p2);}
|
||||
#define BLYNK_LOG3(p1,p2,p3) { BLYNK_LOG(p1,p2,p3);}
|
||||
#define BLYNK_LOG4(p1,p2,p3,p4) { BLYNK_LOG(p1,p2,p3,p4);}
|
||||
#define BLYNK_LOG6(p1,p2,p3,p4,p5,p6) { BLYNK_LOG(p1,p2,p3,p4,p5,p6);}
|
||||
|
||||
#define BLYNK_LOG_TIME() BLYNK_PRINT.printf("[%ld]", BlynkMillis());
|
||||
|
||||
#ifdef BLYNK_DEBUG
|
||||
#define BLYNK_DBG_BREAK() raise(SIGTRAP);
|
||||
#define BLYNK_ASSERT(expr) assert(expr)
|
||||
|
||||
static
|
||||
void BLYNK_DBG_DUMP(const char* msg, const void* addr, size_t len) {
|
||||
BLYNK_LOG_TIME();
|
||||
BLYNK_PRINT.printf(msg);
|
||||
int l2 = len;
|
||||
const uint8_t* octets = (const uint8_t*)addr;
|
||||
bool prev_print = true;
|
||||
while (l2--) {
|
||||
const uint8_t c = *octets++ & 0xFF;
|
||||
if (c >= 32 && c < 127) {
|
||||
if (!prev_print) { BLYNK_PRINT.putc(']'); }
|
||||
BLYNK_PRINT.putc((char)c);
|
||||
prev_print = true;
|
||||
} else {
|
||||
BLYNK_PRINT.putc(prev_print?'[':'|');
|
||||
BLYNK_PRINT.printf("%02x", c);
|
||||
prev_print = false;
|
||||
}
|
||||
}
|
||||
BLYNK_PRINT.printf("%s\n", prev_print?"":"]");
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(LINUX)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define BLYNK_LOG(msg, ...) { fprintf(BLYNK_PRINT, "[%ld] " msg "\n", BlynkMillis(), ##__VA_ARGS__); }
|
||||
#define BLYNK_LOG1(p1) { BLYNK_LOG_TIME(); cout << p1 << endl; }
|
||||
#define BLYNK_LOG2(p1,p2) { BLYNK_LOG_TIME(); cout << p1 << p2 << endl; }
|
||||
#define BLYNK_LOG3(p1,p2,p3) { BLYNK_LOG_TIME(); cout << p1 << p2 << p3 << endl; }
|
||||
#define BLYNK_LOG4(p1,p2,p3,p4) { BLYNK_LOG_TIME(); cout << p1 << p2 << p3 << p4 << endl; }
|
||||
#define BLYNK_LOG6(p1,p2,p3,p4,p5,p6) { BLYNK_LOG_TIME(); cout << p1 << p2 << p3 << p4 << p5 << p6 << endl; }
|
||||
|
||||
#define BLYNK_LOG_TIME() cout << '[' << BlynkMillis() << "] ";
|
||||
|
||||
#ifdef BLYNK_DEBUG
|
||||
#define BLYNK_DBG_BREAK() raise(SIGTRAP);
|
||||
#define BLYNK_ASSERT(expr) assert(expr)
|
||||
|
||||
static
|
||||
void BLYNK_DBG_DUMP(const char* msg, const void* addr, size_t len) {
|
||||
BLYNK_LOG_TIME();
|
||||
fprintf(BLYNK_PRINT, "%s", msg);
|
||||
int l2 = len;
|
||||
const uint8_t* octets = (const uint8_t*)addr;
|
||||
bool prev_print = true;
|
||||
while (l2--) {
|
||||
const uint8_t c = *octets++ & 0xFF;
|
||||
if (c >= 32 && c < 127) {
|
||||
if (!prev_print) { fputc(']', BLYNK_PRINT); }
|
||||
fputc((char)c, BLYNK_PRINT);
|
||||
prev_print = true;
|
||||
} else {
|
||||
fputc(prev_print?'[':'|', BLYNK_PRINT);
|
||||
fprintf(BLYNK_PRINT, "%02x", c);
|
||||
prev_print = false;
|
||||
}
|
||||
}
|
||||
fprintf(BLYNK_PRINT, "%s\n", prev_print?"":"]");
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#warning "Cannot detect platform"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BLYNK_LOG
|
||||
#define BLYNK_LOG(...)
|
||||
#define BLYNK_LOG1(p1)
|
||||
#define BLYNK_LOG2(p1,p2)
|
||||
#define BLYNK_LOG3(p1,p2,p3)
|
||||
#define BLYNK_LOG4(p1,p2,p3,p4)
|
||||
#define BLYNK_LOG6(p1,p2,p3,p4,p5,p6)
|
||||
#define BLYNK_LOG_IP(msg, ip)
|
||||
#define BLYNK_LOG_IP_REV(msg, ip)
|
||||
#endif
|
||||
|
||||
#ifndef BLYNK_DBG_BREAK
|
||||
#define BLYNK_DBG_BREAK()
|
||||
#define BLYNK_ASSERT(expr)
|
||||
#define BLYNK_DBG_DUMP(msg, addr, len)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
268
wled00/src/dependencies/blynk/Blynk/BlynkDetectDevice.h
Normal file
268
wled00/src/dependencies/blynk/Blynk/BlynkDetectDevice.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* @file BlynkDetectDevice.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
||||
* @date May 2016
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkDetectDevice_h
|
||||
#define BlynkDetectDevice_h
|
||||
|
||||
// General defines
|
||||
|
||||
#define BLYNK_NEWLINE "\r\n"
|
||||
|
||||
#define BLYNK_CONCAT(a, b) a ## b
|
||||
#define BLYNK_CONCAT2(a, b) BLYNK_CONCAT(a, b)
|
||||
|
||||
#define BLYNK_STRINGIFY(x) #x
|
||||
#define BLYNK_TOSTRING(x) BLYNK_STRINGIFY(x)
|
||||
|
||||
#define BLYNK_COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
|
||||
|
||||
#define BLYNK_ATTR_PACKED __attribute__ ((__packed__))
|
||||
#define BLYNK_NORETURN __attribute__ ((noreturn))
|
||||
#define BLYNK_UNUSED __attribute__((__unused__))
|
||||
#define BLYNK_DEPRECATED __attribute__ ((deprecated))
|
||||
#define BLYNK_CONSTRUCTOR __attribute__((constructor))
|
||||
|
||||
// Causes problems on some platforms
|
||||
#define BLYNK_FORCE_INLINE inline //__attribute__((always_inline))
|
||||
|
||||
#ifndef BLYNK_INFO_CPU
|
||||
#if defined(__AVR_ATmega168__)
|
||||
#define BLYNK_INFO_CPU "ATmega168"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BLYNK_INFO_DEVICE
|
||||
|
||||
#if defined(ENERGIA)
|
||||
|
||||
#define BLYNK_NO_YIELD
|
||||
#define BLYNK_USE_128_VPINS
|
||||
|
||||
#if defined(ENERGIA_ARCH_MSP430)
|
||||
#define BLYNK_INFO_DEVICE "LaunchPad MSP430"
|
||||
#define BLYNK_INFO_CPU "MSP430"
|
||||
#define BLYNK_NO_FLOAT
|
||||
#elif defined(ENERGIA_ARCH_MSP432)
|
||||
#define BLYNK_INFO_DEVICE "LaunchPad MSP432"
|
||||
#define BLYNK_INFO_CPU "MSP432"
|
||||
#elif defined(ENERGIA_ARCH_TIVAC)
|
||||
#define BLYNK_INFO_DEVICE "LaunchPad"
|
||||
|
||||
#elif defined(ENERGIA_ARCH_CC3200EMT) || defined(ENERGIA_ARCH_CC3200)
|
||||
#define BLYNK_INFO_CONNECTION "CC3200"
|
||||
#define BLYNK_SEND_CHUNK 64
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
|
||||
#if defined(ENERGIA_CC3200_LAUNCHXL) //TODO: This is a bug in Energia IDE
|
||||
#define BLYNK_INFO_DEVICE "CC3200 LaunchXL"
|
||||
#elif defined(ENERGIA_RedBearLab_CC3200)
|
||||
#define BLYNK_INFO_DEVICE "RBL CC3200"
|
||||
#elif defined(ENERGIA_RedBearLab_WiFiMini)
|
||||
#define BLYNK_INFO_DEVICE "RBL WiFi Mini"
|
||||
#elif defined(ENERGIA_RedBearLab_WiFiMicro)
|
||||
#define BLYNK_INFO_DEVICE "RBL WiFi Micro"
|
||||
#endif
|
||||
#elif defined(ENERGIA_ARCH_CC3220EMT) || defined(ENERGIA_ARCH_CC3220)
|
||||
#define BLYNK_INFO_CONNECTION "CC3220"
|
||||
#define BLYNK_SEND_CHUNK 64
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
|
||||
#define BLYNK_USE_INTERNAL_DTOSTRF
|
||||
|
||||
#define BLYNK_INFO_DEVICE "CC3220"
|
||||
#define BLYNK_INFO_CPU "CC3220"
|
||||
#endif
|
||||
|
||||
#if !defined(BLYNK_INFO_DEVICE)
|
||||
#define BLYNK_INFO_DEVICE "Energia"
|
||||
#endif
|
||||
|
||||
#elif defined(LINUX)
|
||||
|
||||
#define BLYNK_INFO_DEVICE "Linux"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 4096
|
||||
|
||||
#elif defined(SPARK) || defined(PARTICLE)
|
||||
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
|
||||
#if PLATFORM_ID==0
|
||||
#define BLYNK_INFO_DEVICE "Particle Core"
|
||||
#undef BLYNK_BUFFERS_SIZE // Use default on Core
|
||||
#elif PLATFORM_ID==6
|
||||
#define BLYNK_INFO_DEVICE "Particle Photon"
|
||||
#elif PLATFORM_ID==8
|
||||
#define BLYNK_INFO_DEVICE "Particle P1"
|
||||
#elif PLATFORM_ID==9
|
||||
#define BLYNK_INFO_DEVICE "Particle Ethernet"
|
||||
#elif PLATFORM_ID==10
|
||||
#define BLYNK_INFO_DEVICE "Particle Electron"
|
||||
#elif PLATFORM_ID==31
|
||||
#define BLYNK_INFO_DEVICE "Particle RPi"
|
||||
#elif PLATFORM_ID==82
|
||||
#define BLYNK_INFO_DEVICE "Digistump Oak"
|
||||
#elif PLATFORM_ID==88
|
||||
#define BLYNK_INFO_DEVICE "RedBear Duo"
|
||||
#elif PLATFORM_ID==103
|
||||
#define BLYNK_INFO_DEVICE "Bluz"
|
||||
#else
|
||||
#if defined(BLYNK_DEBUG_ALL)
|
||||
#warning "Cannot detect board type"
|
||||
#endif
|
||||
#define BLYNK_INFO_DEVICE "Particle"
|
||||
#endif
|
||||
|
||||
#elif defined(__MBED__)
|
||||
|
||||
#define BLYNK_INFO_DEVICE "MBED"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 512
|
||||
#define noInterrupts() __disable_irq()
|
||||
#define interrupts() __enable_irq()
|
||||
|
||||
#elif defined(ARDUINO) && defined(MPIDE)
|
||||
#define BLYNK_NO_YIELD
|
||||
|
||||
#if defined(_BOARD_UNO_)
|
||||
#define BLYNK_INFO_DEVICE "chipKIT Uno32"
|
||||
#else
|
||||
#define BLYNK_INFO_DEVICE "chipKIT"
|
||||
#endif
|
||||
|
||||
#elif defined(ARDUINO) && defined(ARDUINO_AMEBA)
|
||||
#if defined(BOARD_RTL8710)
|
||||
#define BLYNK_INFO_DEVICE "RTL8710"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#elif defined(BOARD_RTL8711AM)
|
||||
#define BLYNK_INFO_DEVICE "RTL8711AM"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#elif defined(BOARD_RTL8195A)
|
||||
#define BLYNK_INFO_DEVICE "RTL8195A"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#else
|
||||
#define BLYNK_INFO_DEVICE "Ameba"
|
||||
#endif
|
||||
|
||||
#elif defined(ARDUINO) && defined(TEENSYDUINO)
|
||||
|
||||
#if defined(__MK66FX1M0__)
|
||||
#define BLYNK_INFO_DEVICE "Teensy 3.6"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#elif defined(__MK64FX512__)
|
||||
#define BLYNK_INFO_DEVICE "Teensy 3.5"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#elif defined(__MK20DX256__)
|
||||
#define BLYNK_INFO_DEVICE "Teensy 3.2/3.1"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#elif defined(__MK20DX128__)
|
||||
#define BLYNK_INFO_DEVICE "Teensy 3.0"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#elif defined(__MKL26Z64__)
|
||||
#define BLYNK_INFO_DEVICE "Teensy LC"
|
||||
#define BLYNK_BUFFERS_SIZE 512
|
||||
#elif defined(ARDUINO_ARCH_AVR)
|
||||
#define BLYNK_INFO_DEVICE "Teensy 2.0"
|
||||
#else
|
||||
#define BLYNK_INFO_DEVICE "Teensy"
|
||||
#endif
|
||||
|
||||
#elif defined(ARDUINO)
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAMD) || defined(ESP32) || defined(ESP8266)
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
#endif
|
||||
|
||||
/* Arduino AVR */
|
||||
#if defined(ARDUINO_AVR_NANO)
|
||||
#define BLYNK_INFO_DEVICE "Arduino Nano"
|
||||
|
||||
/* ESP8266 */
|
||||
#elif defined(ARDUINO_ESP8266_ESP01)
|
||||
#define BLYNK_INFO_DEVICE "ESP8266"
|
||||
#elif defined(ARDUINO_ESP8266_ESP12)
|
||||
#define BLYNK_INFO_DEVICE "ESP-12"
|
||||
#elif defined(ARDUINO_ESP8266_NODEMCU)
|
||||
#define BLYNK_INFO_DEVICE "NodeMCU"
|
||||
#elif defined(ARDUINO_ESP8266_THING)
|
||||
#define BLYNK_INFO_DEVICE "Esp Thing"
|
||||
#elif defined(ARDUINO_ESP8266_THING_DEV)
|
||||
#define BLYNK_INFO_DEVICE "Esp Thing Dev"
|
||||
|
||||
/* ESP32 */
|
||||
#elif defined(ARDUINO_ESP32_DEV)
|
||||
#define BLYNK_INFO_DEVICE "ESP32"
|
||||
#elif defined(ARDUINO_ESP320)
|
||||
#define BLYNK_INFO_DEVICE "SweetPeas ESP320"
|
||||
#elif defined(ARDUINO_NANO32)
|
||||
#define BLYNK_INFO_DEVICE "ESP32 Nano32"
|
||||
#elif defined(ARDUINO_LoLin32)
|
||||
#define BLYNK_INFO_DEVICE "LoLin32"
|
||||
#elif defined(ARDUINO_ESPea32)
|
||||
#define BLYNK_INFO_DEVICE "ESPea32"
|
||||
#elif defined(ARDUINO_QUANTUM)
|
||||
#define BLYNK_INFO_DEVICE "Noduino Quantum"
|
||||
|
||||
#else
|
||||
#if defined(BLYNK_DEBUG_ALL)
|
||||
#warning "Cannot detect board type"
|
||||
#endif
|
||||
#define BLYNK_INFO_DEVICE "Arduino"
|
||||
#endif
|
||||
|
||||
#elif defined(TI_CC3220)
|
||||
#define BLYNK_INFO_DEVICE "TI CC3220"
|
||||
#define BLYNK_USE_128_VPINS
|
||||
#define BLYNK_BUFFERS_SIZE 1024
|
||||
|
||||
#define BLYNK_USE_INTERNAL_DTOSTRF
|
||||
|
||||
#else
|
||||
|
||||
#define BLYNK_INFO_DEVICE "Custom platform"
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BLYNK_MAX_READBYTES) && defined(BLYNK_BUFFERS_SIZE)
|
||||
#define BLYNK_MAX_READBYTES BLYNK_BUFFERS_SIZE
|
||||
#endif
|
||||
|
||||
#if !defined(BLYNK_MAX_SENDBYTES) && defined(BLYNK_BUFFERS_SIZE)
|
||||
#define BLYNK_MAX_SENDBYTES BLYNK_BUFFERS_SIZE
|
||||
#endif
|
||||
|
||||
// Print diagnostics
|
||||
|
||||
#if defined(BLYNK_DEBUG_ALL)
|
||||
#if defined(BLYNK_INFO_DEVICE)
|
||||
#pragma message ("BLYNK_INFO_DEVICE=" BLYNK_TOSTRING(BLYNK_INFO_DEVICE))
|
||||
#endif
|
||||
|
||||
#if defined(BLYNK_INFO_CPU)
|
||||
#pragma message ("BLYNK_INFO_CPU=" BLYNK_TOSTRING(BLYNK_INFO_CPU))
|
||||
#endif
|
||||
|
||||
#if defined(BLYNK_BUFFERS_SIZE)
|
||||
#pragma message ("BLYNK_BUFFERS_SIZE=" BLYNK_TOSTRING(BLYNK_BUFFERS_SIZE))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
69
wled00/src/dependencies/blynk/Blynk/BlynkEveryN.h
Normal file
69
wled00/src/dependencies/blynk/Blynk/BlynkEveryN.h
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
#ifndef BLYNKEVERYN_H
|
||||
#define BLYNKEVERYN_H
|
||||
|
||||
#include "BlynkDebug.h"
|
||||
|
||||
millis_time_t blynk_count_millis() {
|
||||
const millis_time_t ms = BlynkMillis();
|
||||
return ms;
|
||||
}
|
||||
|
||||
uint16_t blynk_count_seconds16() {
|
||||
const millis_time_t ms = BlynkMillis();
|
||||
return (ms / 1000);
|
||||
}
|
||||
|
||||
uint16_t blynk_count_minutes16()
|
||||
{
|
||||
const millis_time_t ms = BlynkMillis();
|
||||
return (ms / (60000L)) & 0xFFFF;
|
||||
}
|
||||
|
||||
uint8_t blynk_count_hours8()
|
||||
{
|
||||
const millis_time_t ms = BlynkMillis();
|
||||
return (ms / (3600000L)) & 0xFF;
|
||||
}
|
||||
|
||||
template<typename T, T (*timeGetter)()>
|
||||
class BlynkPeriodic {
|
||||
public:
|
||||
T mPrev;
|
||||
T mPeriod;
|
||||
|
||||
BlynkPeriodic() { reset(); mPeriod = 1; };
|
||||
BlynkPeriodic(T period) { reset(); setPeriod(period); };
|
||||
void setPeriod( T period) { mPeriod = period; };
|
||||
T getTime() { return (T)(timeGetter()); };
|
||||
T getPeriod() { return mPeriod; };
|
||||
T getElapsed() { return getTime() - mPrev; }
|
||||
T getRemaining() { return mPeriod - getElapsed(); }
|
||||
T getLastTriggerTime() { return mPrev; }
|
||||
bool ready() {
|
||||
bool isReady = (getElapsed() >= mPeriod);
|
||||
if( isReady ) { reset(); }
|
||||
return isReady;
|
||||
}
|
||||
void reset() { mPrev = getTime(); };
|
||||
void trigger() { mPrev = getTime() - mPeriod; };
|
||||
|
||||
operator bool() { return ready(); }
|
||||
};
|
||||
|
||||
typedef BlynkPeriodic<millis_time_t,blynk_count_millis> BlynkEveryNMillis;
|
||||
typedef BlynkPeriodic<uint16_t,blynk_count_seconds16> BlynkEveryNSeconds;
|
||||
typedef BlynkPeriodic<uint16_t,blynk_count_minutes16> BlynkEveryNMinutes;
|
||||
typedef BlynkPeriodic<uint8_t,blynk_count_hours8> BlynkEveryNHours;
|
||||
|
||||
#define BLYNK_EVERY_N_MILLIS_I(NAME,N) static BlynkEveryNMillis NAME(N); if(NAME)
|
||||
#define BLYNK_EVERY_N_SECONDS_I(NAME,N) static BlynkEveryNSeconds NAME(N); if(NAME)
|
||||
#define BLYNK_EVERY_N_MINUTES_I(NAME,N) static BlynkEveryNMinutes NAME(N); if(NAME)
|
||||
#define BLYNK_EVERY_N_HOURS_I(NAME,N) static BlynkEveryNHours NAME(N); if(NAME)
|
||||
|
||||
#define BLYNK_EVERY_N_MILLIS(N) BLYNK_EVERY_N_MILLIS_I(BLYNK_CONCAT2(PER, __COUNTER__),N)
|
||||
#define BLYNK_EVERY_N_SECONDS(N) BLYNK_EVERY_N_SECONDS_I(BLYNK_CONCAT2(PER, __COUNTER__),N)
|
||||
#define BLYNK_EVERY_N_MINUTES(N) BLYNK_EVERY_N_MINUTES_I(BLYNK_CONCAT2(PER, __COUNTER__),N)
|
||||
#define BLYNK_EVERY_N_HOURS(N) BLYNK_EVERY_N_HOURS_I(BLYNK_CONCAT2(PER, __COUNTER__),N)
|
||||
|
||||
#endif
|
||||
158
wled00/src/dependencies/blynk/Blynk/BlynkFifo.h
Normal file
158
wled00/src/dependencies/blynk/Blynk/BlynkFifo.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* @file BlynkFifo.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Feb 2015
|
||||
* @brief FIFO implementation
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkFifo_h
|
||||
#define BlynkFifo_h
|
||||
|
||||
#include "BlynkUtility.h"
|
||||
|
||||
template <class T, unsigned N>
|
||||
class BlynkFifo
|
||||
{
|
||||
public:
|
||||
BlynkFifo()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
_r = 0;
|
||||
_w = 0;
|
||||
}
|
||||
|
||||
~BlynkFifo(void)
|
||||
{}
|
||||
|
||||
// writing thread/context API
|
||||
//-------------------------------------------------------------
|
||||
|
||||
bool writeable(void)
|
||||
{
|
||||
return free() > 0;
|
||||
}
|
||||
|
||||
int free(void)
|
||||
{
|
||||
int s = _r - _w;
|
||||
if (s <= 0)
|
||||
s += N;
|
||||
return s - 1;
|
||||
}
|
||||
|
||||
T put(const T& c)
|
||||
{
|
||||
int i = _w;
|
||||
int j = i;
|
||||
i = _inc(i);
|
||||
while (i == _r) // = !writeable()
|
||||
/* nothing / just wait */;
|
||||
_b[j] = c;
|
||||
_w = i;
|
||||
return c;
|
||||
}
|
||||
|
||||
int put(const T* p, int n, bool blocking = false)
|
||||
{
|
||||
int c = n;
|
||||
while (c)
|
||||
{
|
||||
int f;
|
||||
while ((f = free()) == 0) // wait for space
|
||||
{
|
||||
if (!blocking) return n - c; // no more space and not blocking
|
||||
/* nothing / just wait */;
|
||||
}
|
||||
// check free space
|
||||
if (c < f) f = c;
|
||||
int w = _w;
|
||||
int m = N - w;
|
||||
// check wrap
|
||||
if (f > m) f = m;
|
||||
memcpy(&_b[w], p, f);
|
||||
_w = _inc(w, f);
|
||||
c -= f;
|
||||
p += f;
|
||||
}
|
||||
return n - c;
|
||||
}
|
||||
|
||||
// reading thread/context API
|
||||
// --------------------------------------------------------
|
||||
|
||||
bool readable(void)
|
||||
{
|
||||
return (_r != _w);
|
||||
}
|
||||
|
||||
size_t size(void)
|
||||
{
|
||||
int s = _w - _r;
|
||||
if (s < 0)
|
||||
s += N;
|
||||
return s;
|
||||
}
|
||||
|
||||
T get(void)
|
||||
{
|
||||
int r = _r;
|
||||
while (r == _w) // = !readable()
|
||||
/* nothing / just wait */;
|
||||
T t = _b[r];
|
||||
_r = _inc(r);
|
||||
return t;
|
||||
}
|
||||
|
||||
T peek(void)
|
||||
{
|
||||
int r = _r;
|
||||
while (r == _w);
|
||||
return _b[r];
|
||||
}
|
||||
|
||||
int get(T* p, int n, bool blocking = false)
|
||||
{
|
||||
int c = n;
|
||||
while (c)
|
||||
{
|
||||
int f;
|
||||
for (;;) // wait for data
|
||||
{
|
||||
f = size();
|
||||
if (f) break; // free space
|
||||
if (!blocking) return n - c; // no space and not blocking
|
||||
/* nothing / just wait */;
|
||||
}
|
||||
// check available data
|
||||
if (c < f) f = c;
|
||||
int r = _r;
|
||||
int m = N - r;
|
||||
// check wrap
|
||||
if (f > m) f = m;
|
||||
memcpy(p, &_b[r], f);
|
||||
_r = _inc(r, f);
|
||||
c -= f;
|
||||
p += f;
|
||||
}
|
||||
return n - c;
|
||||
}
|
||||
|
||||
private:
|
||||
int _inc(int i, int n = 1)
|
||||
{
|
||||
return (i + n) % N;
|
||||
}
|
||||
|
||||
T _b[N];
|
||||
volatile int _w;
|
||||
volatile int _r;
|
||||
};
|
||||
|
||||
#endif
|
||||
402
wled00/src/dependencies/blynk/Blynk/BlynkHandlers.cpp
Normal file
402
wled00/src/dependencies/blynk/Blynk/BlynkHandlers.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
* @file BlynkHandlers.cpp
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Virtual pin utilities
|
||||
*/
|
||||
|
||||
#include "BlynkConfig.h"
|
||||
#include "BlynkHandlers.h"
|
||||
#include "BlynkDebug.h"
|
||||
|
||||
void BlynkNoOpCbk()
|
||||
{}
|
||||
|
||||
void BlynkWidgetRead(BlynkReq BLYNK_UNUSED &request)
|
||||
{
|
||||
BLYNK_LOG2(BLYNK_F("No handler for reading from pin "), request.pin);
|
||||
}
|
||||
|
||||
void BlynkWidgetWrite(BlynkReq BLYNK_UNUSED &request, const BlynkParam BLYNK_UNUSED ¶m)
|
||||
{
|
||||
BLYNK_LOG2(BLYNK_F("No handler for writing to pin "), request.pin);
|
||||
}
|
||||
|
||||
#define BLYNK_ON_READ_IMPL(pin) void BlynkWidgetRead ## pin (BlynkReq BLYNK_UNUSED &req) \
|
||||
__attribute__((weak, alias("BlynkWidgetRead")))
|
||||
|
||||
#define BLYNK_ON_WRITE_IMPL(pin) void BlynkWidgetWrite ## pin (BlynkReq BLYNK_UNUSED &req, const BlynkParam BLYNK_UNUSED ¶m) \
|
||||
__attribute__((weak, alias("BlynkWidgetWrite")))
|
||||
|
||||
BLYNK_CONNECTED() __attribute__((weak, alias("BlynkNoOpCbk")));
|
||||
BLYNK_DISCONNECTED() __attribute__((weak, alias("BlynkNoOpCbk")));
|
||||
|
||||
// Internal Virtual Pins
|
||||
BLYNK_ON_WRITE_IMPL(InternalPinACON);
|
||||
BLYNK_ON_WRITE_IMPL(InternalPinADIS);
|
||||
BLYNK_ON_WRITE_IMPL(InternalPinRTC);
|
||||
BLYNK_ON_WRITE_IMPL(InternalPinOTA);
|
||||
|
||||
// Regular Virtual Pins
|
||||
BLYNK_ON_READ_IMPL(Default);
|
||||
BLYNK_ON_WRITE_IMPL(Default);
|
||||
|
||||
BLYNK_ON_READ_IMPL(0 );
|
||||
BLYNK_ON_READ_IMPL(1 );
|
||||
BLYNK_ON_READ_IMPL(2 );
|
||||
BLYNK_ON_READ_IMPL(3 );
|
||||
BLYNK_ON_READ_IMPL(4 );
|
||||
BLYNK_ON_READ_IMPL(5 );
|
||||
BLYNK_ON_READ_IMPL(6 );
|
||||
BLYNK_ON_READ_IMPL(7 );
|
||||
BLYNK_ON_READ_IMPL(8 );
|
||||
BLYNK_ON_READ_IMPL(9 );
|
||||
BLYNK_ON_READ_IMPL(10);
|
||||
BLYNK_ON_READ_IMPL(11);
|
||||
BLYNK_ON_READ_IMPL(12);
|
||||
BLYNK_ON_READ_IMPL(13);
|
||||
BLYNK_ON_READ_IMPL(14);
|
||||
BLYNK_ON_READ_IMPL(15);
|
||||
BLYNK_ON_READ_IMPL(16);
|
||||
BLYNK_ON_READ_IMPL(17);
|
||||
BLYNK_ON_READ_IMPL(18);
|
||||
BLYNK_ON_READ_IMPL(19);
|
||||
BLYNK_ON_READ_IMPL(20);
|
||||
BLYNK_ON_READ_IMPL(21);
|
||||
BLYNK_ON_READ_IMPL(22);
|
||||
BLYNK_ON_READ_IMPL(23);
|
||||
BLYNK_ON_READ_IMPL(24);
|
||||
BLYNK_ON_READ_IMPL(25);
|
||||
BLYNK_ON_READ_IMPL(26);
|
||||
BLYNK_ON_READ_IMPL(27);
|
||||
BLYNK_ON_READ_IMPL(28);
|
||||
BLYNK_ON_READ_IMPL(29);
|
||||
BLYNK_ON_READ_IMPL(30);
|
||||
BLYNK_ON_READ_IMPL(31);
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
BLYNK_ON_READ_IMPL(32);
|
||||
BLYNK_ON_READ_IMPL(33);
|
||||
BLYNK_ON_READ_IMPL(34);
|
||||
BLYNK_ON_READ_IMPL(35);
|
||||
BLYNK_ON_READ_IMPL(36);
|
||||
BLYNK_ON_READ_IMPL(37);
|
||||
BLYNK_ON_READ_IMPL(38);
|
||||
BLYNK_ON_READ_IMPL(39);
|
||||
BLYNK_ON_READ_IMPL(40);
|
||||
BLYNK_ON_READ_IMPL(41);
|
||||
BLYNK_ON_READ_IMPL(42);
|
||||
BLYNK_ON_READ_IMPL(43);
|
||||
BLYNK_ON_READ_IMPL(44);
|
||||
BLYNK_ON_READ_IMPL(45);
|
||||
BLYNK_ON_READ_IMPL(46);
|
||||
BLYNK_ON_READ_IMPL(47);
|
||||
BLYNK_ON_READ_IMPL(48);
|
||||
BLYNK_ON_READ_IMPL(49);
|
||||
BLYNK_ON_READ_IMPL(50);
|
||||
BLYNK_ON_READ_IMPL(51);
|
||||
BLYNK_ON_READ_IMPL(52);
|
||||
BLYNK_ON_READ_IMPL(53);
|
||||
BLYNK_ON_READ_IMPL(54);
|
||||
BLYNK_ON_READ_IMPL(55);
|
||||
BLYNK_ON_READ_IMPL(56);
|
||||
BLYNK_ON_READ_IMPL(57);
|
||||
BLYNK_ON_READ_IMPL(58);
|
||||
BLYNK_ON_READ_IMPL(59);
|
||||
BLYNK_ON_READ_IMPL(60);
|
||||
BLYNK_ON_READ_IMPL(61);
|
||||
BLYNK_ON_READ_IMPL(62);
|
||||
BLYNK_ON_READ_IMPL(63);
|
||||
BLYNK_ON_READ_IMPL(64);
|
||||
BLYNK_ON_READ_IMPL(65);
|
||||
BLYNK_ON_READ_IMPL(66);
|
||||
BLYNK_ON_READ_IMPL(67);
|
||||
BLYNK_ON_READ_IMPL(68);
|
||||
BLYNK_ON_READ_IMPL(69);
|
||||
BLYNK_ON_READ_IMPL(70);
|
||||
BLYNK_ON_READ_IMPL(71);
|
||||
BLYNK_ON_READ_IMPL(72);
|
||||
BLYNK_ON_READ_IMPL(73);
|
||||
BLYNK_ON_READ_IMPL(74);
|
||||
BLYNK_ON_READ_IMPL(75);
|
||||
BLYNK_ON_READ_IMPL(76);
|
||||
BLYNK_ON_READ_IMPL(77);
|
||||
BLYNK_ON_READ_IMPL(78);
|
||||
BLYNK_ON_READ_IMPL(79);
|
||||
BLYNK_ON_READ_IMPL(80);
|
||||
BLYNK_ON_READ_IMPL(81);
|
||||
BLYNK_ON_READ_IMPL(82);
|
||||
BLYNK_ON_READ_IMPL(83);
|
||||
BLYNK_ON_READ_IMPL(84);
|
||||
BLYNK_ON_READ_IMPL(85);
|
||||
BLYNK_ON_READ_IMPL(86);
|
||||
BLYNK_ON_READ_IMPL(87);
|
||||
BLYNK_ON_READ_IMPL(88);
|
||||
BLYNK_ON_READ_IMPL(89);
|
||||
BLYNK_ON_READ_IMPL(90);
|
||||
BLYNK_ON_READ_IMPL(91);
|
||||
BLYNK_ON_READ_IMPL(92);
|
||||
BLYNK_ON_READ_IMPL(93);
|
||||
BLYNK_ON_READ_IMPL(94);
|
||||
BLYNK_ON_READ_IMPL(95);
|
||||
BLYNK_ON_READ_IMPL(96);
|
||||
BLYNK_ON_READ_IMPL(97);
|
||||
BLYNK_ON_READ_IMPL(98);
|
||||
BLYNK_ON_READ_IMPL(99);
|
||||
BLYNK_ON_READ_IMPL(100);
|
||||
BLYNK_ON_READ_IMPL(101);
|
||||
BLYNK_ON_READ_IMPL(102);
|
||||
BLYNK_ON_READ_IMPL(103);
|
||||
BLYNK_ON_READ_IMPL(104);
|
||||
BLYNK_ON_READ_IMPL(105);
|
||||
BLYNK_ON_READ_IMPL(106);
|
||||
BLYNK_ON_READ_IMPL(107);
|
||||
BLYNK_ON_READ_IMPL(108);
|
||||
BLYNK_ON_READ_IMPL(109);
|
||||
BLYNK_ON_READ_IMPL(110);
|
||||
BLYNK_ON_READ_IMPL(111);
|
||||
BLYNK_ON_READ_IMPL(112);
|
||||
BLYNK_ON_READ_IMPL(113);
|
||||
BLYNK_ON_READ_IMPL(114);
|
||||
BLYNK_ON_READ_IMPL(115);
|
||||
BLYNK_ON_READ_IMPL(116);
|
||||
BLYNK_ON_READ_IMPL(117);
|
||||
BLYNK_ON_READ_IMPL(118);
|
||||
BLYNK_ON_READ_IMPL(119);
|
||||
BLYNK_ON_READ_IMPL(120);
|
||||
BLYNK_ON_READ_IMPL(121);
|
||||
BLYNK_ON_READ_IMPL(122);
|
||||
BLYNK_ON_READ_IMPL(123);
|
||||
BLYNK_ON_READ_IMPL(124);
|
||||
BLYNK_ON_READ_IMPL(125);
|
||||
BLYNK_ON_READ_IMPL(126);
|
||||
BLYNK_ON_READ_IMPL(127);
|
||||
#endif
|
||||
|
||||
BLYNK_ON_WRITE_IMPL(0 );
|
||||
BLYNK_ON_WRITE_IMPL(1 );
|
||||
BLYNK_ON_WRITE_IMPL(2 );
|
||||
BLYNK_ON_WRITE_IMPL(3 );
|
||||
BLYNK_ON_WRITE_IMPL(4 );
|
||||
BLYNK_ON_WRITE_IMPL(5 );
|
||||
BLYNK_ON_WRITE_IMPL(6 );
|
||||
BLYNK_ON_WRITE_IMPL(7 );
|
||||
BLYNK_ON_WRITE_IMPL(8 );
|
||||
BLYNK_ON_WRITE_IMPL(9 );
|
||||
BLYNK_ON_WRITE_IMPL(10);
|
||||
BLYNK_ON_WRITE_IMPL(11);
|
||||
BLYNK_ON_WRITE_IMPL(12);
|
||||
BLYNK_ON_WRITE_IMPL(13);
|
||||
BLYNK_ON_WRITE_IMPL(14);
|
||||
BLYNK_ON_WRITE_IMPL(15);
|
||||
BLYNK_ON_WRITE_IMPL(16);
|
||||
BLYNK_ON_WRITE_IMPL(17);
|
||||
BLYNK_ON_WRITE_IMPL(18);
|
||||
BLYNK_ON_WRITE_IMPL(19);
|
||||
BLYNK_ON_WRITE_IMPL(20);
|
||||
BLYNK_ON_WRITE_IMPL(21);
|
||||
BLYNK_ON_WRITE_IMPL(22);
|
||||
BLYNK_ON_WRITE_IMPL(23);
|
||||
BLYNK_ON_WRITE_IMPL(24);
|
||||
BLYNK_ON_WRITE_IMPL(25);
|
||||
BLYNK_ON_WRITE_IMPL(26);
|
||||
BLYNK_ON_WRITE_IMPL(27);
|
||||
BLYNK_ON_WRITE_IMPL(28);
|
||||
BLYNK_ON_WRITE_IMPL(29);
|
||||
BLYNK_ON_WRITE_IMPL(30);
|
||||
BLYNK_ON_WRITE_IMPL(31);
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
BLYNK_ON_WRITE_IMPL(32);
|
||||
BLYNK_ON_WRITE_IMPL(33);
|
||||
BLYNK_ON_WRITE_IMPL(34);
|
||||
BLYNK_ON_WRITE_IMPL(35);
|
||||
BLYNK_ON_WRITE_IMPL(36);
|
||||
BLYNK_ON_WRITE_IMPL(37);
|
||||
BLYNK_ON_WRITE_IMPL(38);
|
||||
BLYNK_ON_WRITE_IMPL(39);
|
||||
BLYNK_ON_WRITE_IMPL(40);
|
||||
BLYNK_ON_WRITE_IMPL(41);
|
||||
BLYNK_ON_WRITE_IMPL(42);
|
||||
BLYNK_ON_WRITE_IMPL(43);
|
||||
BLYNK_ON_WRITE_IMPL(44);
|
||||
BLYNK_ON_WRITE_IMPL(45);
|
||||
BLYNK_ON_WRITE_IMPL(46);
|
||||
BLYNK_ON_WRITE_IMPL(47);
|
||||
BLYNK_ON_WRITE_IMPL(48);
|
||||
BLYNK_ON_WRITE_IMPL(49);
|
||||
BLYNK_ON_WRITE_IMPL(50);
|
||||
BLYNK_ON_WRITE_IMPL(51);
|
||||
BLYNK_ON_WRITE_IMPL(52);
|
||||
BLYNK_ON_WRITE_IMPL(53);
|
||||
BLYNK_ON_WRITE_IMPL(54);
|
||||
BLYNK_ON_WRITE_IMPL(55);
|
||||
BLYNK_ON_WRITE_IMPL(56);
|
||||
BLYNK_ON_WRITE_IMPL(57);
|
||||
BLYNK_ON_WRITE_IMPL(58);
|
||||
BLYNK_ON_WRITE_IMPL(59);
|
||||
BLYNK_ON_WRITE_IMPL(60);
|
||||
BLYNK_ON_WRITE_IMPL(61);
|
||||
BLYNK_ON_WRITE_IMPL(62);
|
||||
BLYNK_ON_WRITE_IMPL(63);
|
||||
BLYNK_ON_WRITE_IMPL(64);
|
||||
BLYNK_ON_WRITE_IMPL(65);
|
||||
BLYNK_ON_WRITE_IMPL(66);
|
||||
BLYNK_ON_WRITE_IMPL(67);
|
||||
BLYNK_ON_WRITE_IMPL(68);
|
||||
BLYNK_ON_WRITE_IMPL(69);
|
||||
BLYNK_ON_WRITE_IMPL(70);
|
||||
BLYNK_ON_WRITE_IMPL(71);
|
||||
BLYNK_ON_WRITE_IMPL(72);
|
||||
BLYNK_ON_WRITE_IMPL(73);
|
||||
BLYNK_ON_WRITE_IMPL(74);
|
||||
BLYNK_ON_WRITE_IMPL(75);
|
||||
BLYNK_ON_WRITE_IMPL(76);
|
||||
BLYNK_ON_WRITE_IMPL(77);
|
||||
BLYNK_ON_WRITE_IMPL(78);
|
||||
BLYNK_ON_WRITE_IMPL(79);
|
||||
BLYNK_ON_WRITE_IMPL(80);
|
||||
BLYNK_ON_WRITE_IMPL(81);
|
||||
BLYNK_ON_WRITE_IMPL(82);
|
||||
BLYNK_ON_WRITE_IMPL(83);
|
||||
BLYNK_ON_WRITE_IMPL(84);
|
||||
BLYNK_ON_WRITE_IMPL(85);
|
||||
BLYNK_ON_WRITE_IMPL(86);
|
||||
BLYNK_ON_WRITE_IMPL(87);
|
||||
BLYNK_ON_WRITE_IMPL(88);
|
||||
BLYNK_ON_WRITE_IMPL(89);
|
||||
BLYNK_ON_WRITE_IMPL(90);
|
||||
BLYNK_ON_WRITE_IMPL(91);
|
||||
BLYNK_ON_WRITE_IMPL(92);
|
||||
BLYNK_ON_WRITE_IMPL(93);
|
||||
BLYNK_ON_WRITE_IMPL(94);
|
||||
BLYNK_ON_WRITE_IMPL(95);
|
||||
BLYNK_ON_WRITE_IMPL(96);
|
||||
BLYNK_ON_WRITE_IMPL(97);
|
||||
BLYNK_ON_WRITE_IMPL(98);
|
||||
BLYNK_ON_WRITE_IMPL(99);
|
||||
BLYNK_ON_WRITE_IMPL(100);
|
||||
BLYNK_ON_WRITE_IMPL(101);
|
||||
BLYNK_ON_WRITE_IMPL(102);
|
||||
BLYNK_ON_WRITE_IMPL(103);
|
||||
BLYNK_ON_WRITE_IMPL(104);
|
||||
BLYNK_ON_WRITE_IMPL(105);
|
||||
BLYNK_ON_WRITE_IMPL(106);
|
||||
BLYNK_ON_WRITE_IMPL(107);
|
||||
BLYNK_ON_WRITE_IMPL(108);
|
||||
BLYNK_ON_WRITE_IMPL(109);
|
||||
BLYNK_ON_WRITE_IMPL(110);
|
||||
BLYNK_ON_WRITE_IMPL(111);
|
||||
BLYNK_ON_WRITE_IMPL(112);
|
||||
BLYNK_ON_WRITE_IMPL(113);
|
||||
BLYNK_ON_WRITE_IMPL(114);
|
||||
BLYNK_ON_WRITE_IMPL(115);
|
||||
BLYNK_ON_WRITE_IMPL(116);
|
||||
BLYNK_ON_WRITE_IMPL(117);
|
||||
BLYNK_ON_WRITE_IMPL(118);
|
||||
BLYNK_ON_WRITE_IMPL(119);
|
||||
BLYNK_ON_WRITE_IMPL(120);
|
||||
BLYNK_ON_WRITE_IMPL(121);
|
||||
BLYNK_ON_WRITE_IMPL(122);
|
||||
BLYNK_ON_WRITE_IMPL(123);
|
||||
BLYNK_ON_WRITE_IMPL(124);
|
||||
BLYNK_ON_WRITE_IMPL(125);
|
||||
BLYNK_ON_WRITE_IMPL(126);
|
||||
BLYNK_ON_WRITE_IMPL(127);
|
||||
#endif
|
||||
|
||||
static const WidgetReadHandler BlynkReadHandlerVector[] BLYNK_PROGMEM = {
|
||||
BlynkWidgetRead0, BlynkWidgetRead1, BlynkWidgetRead2, BlynkWidgetRead3,
|
||||
BlynkWidgetRead4, BlynkWidgetRead5, BlynkWidgetRead6, BlynkWidgetRead7,
|
||||
BlynkWidgetRead8, BlynkWidgetRead9, BlynkWidgetRead10, BlynkWidgetRead11,
|
||||
BlynkWidgetRead12, BlynkWidgetRead13, BlynkWidgetRead14, BlynkWidgetRead15,
|
||||
BlynkWidgetRead16, BlynkWidgetRead17, BlynkWidgetRead18, BlynkWidgetRead19,
|
||||
BlynkWidgetRead20, BlynkWidgetRead21, BlynkWidgetRead22, BlynkWidgetRead23,
|
||||
BlynkWidgetRead24, BlynkWidgetRead25, BlynkWidgetRead26, BlynkWidgetRead27,
|
||||
BlynkWidgetRead28, BlynkWidgetRead29, BlynkWidgetRead30, BlynkWidgetRead31,
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
BlynkWidgetRead32, BlynkWidgetRead33, BlynkWidgetRead34, BlynkWidgetRead35,
|
||||
BlynkWidgetRead36, BlynkWidgetRead37, BlynkWidgetRead38, BlynkWidgetRead39,
|
||||
BlynkWidgetRead40, BlynkWidgetRead41, BlynkWidgetRead42, BlynkWidgetRead43,
|
||||
BlynkWidgetRead44, BlynkWidgetRead45, BlynkWidgetRead46, BlynkWidgetRead47,
|
||||
BlynkWidgetRead48, BlynkWidgetRead49, BlynkWidgetRead50, BlynkWidgetRead51,
|
||||
BlynkWidgetRead52, BlynkWidgetRead53, BlynkWidgetRead54, BlynkWidgetRead55,
|
||||
BlynkWidgetRead56, BlynkWidgetRead57, BlynkWidgetRead58, BlynkWidgetRead59,
|
||||
BlynkWidgetRead60, BlynkWidgetRead61, BlynkWidgetRead62, BlynkWidgetRead63,
|
||||
BlynkWidgetRead64, BlynkWidgetRead65, BlynkWidgetRead66, BlynkWidgetRead67,
|
||||
BlynkWidgetRead68, BlynkWidgetRead69, BlynkWidgetRead70, BlynkWidgetRead71,
|
||||
BlynkWidgetRead72, BlynkWidgetRead73, BlynkWidgetRead74, BlynkWidgetRead75,
|
||||
BlynkWidgetRead76, BlynkWidgetRead77, BlynkWidgetRead78, BlynkWidgetRead79,
|
||||
BlynkWidgetRead80, BlynkWidgetRead81, BlynkWidgetRead82, BlynkWidgetRead83,
|
||||
BlynkWidgetRead84, BlynkWidgetRead85, BlynkWidgetRead86, BlynkWidgetRead87,
|
||||
BlynkWidgetRead88, BlynkWidgetRead89, BlynkWidgetRead90, BlynkWidgetRead91,
|
||||
BlynkWidgetRead92, BlynkWidgetRead93, BlynkWidgetRead94, BlynkWidgetRead95,
|
||||
BlynkWidgetRead96, BlynkWidgetRead97, BlynkWidgetRead98, BlynkWidgetRead99,
|
||||
BlynkWidgetRead100, BlynkWidgetRead101, BlynkWidgetRead102, BlynkWidgetRead103,
|
||||
BlynkWidgetRead104, BlynkWidgetRead105, BlynkWidgetRead106, BlynkWidgetRead107,
|
||||
BlynkWidgetRead108, BlynkWidgetRead109, BlynkWidgetRead110, BlynkWidgetRead111,
|
||||
BlynkWidgetRead112, BlynkWidgetRead113, BlynkWidgetRead114, BlynkWidgetRead115,
|
||||
BlynkWidgetRead116, BlynkWidgetRead117, BlynkWidgetRead118, BlynkWidgetRead119,
|
||||
BlynkWidgetRead120, BlynkWidgetRead121, BlynkWidgetRead122, BlynkWidgetRead123,
|
||||
BlynkWidgetRead124, BlynkWidgetRead125, BlynkWidgetRead126, BlynkWidgetRead127,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const WidgetWriteHandler BlynkWriteHandlerVector[] BLYNK_PROGMEM = {
|
||||
BlynkWidgetWrite0, BlynkWidgetWrite1, BlynkWidgetWrite2, BlynkWidgetWrite3,
|
||||
BlynkWidgetWrite4, BlynkWidgetWrite5, BlynkWidgetWrite6, BlynkWidgetWrite7,
|
||||
BlynkWidgetWrite8, BlynkWidgetWrite9, BlynkWidgetWrite10, BlynkWidgetWrite11,
|
||||
BlynkWidgetWrite12, BlynkWidgetWrite13, BlynkWidgetWrite14, BlynkWidgetWrite15,
|
||||
BlynkWidgetWrite16, BlynkWidgetWrite17, BlynkWidgetWrite18, BlynkWidgetWrite19,
|
||||
BlynkWidgetWrite20, BlynkWidgetWrite21, BlynkWidgetWrite22, BlynkWidgetWrite23,
|
||||
BlynkWidgetWrite24, BlynkWidgetWrite25, BlynkWidgetWrite26, BlynkWidgetWrite27,
|
||||
BlynkWidgetWrite28, BlynkWidgetWrite29, BlynkWidgetWrite30, BlynkWidgetWrite31,
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
BlynkWidgetWrite32, BlynkWidgetWrite33, BlynkWidgetWrite34, BlynkWidgetWrite35,
|
||||
BlynkWidgetWrite36, BlynkWidgetWrite37, BlynkWidgetWrite38, BlynkWidgetWrite39,
|
||||
BlynkWidgetWrite40, BlynkWidgetWrite41, BlynkWidgetWrite42, BlynkWidgetWrite43,
|
||||
BlynkWidgetWrite44, BlynkWidgetWrite45, BlynkWidgetWrite46, BlynkWidgetWrite47,
|
||||
BlynkWidgetWrite48, BlynkWidgetWrite49, BlynkWidgetWrite50, BlynkWidgetWrite51,
|
||||
BlynkWidgetWrite52, BlynkWidgetWrite53, BlynkWidgetWrite54, BlynkWidgetWrite55,
|
||||
BlynkWidgetWrite56, BlynkWidgetWrite57, BlynkWidgetWrite58, BlynkWidgetWrite59,
|
||||
BlynkWidgetWrite60, BlynkWidgetWrite61, BlynkWidgetWrite62, BlynkWidgetWrite63,
|
||||
BlynkWidgetWrite64, BlynkWidgetWrite65, BlynkWidgetWrite66, BlynkWidgetWrite67,
|
||||
BlynkWidgetWrite68, BlynkWidgetWrite69, BlynkWidgetWrite70, BlynkWidgetWrite71,
|
||||
BlynkWidgetWrite72, BlynkWidgetWrite73, BlynkWidgetWrite74, BlynkWidgetWrite75,
|
||||
BlynkWidgetWrite76, BlynkWidgetWrite77, BlynkWidgetWrite78, BlynkWidgetWrite79,
|
||||
BlynkWidgetWrite80, BlynkWidgetWrite81, BlynkWidgetWrite82, BlynkWidgetWrite83,
|
||||
BlynkWidgetWrite84, BlynkWidgetWrite85, BlynkWidgetWrite86, BlynkWidgetWrite87,
|
||||
BlynkWidgetWrite88, BlynkWidgetWrite89, BlynkWidgetWrite90, BlynkWidgetWrite91,
|
||||
BlynkWidgetWrite92, BlynkWidgetWrite93, BlynkWidgetWrite94, BlynkWidgetWrite95,
|
||||
BlynkWidgetWrite96, BlynkWidgetWrite97, BlynkWidgetWrite98, BlynkWidgetWrite99,
|
||||
BlynkWidgetWrite100, BlynkWidgetWrite101, BlynkWidgetWrite102, BlynkWidgetWrite103,
|
||||
BlynkWidgetWrite104, BlynkWidgetWrite105, BlynkWidgetWrite106, BlynkWidgetWrite107,
|
||||
BlynkWidgetWrite108, BlynkWidgetWrite109, BlynkWidgetWrite110, BlynkWidgetWrite111,
|
||||
BlynkWidgetWrite112, BlynkWidgetWrite113, BlynkWidgetWrite114, BlynkWidgetWrite115,
|
||||
BlynkWidgetWrite116, BlynkWidgetWrite117, BlynkWidgetWrite118, BlynkWidgetWrite119,
|
||||
BlynkWidgetWrite120, BlynkWidgetWrite121, BlynkWidgetWrite122, BlynkWidgetWrite123,
|
||||
BlynkWidgetWrite124, BlynkWidgetWrite125, BlynkWidgetWrite126, BlynkWidgetWrite127,
|
||||
#endif
|
||||
};
|
||||
|
||||
WidgetReadHandler GetReadHandler(uint8_t pin)
|
||||
{
|
||||
if (pin >= BLYNK_COUNT_OF(BlynkReadHandlerVector))
|
||||
return NULL;
|
||||
#ifdef BLYNK_HAS_PROGMEM
|
||||
return (WidgetReadHandler)pgm_read_word(&BlynkReadHandlerVector[pin]);
|
||||
#else
|
||||
return BlynkReadHandlerVector[pin];
|
||||
#endif
|
||||
}
|
||||
|
||||
WidgetWriteHandler GetWriteHandler(uint8_t pin)
|
||||
{
|
||||
if (pin >= BLYNK_COUNT_OF(BlynkWriteHandlerVector))
|
||||
return NULL;
|
||||
#ifdef BLYNK_HAS_PROGMEM
|
||||
return (WidgetWriteHandler)pgm_read_word(&BlynkWriteHandlerVector[pin]);
|
||||
#else
|
||||
return BlynkWriteHandlerVector[pin];
|
||||
#endif
|
||||
}
|
||||
511
wled00/src/dependencies/blynk/Blynk/BlynkHandlers.h
Normal file
511
wled00/src/dependencies/blynk/Blynk/BlynkHandlers.h
Normal file
@@ -0,0 +1,511 @@
|
||||
/**
|
||||
* @file BlynkHandlers.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Handlers for virtual pin operations
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkHandlers_h
|
||||
#define BlynkHandlers_h
|
||||
|
||||
#include "BlynkConfig.h"
|
||||
#include "BlynkParam.h"
|
||||
|
||||
// Helper macro
|
||||
|
||||
#define V0 0
|
||||
#define V1 1
|
||||
#define V2 2
|
||||
#define V3 3
|
||||
#define V4 4
|
||||
#define V5 5
|
||||
#define V6 6
|
||||
#define V7 7
|
||||
#define V8 8
|
||||
#define V9 9
|
||||
#define V10 10
|
||||
#define V11 11
|
||||
#define V12 12
|
||||
#define V13 13
|
||||
#define V14 14
|
||||
#define V15 15
|
||||
#define V16 16
|
||||
#define V17 17
|
||||
#define V18 18
|
||||
#define V19 19
|
||||
#define V20 20
|
||||
#define V21 21
|
||||
#define V22 22
|
||||
#define V23 23
|
||||
#define V24 24
|
||||
#define V25 25
|
||||
#define V26 26
|
||||
#define V27 27
|
||||
#define V28 28
|
||||
#define V29 29
|
||||
#define V30 30
|
||||
#define V31 31
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
#define V32 32
|
||||
#define V33 33
|
||||
#define V34 34
|
||||
#define V35 35
|
||||
#define V36 36
|
||||
#define V37 37
|
||||
#define V38 38
|
||||
#define V39 39
|
||||
#define V40 40
|
||||
#define V41 41
|
||||
#define V42 42
|
||||
#define V43 43
|
||||
#define V44 44
|
||||
#define V45 45
|
||||
#define V46 46
|
||||
#define V47 47
|
||||
#define V48 48
|
||||
#define V49 49
|
||||
#define V50 50
|
||||
#define V51 51
|
||||
#define V52 52
|
||||
#define V53 53
|
||||
#define V54 54
|
||||
#define V55 55
|
||||
#define V56 56
|
||||
#define V57 57
|
||||
#define V58 58
|
||||
#define V59 59
|
||||
#define V60 60
|
||||
#define V61 61
|
||||
#define V62 62
|
||||
#define V63 63
|
||||
#define V64 64
|
||||
#define V65 65
|
||||
#define V66 66
|
||||
#define V67 67
|
||||
#define V68 68
|
||||
#define V69 69
|
||||
#define V70 70
|
||||
#define V71 71
|
||||
#define V72 72
|
||||
#define V73 73
|
||||
#define V74 74
|
||||
#define V75 75
|
||||
#define V76 76
|
||||
#define V77 77
|
||||
#define V78 78
|
||||
#define V79 79
|
||||
#define V80 80
|
||||
#define V81 81
|
||||
#define V82 82
|
||||
#define V83 83
|
||||
#define V84 84
|
||||
#define V85 85
|
||||
#define V86 86
|
||||
#define V87 87
|
||||
#define V88 88
|
||||
#define V89 89
|
||||
#define V90 90
|
||||
#define V91 91
|
||||
#define V92 92
|
||||
#define V93 93
|
||||
#define V94 94
|
||||
#define V95 95
|
||||
#define V96 96
|
||||
#define V97 97
|
||||
#define V98 98
|
||||
#define V99 99
|
||||
#define V100 100
|
||||
#define V101 101
|
||||
#define V102 102
|
||||
#define V103 103
|
||||
#define V104 104
|
||||
#define V105 105
|
||||
#define V106 106
|
||||
#define V107 107
|
||||
#define V108 108
|
||||
#define V109 109
|
||||
#define V110 110
|
||||
#define V111 111
|
||||
#define V112 112
|
||||
#define V113 113
|
||||
#define V114 114
|
||||
#define V115 115
|
||||
#define V116 116
|
||||
#define V117 117
|
||||
#define V118 118
|
||||
#define V119 119
|
||||
#define V120 120
|
||||
#define V121 121
|
||||
#define V122 122
|
||||
#define V123 123
|
||||
#define V124 124
|
||||
#define V125 125
|
||||
#define V126 126
|
||||
#define V127 127
|
||||
#endif
|
||||
|
||||
// Initial syntax:
|
||||
#define BLYNK_WRITE_2(pin) \
|
||||
void BlynkWidgetWrite ## pin (BlynkReq BLYNK_UNUSED &request, const BlynkParam BLYNK_UNUSED ¶m)
|
||||
|
||||
#define BLYNK_READ_2(pin) \
|
||||
void BlynkWidgetRead ## pin (BlynkReq BLYNK_UNUSED &request)
|
||||
|
||||
#define BLYNK_WRITE_DEFAULT() BLYNK_WRITE_2(Default)
|
||||
#define BLYNK_READ_DEFAULT() BLYNK_READ_2(Default)
|
||||
|
||||
#define BLYNK_WRITE(pin) BLYNK_WRITE_2(pin)
|
||||
#define BLYNK_READ(pin) BLYNK_READ_2(pin)
|
||||
|
||||
// New, more readable syntax:
|
||||
#define BLYNK_IN_2(pin) \
|
||||
void BlynkWidgetWrite ## pin (BlynkReq BLYNK_UNUSED &request, const BlynkParam BLYNK_UNUSED &getValue)
|
||||
|
||||
#define BLYNK_OUT_2(pin) \
|
||||
void BlynkWidgetRead ## pin (BlynkReq BLYNK_UNUSED &request)
|
||||
|
||||
#define BLYNK_INPUT_DEFAULT() BLYNK_IN_2(Default)
|
||||
#define BLYNK_OUTPUT_DEFAULT() BLYNK_OUT_2(Default)
|
||||
|
||||
#define BLYNK_INPUT(pin) BLYNK_IN_2(pin)
|
||||
#define BLYNK_OUTPUT(pin) BLYNK_OUT_2(pin)
|
||||
|
||||
// Additional handlers
|
||||
#define BLYNK_CONNECTED() void BlynkOnConnected()
|
||||
#define BLYNK_DISCONNECTED() void BlynkOnDisconnected()
|
||||
|
||||
// Advanced functions
|
||||
|
||||
#define BLYNK_VAR_INT(name, pin) \
|
||||
int name; \
|
||||
BLYNK_WRITE(pin) { name = param.asInt(); } \
|
||||
BLYNK_READ(pin) { Blynk.virtualWrite(pin, name); }
|
||||
|
||||
#define BLYNK_VAR_LONG(name, pin) \
|
||||
long name; \
|
||||
BLYNK_WRITE(pin) { name = param.asLong(); } \
|
||||
BLYNK_READ(pin) { Blynk.virtualWrite(pin, name); }
|
||||
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
#define BLYNK_VAR_DOUBLE(name, pin) \
|
||||
double name; \
|
||||
BLYNK_WRITE(pin) { name = param.asDouble(); } \
|
||||
BLYNK_READ(pin) { Blynk.virtualWrite(pin, name); }
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO
|
||||
#define BLYNK_VAR_STRING(name, pin) \
|
||||
String name; \
|
||||
BLYNK_WRITE(pin) { name = param.asStr(); } \
|
||||
BLYNK_READ(pin) { Blynk.virtualWrite(pin, name); }
|
||||
#endif
|
||||
|
||||
// Default read/write handlers (you can redefine them in your code)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct BlynkReq
|
||||
{
|
||||
uint8_t pin;
|
||||
};
|
||||
|
||||
typedef void (*WidgetReadHandler)(BlynkReq BLYNK_UNUSED &request);
|
||||
typedef void (*WidgetWriteHandler)(BlynkReq BLYNK_UNUSED &request, const BlynkParam BLYNK_UNUSED ¶m);
|
||||
|
||||
WidgetReadHandler GetReadHandler(uint8_t pin);
|
||||
WidgetWriteHandler GetWriteHandler(uint8_t pin);
|
||||
|
||||
// Declare placeholders
|
||||
BLYNK_READ();
|
||||
BLYNK_WRITE();
|
||||
void BlynkNoOpCbk();
|
||||
|
||||
// Declare all pin handlers (you can redefine them in your code)
|
||||
BLYNK_CONNECTED();
|
||||
BLYNK_DISCONNECTED();
|
||||
|
||||
// Internal Virtual Pins
|
||||
BLYNK_WRITE(InternalPinACON);
|
||||
BLYNK_WRITE(InternalPinADIS);
|
||||
BLYNK_WRITE(InternalPinRTC);
|
||||
BLYNK_WRITE(InternalPinOTA);
|
||||
|
||||
// Aliases
|
||||
#define BLYNK_APP_CONNECTED() BLYNK_WRITE(InternalPinACON)
|
||||
#define BLYNK_APP_DISCONNECTED() BLYNK_WRITE(InternalPinADIS)
|
||||
|
||||
// Regular Virtual Pins
|
||||
BLYNK_READ_DEFAULT();
|
||||
BLYNK_WRITE_DEFAULT();
|
||||
|
||||
BLYNK_READ(0 );
|
||||
BLYNK_READ(1 );
|
||||
BLYNK_READ(2 );
|
||||
BLYNK_READ(3 );
|
||||
BLYNK_READ(4 );
|
||||
BLYNK_READ(5 );
|
||||
BLYNK_READ(6 );
|
||||
BLYNK_READ(7 );
|
||||
BLYNK_READ(8 );
|
||||
BLYNK_READ(9 );
|
||||
BLYNK_READ(10);
|
||||
BLYNK_READ(11);
|
||||
BLYNK_READ(12);
|
||||
BLYNK_READ(13);
|
||||
BLYNK_READ(14);
|
||||
BLYNK_READ(15);
|
||||
BLYNK_READ(16);
|
||||
BLYNK_READ(17);
|
||||
BLYNK_READ(18);
|
||||
BLYNK_READ(19);
|
||||
BLYNK_READ(20);
|
||||
BLYNK_READ(21);
|
||||
BLYNK_READ(22);
|
||||
BLYNK_READ(23);
|
||||
BLYNK_READ(24);
|
||||
BLYNK_READ(25);
|
||||
BLYNK_READ(26);
|
||||
BLYNK_READ(27);
|
||||
BLYNK_READ(28);
|
||||
BLYNK_READ(29);
|
||||
BLYNK_READ(30);
|
||||
BLYNK_READ(31);
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
BLYNK_READ(32);
|
||||
BLYNK_READ(33);
|
||||
BLYNK_READ(34);
|
||||
BLYNK_READ(35);
|
||||
BLYNK_READ(36);
|
||||
BLYNK_READ(37);
|
||||
BLYNK_READ(38);
|
||||
BLYNK_READ(39);
|
||||
BLYNK_READ(40);
|
||||
BLYNK_READ(41);
|
||||
BLYNK_READ(42);
|
||||
BLYNK_READ(43);
|
||||
BLYNK_READ(44);
|
||||
BLYNK_READ(45);
|
||||
BLYNK_READ(46);
|
||||
BLYNK_READ(47);
|
||||
BLYNK_READ(48);
|
||||
BLYNK_READ(49);
|
||||
BLYNK_READ(50);
|
||||
BLYNK_READ(51);
|
||||
BLYNK_READ(52);
|
||||
BLYNK_READ(53);
|
||||
BLYNK_READ(54);
|
||||
BLYNK_READ(55);
|
||||
BLYNK_READ(56);
|
||||
BLYNK_READ(57);
|
||||
BLYNK_READ(58);
|
||||
BLYNK_READ(59);
|
||||
BLYNK_READ(60);
|
||||
BLYNK_READ(61);
|
||||
BLYNK_READ(62);
|
||||
BLYNK_READ(63);
|
||||
BLYNK_READ(64);
|
||||
BLYNK_READ(65);
|
||||
BLYNK_READ(66);
|
||||
BLYNK_READ(67);
|
||||
BLYNK_READ(68);
|
||||
BLYNK_READ(69);
|
||||
BLYNK_READ(70);
|
||||
BLYNK_READ(71);
|
||||
BLYNK_READ(72);
|
||||
BLYNK_READ(73);
|
||||
BLYNK_READ(74);
|
||||
BLYNK_READ(75);
|
||||
BLYNK_READ(76);
|
||||
BLYNK_READ(77);
|
||||
BLYNK_READ(78);
|
||||
BLYNK_READ(79);
|
||||
BLYNK_READ(80);
|
||||
BLYNK_READ(81);
|
||||
BLYNK_READ(82);
|
||||
BLYNK_READ(83);
|
||||
BLYNK_READ(84);
|
||||
BLYNK_READ(85);
|
||||
BLYNK_READ(86);
|
||||
BLYNK_READ(87);
|
||||
BLYNK_READ(88);
|
||||
BLYNK_READ(89);
|
||||
BLYNK_READ(90);
|
||||
BLYNK_READ(91);
|
||||
BLYNK_READ(92);
|
||||
BLYNK_READ(93);
|
||||
BLYNK_READ(94);
|
||||
BLYNK_READ(95);
|
||||
BLYNK_READ(96);
|
||||
BLYNK_READ(97);
|
||||
BLYNK_READ(98);
|
||||
BLYNK_READ(99);
|
||||
BLYNK_READ(100);
|
||||
BLYNK_READ(101);
|
||||
BLYNK_READ(102);
|
||||
BLYNK_READ(103);
|
||||
BLYNK_READ(104);
|
||||
BLYNK_READ(105);
|
||||
BLYNK_READ(106);
|
||||
BLYNK_READ(107);
|
||||
BLYNK_READ(108);
|
||||
BLYNK_READ(109);
|
||||
BLYNK_READ(110);
|
||||
BLYNK_READ(111);
|
||||
BLYNK_READ(112);
|
||||
BLYNK_READ(113);
|
||||
BLYNK_READ(114);
|
||||
BLYNK_READ(115);
|
||||
BLYNK_READ(116);
|
||||
BLYNK_READ(117);
|
||||
BLYNK_READ(118);
|
||||
BLYNK_READ(119);
|
||||
BLYNK_READ(120);
|
||||
BLYNK_READ(121);
|
||||
BLYNK_READ(122);
|
||||
BLYNK_READ(123);
|
||||
BLYNK_READ(124);
|
||||
BLYNK_READ(125);
|
||||
BLYNK_READ(126);
|
||||
BLYNK_READ(127);
|
||||
#endif
|
||||
|
||||
BLYNK_WRITE(0 );
|
||||
BLYNK_WRITE(1 );
|
||||
BLYNK_WRITE(2 );
|
||||
BLYNK_WRITE(3 );
|
||||
BLYNK_WRITE(4 );
|
||||
BLYNK_WRITE(5 );
|
||||
BLYNK_WRITE(6 );
|
||||
BLYNK_WRITE(7 );
|
||||
BLYNK_WRITE(8 );
|
||||
BLYNK_WRITE(9 );
|
||||
BLYNK_WRITE(10);
|
||||
BLYNK_WRITE(11);
|
||||
BLYNK_WRITE(12);
|
||||
BLYNK_WRITE(13);
|
||||
BLYNK_WRITE(14);
|
||||
BLYNK_WRITE(15);
|
||||
BLYNK_WRITE(16);
|
||||
BLYNK_WRITE(17);
|
||||
BLYNK_WRITE(18);
|
||||
BLYNK_WRITE(19);
|
||||
BLYNK_WRITE(20);
|
||||
BLYNK_WRITE(21);
|
||||
BLYNK_WRITE(22);
|
||||
BLYNK_WRITE(23);
|
||||
BLYNK_WRITE(24);
|
||||
BLYNK_WRITE(25);
|
||||
BLYNK_WRITE(26);
|
||||
BLYNK_WRITE(27);
|
||||
BLYNK_WRITE(28);
|
||||
BLYNK_WRITE(29);
|
||||
BLYNK_WRITE(30);
|
||||
BLYNK_WRITE(31);
|
||||
#ifdef BLYNK_USE_128_VPINS
|
||||
BLYNK_WRITE(32);
|
||||
BLYNK_WRITE(33);
|
||||
BLYNK_WRITE(34);
|
||||
BLYNK_WRITE(35);
|
||||
BLYNK_WRITE(36);
|
||||
BLYNK_WRITE(37);
|
||||
BLYNK_WRITE(38);
|
||||
BLYNK_WRITE(39);
|
||||
BLYNK_WRITE(40);
|
||||
BLYNK_WRITE(41);
|
||||
BLYNK_WRITE(42);
|
||||
BLYNK_WRITE(43);
|
||||
BLYNK_WRITE(44);
|
||||
BLYNK_WRITE(45);
|
||||
BLYNK_WRITE(46);
|
||||
BLYNK_WRITE(47);
|
||||
BLYNK_WRITE(48);
|
||||
BLYNK_WRITE(49);
|
||||
BLYNK_WRITE(50);
|
||||
BLYNK_WRITE(51);
|
||||
BLYNK_WRITE(52);
|
||||
BLYNK_WRITE(53);
|
||||
BLYNK_WRITE(54);
|
||||
BLYNK_WRITE(55);
|
||||
BLYNK_WRITE(56);
|
||||
BLYNK_WRITE(57);
|
||||
BLYNK_WRITE(58);
|
||||
BLYNK_WRITE(59);
|
||||
BLYNK_WRITE(60);
|
||||
BLYNK_WRITE(61);
|
||||
BLYNK_WRITE(62);
|
||||
BLYNK_WRITE(63);
|
||||
BLYNK_WRITE(64);
|
||||
BLYNK_WRITE(65);
|
||||
BLYNK_WRITE(66);
|
||||
BLYNK_WRITE(67);
|
||||
BLYNK_WRITE(68);
|
||||
BLYNK_WRITE(69);
|
||||
BLYNK_WRITE(70);
|
||||
BLYNK_WRITE(71);
|
||||
BLYNK_WRITE(72);
|
||||
BLYNK_WRITE(73);
|
||||
BLYNK_WRITE(74);
|
||||
BLYNK_WRITE(75);
|
||||
BLYNK_WRITE(76);
|
||||
BLYNK_WRITE(77);
|
||||
BLYNK_WRITE(78);
|
||||
BLYNK_WRITE(79);
|
||||
BLYNK_WRITE(80);
|
||||
BLYNK_WRITE(81);
|
||||
BLYNK_WRITE(82);
|
||||
BLYNK_WRITE(83);
|
||||
BLYNK_WRITE(84);
|
||||
BLYNK_WRITE(85);
|
||||
BLYNK_WRITE(86);
|
||||
BLYNK_WRITE(87);
|
||||
BLYNK_WRITE(88);
|
||||
BLYNK_WRITE(89);
|
||||
BLYNK_WRITE(90);
|
||||
BLYNK_WRITE(91);
|
||||
BLYNK_WRITE(92);
|
||||
BLYNK_WRITE(93);
|
||||
BLYNK_WRITE(94);
|
||||
BLYNK_WRITE(95);
|
||||
BLYNK_WRITE(96);
|
||||
BLYNK_WRITE(97);
|
||||
BLYNK_WRITE(98);
|
||||
BLYNK_WRITE(99);
|
||||
BLYNK_WRITE(100);
|
||||
BLYNK_WRITE(101);
|
||||
BLYNK_WRITE(102);
|
||||
BLYNK_WRITE(103);
|
||||
BLYNK_WRITE(104);
|
||||
BLYNK_WRITE(105);
|
||||
BLYNK_WRITE(106);
|
||||
BLYNK_WRITE(107);
|
||||
BLYNK_WRITE(108);
|
||||
BLYNK_WRITE(109);
|
||||
BLYNK_WRITE(110);
|
||||
BLYNK_WRITE(111);
|
||||
BLYNK_WRITE(112);
|
||||
BLYNK_WRITE(113);
|
||||
BLYNK_WRITE(114);
|
||||
BLYNK_WRITE(115);
|
||||
BLYNK_WRITE(116);
|
||||
BLYNK_WRITE(117);
|
||||
BLYNK_WRITE(118);
|
||||
BLYNK_WRITE(119);
|
||||
BLYNK_WRITE(120);
|
||||
BLYNK_WRITE(121);
|
||||
BLYNK_WRITE(122);
|
||||
BLYNK_WRITE(123);
|
||||
BLYNK_WRITE(124);
|
||||
BLYNK_WRITE(125);
|
||||
BLYNK_WRITE(126);
|
||||
BLYNK_WRITE(127);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
379
wled00/src/dependencies/blynk/Blynk/BlynkParam.h
Normal file
379
wled00/src/dependencies/blynk/Blynk/BlynkParam.h
Normal file
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* @file BlynkParam.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Container for handler parameters
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkParam_h
|
||||
#define BlynkParam_h
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "BlynkConfig.h"
|
||||
#include "BlynkDebug.h"
|
||||
|
||||
#define BLYNK_PARAM_KV(k, v) k "\0" v "\0"
|
||||
|
||||
class BlynkParam
|
||||
{
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator(const char* c, const char* l) : ptr(c), limit(l) {}
|
||||
static iterator invalid() { return iterator(NULL, NULL); }
|
||||
|
||||
operator const char* () const { return asStr(); }
|
||||
operator int () const { return asInt(); }
|
||||
const char* asStr() const { return ptr; }
|
||||
const char* asString() const { return ptr; }
|
||||
int asInt() const { if(!isValid()) return 0; return atoi(ptr); }
|
||||
long asLong() const { if(!isValid()) return 0; return atol(ptr); }
|
||||
//long long asLongLong() const { return atoll(ptr); }
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
double asDouble() const { if(!isValid()) return 0; return atof(ptr); }
|
||||
float asFloat() const { if(!isValid()) return 0; return atof(ptr); }
|
||||
#endif
|
||||
bool isValid() const { return ptr != NULL && ptr < limit; }
|
||||
bool isEmpty() const { if(!isValid()) return true; return *ptr == '\0'; }
|
||||
|
||||
bool operator < (const iterator& it) const { return ptr < it.ptr; }
|
||||
bool operator >= (const iterator& it) const { return ptr >= it.ptr; }
|
||||
|
||||
iterator& operator ++() {
|
||||
if(isValid()) {
|
||||
ptr += strlen(ptr) + 1;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
const char* ptr;
|
||||
const char* limit;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit
|
||||
BlynkParam(void* addr, size_t length)
|
||||
: buff((char*)addr), len(length), buff_size(length)
|
||||
{}
|
||||
|
||||
explicit
|
||||
BlynkParam(void* addr, size_t length, size_t buffsize)
|
||||
: buff((char*)addr), len(length), buff_size(buffsize)
|
||||
{}
|
||||
|
||||
const char* asStr() const { return buff; }
|
||||
const char* asString() const { return buff; }
|
||||
int asInt() const { return atoi(buff); }
|
||||
long asLong() const { return atol(buff); }
|
||||
//long long asLongLong() const { return atoll(buff); }
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
double asDouble() const { return atof(buff); }
|
||||
float asFloat() const { return atof(buff); }
|
||||
#endif
|
||||
bool isEmpty() const { return *buff == '\0'; }
|
||||
|
||||
iterator begin() const { return iterator(buff, buff+len); }
|
||||
iterator end() const { return iterator(buff+len, buff+len); }
|
||||
|
||||
iterator operator[](int index) const;
|
||||
iterator operator[](const char* key) const;
|
||||
|
||||
void* getBuffer() const { return (void*)buff; }
|
||||
size_t getLength() const { return len; }
|
||||
|
||||
// Modification
|
||||
void add(int value);
|
||||
void add(unsigned int value);
|
||||
void add(long value);
|
||||
void add(unsigned long value);
|
||||
void add(long long value);
|
||||
void add(unsigned long long value);
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
void add(float value);
|
||||
void add(double value);
|
||||
#endif
|
||||
void add(const char* str);
|
||||
void add(const void* b, size_t l);
|
||||
#if defined(ARDUINO) || defined(SPARK) || defined(PARTICLE)
|
||||
void add(const String& str);
|
||||
#if defined(BLYNK_HAS_PROGMEM)
|
||||
void add(const __FlashStringHelper* str);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void add_multi(T last) {
|
||||
add(last);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void add_multi(T head, Args... tail) {
|
||||
add(head);
|
||||
add_multi(tail...);
|
||||
}
|
||||
|
||||
template <typename TV>
|
||||
void add_key(const char* key, const TV& val) {
|
||||
add(key);
|
||||
add(val);
|
||||
}
|
||||
|
||||
protected:
|
||||
char* buff;
|
||||
size_t len;
|
||||
size_t buff_size;
|
||||
};
|
||||
|
||||
|
||||
class BlynkParamAllocated
|
||||
: public BlynkParam
|
||||
{
|
||||
public:
|
||||
BlynkParamAllocated(size_t size)
|
||||
: BlynkParam(malloc(size), 0, size)
|
||||
{}
|
||||
~BlynkParamAllocated() {
|
||||
free(buff);
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
BlynkParam::iterator BlynkParam::operator[](int index) const
|
||||
{
|
||||
const iterator e = end();
|
||||
for (iterator it = begin(); it < e; ++it) {
|
||||
if (!index--) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return iterator::invalid();
|
||||
}
|
||||
|
||||
inline
|
||||
BlynkParam::iterator BlynkParam::operator[](const char* key) const
|
||||
{
|
||||
const iterator e = end();
|
||||
for (iterator it = begin(); it < e; ++it) {
|
||||
if (!strcmp(it.asStr(), key)) {
|
||||
return ++it;
|
||||
}
|
||||
++it;
|
||||
if (it >= e) break;
|
||||
}
|
||||
return iterator::invalid();
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(const void* b, size_t l)
|
||||
{
|
||||
if (len + l > buff_size)
|
||||
return;
|
||||
memcpy(buff+len, b, l);
|
||||
len += l;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(const char* str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
buff[len++] = '\0';
|
||||
return;
|
||||
}
|
||||
add(str, strlen(str)+1);
|
||||
}
|
||||
|
||||
#if defined(ARDUINO) || defined(SPARK) || defined(PARTICLE)
|
||||
inline
|
||||
void BlynkParam::add(const String& str)
|
||||
{
|
||||
#if defined(ARDUINO_AVR_DIGISPARK) \
|
||||
|| defined(__ARDUINO_X86__) \
|
||||
|| defined(__RFduino__)
|
||||
|
||||
size_t len = str.length()+1;
|
||||
char buff[len];
|
||||
const_cast<String&>(str).toCharArray(buff, len);
|
||||
add(buff, len);
|
||||
#else
|
||||
add(str.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BLYNK_HAS_PROGMEM)
|
||||
|
||||
inline
|
||||
void BlynkParam::add(const __FlashStringHelper* ifsh)
|
||||
{
|
||||
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
|
||||
size_t l = strlen_P(p) + 1;
|
||||
if (len + l > buff_size)
|
||||
return;
|
||||
memcpy_P(buff+len, p, l);
|
||||
len += l;
|
||||
buff[len] = '\0';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__) || defined (ARDUINO_ARCH_ARC32)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
inline
|
||||
void BlynkParam::add(int value)
|
||||
{
|
||||
char str[2 + 8 * sizeof(value)];
|
||||
itoa(value, str, 10);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(unsigned int value)
|
||||
{
|
||||
char str[1 + 8 * sizeof(value)];
|
||||
utoa(value, str, 10);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(long value)
|
||||
{
|
||||
char str[2 + 8 * sizeof(value)];
|
||||
ltoa(value, str, 10);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(unsigned long value)
|
||||
{
|
||||
char str[1 + 8 * sizeof(value)];
|
||||
ultoa(value, str, 10);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(long long value) // TODO: this currently adds just a long
|
||||
{
|
||||
char str[2 + 8 * sizeof(value)];
|
||||
ltoa(value, str, 10);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(unsigned long long value) // TODO: this currently adds just a long
|
||||
{
|
||||
char str[1 + 8 * sizeof(value)];
|
||||
ultoa(value, str, 10);
|
||||
add(str);
|
||||
}
|
||||
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
|
||||
inline
|
||||
void BlynkParam::add(float value)
|
||||
{
|
||||
char str[33];
|
||||
dtostrf(value, 5, 3, str);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(double value)
|
||||
{
|
||||
char str[33];
|
||||
dtostrf(value, 5, 7, str);
|
||||
add(str);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
inline
|
||||
void BlynkParam::add(int value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%i", value)+1;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(unsigned int value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%u", value)+1;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(long value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%li", value)+1;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(unsigned long value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%lu", value)+1;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(long long value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%lli", value)+1;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(unsigned long long value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%llu", value)+1;
|
||||
}
|
||||
|
||||
#ifndef BLYNK_NO_FLOAT
|
||||
|
||||
#if defined(BLYNK_USE_INTERNAL_DTOSTRF)
|
||||
|
||||
extern char* dtostrf_internal(double number, signed char width, unsigned char prec, char *s);
|
||||
|
||||
inline
|
||||
void BlynkParam::add(float value)
|
||||
{
|
||||
char str[33];
|
||||
dtostrf_internal(value, 5, 3, str);
|
||||
add(str);
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(double value)
|
||||
{
|
||||
char str[33];
|
||||
dtostrf_internal(value, 5, 7, str);
|
||||
add(str);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline
|
||||
void BlynkParam::add(float value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%2.3f", value)+1;
|
||||
}
|
||||
|
||||
inline
|
||||
void BlynkParam::add(double value)
|
||||
{
|
||||
len += snprintf(buff+len, buff_size-len, "%2.7f", value)+1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
535
wled00/src/dependencies/blynk/Blynk/BlynkProtocol.h
Normal file
535
wled00/src/dependencies/blynk/Blynk/BlynkProtocol.h
Normal file
@@ -0,0 +1,535 @@
|
||||
/**
|
||||
* @file BlynkProtocol.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Blynk protocol implementation
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkProtocol_h
|
||||
#define BlynkProtocol_h
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "BlynkDebug.h"
|
||||
#include "BlynkProtocolDefs.h"
|
||||
#include "BlynkApi.h"
|
||||
#include "BlynkUtility.h"
|
||||
|
||||
template <class Transp>
|
||||
class BlynkProtocol
|
||||
: public BlynkApi< BlynkProtocol<Transp> >
|
||||
{
|
||||
friend class BlynkApi< BlynkProtocol<Transp> >;
|
||||
public:
|
||||
enum BlynkState {
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
DISCONNECTED,
|
||||
};
|
||||
|
||||
BlynkProtocol(Transp& transp)
|
||||
: conn(transp)
|
||||
, authkey(NULL)
|
||||
, redir_serv(NULL)
|
||||
, lastActivityIn(0)
|
||||
, lastActivityOut(0)
|
||||
, lastHeartbeat(0)
|
||||
, msgIdOut(0)
|
||||
, msgIdOutOverride(0)
|
||||
, nesting(0)
|
||||
, state(CONNECTING)
|
||||
{}
|
||||
|
||||
bool connected() { return state == CONNECTED; }
|
||||
|
||||
bool connect(uint32_t timeout = BLYNK_TIMEOUT_MS*3) {
|
||||
conn.disconnect();
|
||||
state = CONNECTING;
|
||||
millis_time_t started = BlynkMillis();
|
||||
while ((state != CONNECTED) &&
|
||||
(BlynkMillis() - started < timeout))
|
||||
{
|
||||
run();
|
||||
}
|
||||
return state == CONNECTED;
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
conn.disconnect();
|
||||
state = DISCONNECTED;
|
||||
BLYNK_LOG1(BLYNK_F("Disconnected"));
|
||||
}
|
||||
|
||||
bool run(bool avail = false);
|
||||
|
||||
// TODO: Fixme
|
||||
void startSession() {
|
||||
conn.connect();
|
||||
state = CONNECTING;
|
||||
msgIdOut = 0;
|
||||
lastHeartbeat = lastActivityIn = lastActivityOut = (BlynkMillis() - 5000UL);
|
||||
}
|
||||
|
||||
void sendCmd(uint8_t cmd, uint16_t id = 0, const void* data = NULL, size_t length = 0, const void* data2 = NULL, size_t length2 = 0);
|
||||
|
||||
private:
|
||||
|
||||
void internalReconnect() {
|
||||
state = CONNECTING;
|
||||
conn.disconnect();
|
||||
BlynkOnDisconnected();
|
||||
}
|
||||
|
||||
int readHeader(BlynkHeader& hdr);
|
||||
uint16_t getNextMsgId();
|
||||
|
||||
protected:
|
||||
void begin(const char* auth) {
|
||||
this->authkey = auth;
|
||||
lastHeartbeat = lastActivityIn = lastActivityOut = (BlynkMillis() - 5000UL);
|
||||
|
||||
#if defined(BLYNK_NO_FANCY_LOGO)
|
||||
BLYNK_LOG1(BLYNK_F("Blynk v" BLYNK_VERSION " on " BLYNK_INFO_DEVICE));
|
||||
#else
|
||||
BLYNK_LOG1(BLYNK_F(BLYNK_NEWLINE
|
||||
" ___ __ __" BLYNK_NEWLINE
|
||||
" / _ )/ /_ _____ / /__" BLYNK_NEWLINE
|
||||
" / _ / / // / _ \\/ '_/" BLYNK_NEWLINE
|
||||
" /____/_/\\_, /_//_/_/\\_\\" BLYNK_NEWLINE
|
||||
" /___/ v" BLYNK_VERSION " on " BLYNK_INFO_DEVICE BLYNK_NEWLINE
|
||||
BLYNK_NEWLINE
|
||||
" Give Blynk a Github star! => https://github.com/blynkkk/blynk-library" BLYNK_NEWLINE
|
||||
));
|
||||
#endif
|
||||
}
|
||||
bool processInput(void);
|
||||
|
||||
Transp& conn;
|
||||
|
||||
private:
|
||||
const char* authkey;
|
||||
char* redir_serv;
|
||||
millis_time_t lastActivityIn;
|
||||
millis_time_t lastActivityOut;
|
||||
union {
|
||||
millis_time_t lastHeartbeat;
|
||||
millis_time_t lastLogin;
|
||||
};
|
||||
uint16_t msgIdOut;
|
||||
uint16_t msgIdOutOverride;
|
||||
uint8_t nesting;
|
||||
protected:
|
||||
BlynkState state;
|
||||
};
|
||||
|
||||
template <class Transp>
|
||||
bool BlynkProtocol<Transp>::run(bool avail)
|
||||
{
|
||||
BLYNK_RUN_YIELD();
|
||||
|
||||
if (state == DISCONNECTED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Detect nesting
|
||||
BlynkHelperAutoInc guard(nesting);
|
||||
if (msgIdOutOverride || nesting > 2) {
|
||||
//BLYNK_LOG1(BLYNK_F("Nested run() skipped"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (conn.connected()) {
|
||||
while (avail || conn.available() > 0) {
|
||||
//BLYNK_LOG2(BLYNK_F("Available: "), conn.available());
|
||||
//const unsigned long t = micros();
|
||||
if (!processInput()) {
|
||||
conn.disconnect();
|
||||
// TODO: Only when in direct mode?
|
||||
#ifdef BLYNK_USE_DIRECT_CONNECT
|
||||
state = CONNECTING;
|
||||
#endif
|
||||
BlynkOnDisconnected();
|
||||
return false;
|
||||
}
|
||||
avail = false;
|
||||
//BLYNK_LOG2(BLYNK_F("Proc time: "), micros() - t);
|
||||
}
|
||||
}
|
||||
|
||||
const millis_time_t t = BlynkMillis();
|
||||
|
||||
// Update connection status after running commands
|
||||
const bool tconn = conn.connected();
|
||||
|
||||
if (state == CONNECTED) {
|
||||
if (!tconn) {
|
||||
lastHeartbeat = t;
|
||||
internalReconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t - lastActivityIn > (1000UL * BLYNK_HEARTBEAT + BLYNK_TIMEOUT_MS*3)) {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG6(BLYNK_F("Heartbeat timeout: "), t, BLYNK_F(", "), lastActivityIn, BLYNK_F(", "), lastHeartbeat);
|
||||
#else
|
||||
BLYNK_LOG1(BLYNK_F("Heartbeat timeout"));
|
||||
#endif
|
||||
internalReconnect();
|
||||
return false;
|
||||
} else if ((t - lastActivityIn > 1000UL * BLYNK_HEARTBEAT ||
|
||||
t - lastActivityOut > 1000UL * BLYNK_HEARTBEAT) &&
|
||||
t - lastHeartbeat > BLYNK_TIMEOUT_MS)
|
||||
{
|
||||
// Send ping if we didn't either send or receive something
|
||||
// for BLYNK_HEARTBEAT seconds
|
||||
sendCmd(BLYNK_CMD_PING);
|
||||
lastHeartbeat = t;
|
||||
}
|
||||
} else if (state == CONNECTING) {
|
||||
#ifdef BLYNK_USE_DIRECT_CONNECT
|
||||
if (!tconn)
|
||||
conn.connect();
|
||||
#else
|
||||
if (tconn && (t - lastLogin > BLYNK_TIMEOUT_MS)) {
|
||||
BLYNK_LOG1(BLYNK_F("Login timeout"));
|
||||
conn.disconnect();
|
||||
state = CONNECTING;
|
||||
return false;
|
||||
} else if (!tconn && (t - lastLogin > 5000UL)) {
|
||||
conn.disconnect();
|
||||
if (!conn.connect()) {
|
||||
lastLogin = t;
|
||||
return false;
|
||||
}
|
||||
|
||||
msgIdOut = 1;
|
||||
sendCmd(BLYNK_CMD_LOGIN, 1, authkey, strlen(authkey));
|
||||
lastLogin = lastActivityOut;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Transp>
|
||||
BLYNK_FORCE_INLINE
|
||||
bool BlynkProtocol<Transp>::processInput(void)
|
||||
{
|
||||
BlynkHeader hdr;
|
||||
const int ret = readHeader(hdr);
|
||||
|
||||
if (ret == 0) {
|
||||
return true; // Considered OK (no data on input)
|
||||
}
|
||||
|
||||
if (ret < 0 || hdr.msg_id == 0) {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG2(BLYNK_F("Bad hdr len: "), ret);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hdr.type == BLYNK_CMD_RESPONSE) {
|
||||
lastActivityIn = BlynkMillis();
|
||||
|
||||
#ifndef BLYNK_USE_DIRECT_CONNECT
|
||||
if (state == CONNECTING && (1 == hdr.msg_id)) {
|
||||
switch (hdr.length) {
|
||||
case BLYNK_SUCCESS:
|
||||
case BLYNK_ALREADY_REGISTERED:
|
||||
BLYNK_LOG3(BLYNK_F("Ready (ping: "), lastActivityIn-lastHeartbeat, BLYNK_F("ms)."));
|
||||
lastHeartbeat = lastActivityIn;
|
||||
state = CONNECTED;
|
||||
#ifdef BLYNK_DEBUG
|
||||
if (size_t ram = BlynkFreeRam()) {
|
||||
BLYNK_LOG2(BLYNK_F("Free RAM: "), ram);
|
||||
}
|
||||
#endif
|
||||
this->sendInfo();
|
||||
BLYNK_RUN_YIELD();
|
||||
BlynkOnConnected();
|
||||
return true;
|
||||
case BLYNK_INVALID_TOKEN:
|
||||
BLYNK_LOG1(BLYNK_F("Invalid auth token"));
|
||||
break;
|
||||
default:
|
||||
BLYNK_LOG2(BLYNK_F("Connect failed. code: "), hdr.length);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (BLYNK_NOT_AUTHENTICATED == hdr.length) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
// TODO: return code may indicate App presence
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hdr.length > BLYNK_MAX_READBYTES) {
|
||||
BLYNK_LOG2(BLYNK_F("Packet too big: "), hdr.length);
|
||||
// TODO: Flush
|
||||
internalReconnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t inputBuffer[hdr.length+1]; // Add 1 to zero-terminate
|
||||
if (hdr.length != conn.read(inputBuffer, hdr.length)) {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG1(BLYNK_F("Can't read body"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
inputBuffer[hdr.length] = '\0';
|
||||
|
||||
BLYNK_DBG_DUMP(">", inputBuffer, hdr.length);
|
||||
|
||||
lastActivityIn = BlynkMillis();
|
||||
|
||||
switch (hdr.type)
|
||||
{
|
||||
case BLYNK_CMD_LOGIN: {
|
||||
#ifdef BLYNK_USE_DIRECT_CONNECT
|
||||
if (strncmp(authkey, (char*)inputBuffer, 32)) {
|
||||
BLYNK_LOG1(BLYNK_F("Invalid token"));
|
||||
sendCmd(BLYNK_CMD_RESPONSE, hdr.msg_id, NULL, BLYNK_INVALID_TOKEN);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (state == CONNECTING) {
|
||||
BLYNK_LOG1(BLYNK_F("Ready"));
|
||||
state = CONNECTED;
|
||||
#ifdef BLYNK_DEBUG
|
||||
if (size_t ram = BlynkFreeRam()) {
|
||||
BLYNK_LOG2(BLYNK_F("Free RAM: "), ram);
|
||||
}
|
||||
#endif
|
||||
this->sendInfo();
|
||||
BLYNK_RUN_YIELD();
|
||||
BlynkOnConnected();
|
||||
}
|
||||
sendCmd(BLYNK_CMD_RESPONSE, hdr.msg_id, NULL, BLYNK_SUCCESS);
|
||||
} break;
|
||||
case BLYNK_CMD_PING: {
|
||||
sendCmd(BLYNK_CMD_RESPONSE, hdr.msg_id, NULL, BLYNK_SUCCESS);
|
||||
} break;
|
||||
case BLYNK_CMD_REDIRECT: {
|
||||
if (!redir_serv) {
|
||||
redir_serv = (char*)malloc(32);
|
||||
}
|
||||
BlynkParam param(inputBuffer, hdr.length);
|
||||
uint16_t redir_port = BLYNK_DEFAULT_PORT; // TODO: Fixit
|
||||
|
||||
BlynkParam::iterator it = param.begin();
|
||||
if (it >= param.end())
|
||||
return false;
|
||||
strncpy(redir_serv, it.asStr(), 32);
|
||||
if (++it < param.end())
|
||||
redir_port = it.asLong();
|
||||
BLYNK_LOG4(BLYNK_F("Redirecting to "), redir_serv, ':', redir_port);
|
||||
conn.disconnect();
|
||||
conn.begin(redir_serv, redir_port);
|
||||
state = CONNECTING;
|
||||
lastHeartbeat = lastActivityIn = lastActivityOut = (BlynkMillis() - 5000UL);
|
||||
} break;
|
||||
case BLYNK_CMD_HARDWARE:
|
||||
case BLYNK_CMD_BRIDGE: {
|
||||
msgIdOutOverride = hdr.msg_id;
|
||||
this->processCmd(inputBuffer, hdr.length);
|
||||
msgIdOutOverride = 0;
|
||||
} break;
|
||||
case BLYNK_CMD_INTERNAL: {
|
||||
BlynkReq req = { 0 };
|
||||
BlynkParam param(inputBuffer, hdr.length);
|
||||
BlynkParam::iterator it = param.begin();
|
||||
if (it >= param.end())
|
||||
return true;
|
||||
|
||||
uint32_t cmd32;
|
||||
memcpy(&cmd32, it.asStr(), sizeof(cmd32));
|
||||
|
||||
++it;
|
||||
char* start = (char*)(it).asStr();
|
||||
unsigned length = hdr.length - (start - (char*)inputBuffer);
|
||||
BlynkParam param2(start, length);
|
||||
|
||||
switch (cmd32) {
|
||||
case BLYNK_INT_RTC: BlynkWidgetWriteInternalPinRTC(req, param2); break;
|
||||
case BLYNK_INT_OTA: BlynkWidgetWriteInternalPinOTA(req, param2); break;
|
||||
case BLYNK_INT_ACON: BlynkWidgetWriteInternalPinACON(req, param2); break;
|
||||
case BLYNK_INT_ADIS: BlynkWidgetWriteInternalPinADIS(req, param2); break;
|
||||
#ifdef BLYNK_DEBUG
|
||||
default: BLYNK_LOG2(BLYNK_F("Invalid internal cmd:"), param.asStr());
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case BLYNK_CMD_DEBUG_PRINT: {
|
||||
if (hdr.length) {
|
||||
BLYNK_LOG2(BLYNK_F("Server: "), (char*)inputBuffer);
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG2(BLYNK_F("Invalid header type: "), hdr.type);
|
||||
#endif
|
||||
// TODO: Flush
|
||||
internalReconnect();
|
||||
} break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Transp>
|
||||
int BlynkProtocol<Transp>::readHeader(BlynkHeader& hdr)
|
||||
{
|
||||
size_t rlen = conn.read(&hdr, sizeof(hdr));
|
||||
if (rlen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sizeof(hdr) != rlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
BLYNK_DBG_DUMP(">", &hdr, sizeof(BlynkHeader));
|
||||
|
||||
hdr.msg_id = ntohs(hdr.msg_id);
|
||||
hdr.length = ntohs(hdr.length);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
#ifndef BLYNK_SEND_THROTTLE
|
||||
#define BLYNK_SEND_THROTTLE 0
|
||||
#endif
|
||||
|
||||
#ifndef BLYNK_SEND_CHUNK
|
||||
#define BLYNK_SEND_CHUNK 1024 // Just a big number
|
||||
#endif
|
||||
|
||||
template <class Transp>
|
||||
void BlynkProtocol<Transp>::sendCmd(uint8_t cmd, uint16_t id, const void* data, size_t length, const void* data2, size_t length2)
|
||||
{
|
||||
if (!conn.connected() || (cmd != BLYNK_CMD_RESPONSE && cmd != BLYNK_CMD_PING && cmd != BLYNK_CMD_LOGIN && state != CONNECTED) ) {
|
||||
#ifdef BLYNK_DEBUG_ALL
|
||||
BLYNK_LOG2(BLYNK_F("Cmd skipped:"), cmd);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 == id) {
|
||||
id = getNextMsgId();
|
||||
}
|
||||
|
||||
#if defined(BLYNK_MSG_LIMIT) && BLYNK_MSG_LIMIT > 0
|
||||
if (cmd >= BLYNK_CMD_TWEET && cmd <= BLYNK_CMD_HARDWARE) {
|
||||
const millis_time_t allowed_time = BlynkMax(lastActivityOut, lastActivityIn) + 1000/BLYNK_MSG_LIMIT;
|
||||
int32_t wait_time = allowed_time - BlynkMillis();
|
||||
if (wait_time >= 0) {
|
||||
#ifdef BLYNK_DEBUG_ALL
|
||||
BLYNK_LOG2(BLYNK_F("Waiting:"), wait_time);
|
||||
#endif
|
||||
while (wait_time >= 0) {
|
||||
run();
|
||||
wait_time = allowed_time - BlynkMillis();
|
||||
}
|
||||
} else if (nesting == 0) {
|
||||
run();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const size_t full_length = (sizeof(BlynkHeader)) +
|
||||
(data ? length : 0) +
|
||||
(data2 ? length2 : 0);
|
||||
|
||||
#if defined(BLYNK_SEND_ATOMIC) || defined(ESP8266) || defined(ESP32) || defined(SPARK) || defined(PARTICLE) || defined(ENERGIA)
|
||||
// Those have more RAM and like single write at a time...
|
||||
|
||||
uint8_t buff[full_length];
|
||||
|
||||
BlynkHeader* hdr = (BlynkHeader*)buff;
|
||||
hdr->type = cmd;
|
||||
hdr->msg_id = htons(id);
|
||||
hdr->length = htons(length+length2);
|
||||
|
||||
size_t pos = sizeof(BlynkHeader);
|
||||
if (data && length) {
|
||||
memcpy(buff + pos, data, length);
|
||||
pos += length;
|
||||
}
|
||||
if (data2 && length2) {
|
||||
memcpy(buff + pos, data2, length2);
|
||||
}
|
||||
|
||||
size_t wlen = 0;
|
||||
while (wlen < full_length) {
|
||||
const size_t chunk = BlynkMin(size_t(BLYNK_SEND_CHUNK), full_length - wlen);
|
||||
BLYNK_DBG_DUMP("<", buff + wlen, chunk);
|
||||
const size_t w = conn.write(buff + wlen, chunk);
|
||||
BlynkDelay(BLYNK_SEND_THROTTLE);
|
||||
if (w == 0) {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG1(BLYNK_F("Cmd error"));
|
||||
#endif
|
||||
conn.disconnect();
|
||||
state = CONNECTING;
|
||||
BlynkOnDisconnected();
|
||||
return;
|
||||
}
|
||||
wlen += w;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BlynkHeader hdr;
|
||||
hdr.type = cmd;
|
||||
hdr.msg_id = htons(id);
|
||||
hdr.length = htons(length+length2);
|
||||
|
||||
BLYNK_DBG_DUMP("<", &hdr, sizeof(hdr));
|
||||
size_t wlen = conn.write(&hdr, sizeof(hdr));
|
||||
BlynkDelay(BLYNK_SEND_THROTTLE);
|
||||
|
||||
if (cmd != BLYNK_CMD_RESPONSE) {
|
||||
if (length) {
|
||||
BLYNK_DBG_DUMP("<", data, length);
|
||||
wlen += conn.write(data, length);
|
||||
BlynkDelay(BLYNK_SEND_THROTTLE);
|
||||
}
|
||||
if (length2) {
|
||||
BLYNK_DBG_DUMP("<", data2, length2);
|
||||
wlen += conn.write(data2, length2);
|
||||
BlynkDelay(BLYNK_SEND_THROTTLE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (wlen != full_length) {
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG4(BLYNK_F("Sent "), wlen, '/', full_length);
|
||||
#endif
|
||||
internalReconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
lastActivityOut = BlynkMillis();
|
||||
|
||||
}
|
||||
|
||||
template <class Transp>
|
||||
uint16_t BlynkProtocol<Transp>::getNextMsgId()
|
||||
{
|
||||
if (msgIdOutOverride != 0)
|
||||
return msgIdOutOverride;
|
||||
if (++msgIdOut == 0)
|
||||
msgIdOut = 1;
|
||||
return msgIdOut;
|
||||
}
|
||||
|
||||
#endif
|
||||
138
wled00/src/dependencies/blynk/Blynk/BlynkProtocolDefs.h
Normal file
138
wled00/src/dependencies/blynk/Blynk/BlynkProtocolDefs.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* @file BlynkProtocolDefs.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief Blynk protocol definitions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkProtocolDefs_h
|
||||
#define BlynkProtocolDefs_h
|
||||
|
||||
enum BlynkCmd
|
||||
{
|
||||
BLYNK_CMD_RESPONSE = 0,
|
||||
BLYNK_CMD_REGISTER = 1,
|
||||
BLYNK_CMD_LOGIN = 2,
|
||||
BLYNK_CMD_SAVE_PROF = 3,
|
||||
BLYNK_CMD_LOAD_PROF = 4,
|
||||
BLYNK_CMD_GET_TOKEN = 5,
|
||||
BLYNK_CMD_PING = 6,
|
||||
BLYNK_CMD_ACTIVATE = 7,
|
||||
BLYNK_CMD_DEACTIVATE = 8,
|
||||
BLYNK_CMD_REFRESH = 9,
|
||||
BLYNK_CMD_GET_GRAPH_DATA = 10,
|
||||
BLYNK_CMD_GET_GRAPH_DATA_RESPONSE = 11,
|
||||
|
||||
BLYNK_CMD_TWEET = 12,
|
||||
BLYNK_CMD_EMAIL = 13,
|
||||
BLYNK_CMD_NOTIFY = 14,
|
||||
BLYNK_CMD_BRIDGE = 15,
|
||||
BLYNK_CMD_HARDWARE_SYNC = 16,
|
||||
BLYNK_CMD_INTERNAL = 17,
|
||||
BLYNK_CMD_SMS = 18,
|
||||
BLYNK_CMD_PROPERTY = 19,
|
||||
BLYNK_CMD_HARDWARE = 20,
|
||||
|
||||
BLYNK_CMD_CREATE_DASH = 21,
|
||||
BLYNK_CMD_SAVE_DASH = 22,
|
||||
BLYNK_CMD_DELETE_DASH = 23,
|
||||
BLYNK_CMD_LOAD_PROF_GZ = 24,
|
||||
BLYNK_CMD_SYNC = 25,
|
||||
BLYNK_CMD_SHARING = 26,
|
||||
BLYNK_CMD_ADD_PUSH_TOKEN = 27,
|
||||
|
||||
//sharing commands
|
||||
BLYNK_CMD_GET_SHARED_DASH = 29,
|
||||
BLYNK_CMD_GET_SHARE_TOKEN = 30,
|
||||
BLYNK_CMD_REFRESH_SHARE_TOKEN = 31,
|
||||
BLYNK_CMD_SHARE_LOGIN = 32,
|
||||
|
||||
BLYNK_CMD_REDIRECT = 41,
|
||||
|
||||
BLYNK_CMD_DEBUG_PRINT = 55,
|
||||
|
||||
BLYNK_CMD_EVENT_LOG = 64
|
||||
};
|
||||
|
||||
enum BlynkStatus
|
||||
{
|
||||
BLYNK_SUCCESS = 200,
|
||||
BLYNK_QUOTA_LIMIT_EXCEPTION = 1,
|
||||
BLYNK_ILLEGAL_COMMAND = 2,
|
||||
BLYNK_NOT_REGISTERED = 3,
|
||||
BLYNK_ALREADY_REGISTERED = 4,
|
||||
BLYNK_NOT_AUTHENTICATED = 5,
|
||||
BLYNK_NOT_ALLOWED = 6,
|
||||
BLYNK_DEVICE_NOT_IN_NETWORK = 7,
|
||||
BLYNK_NO_ACTIVE_DASHBOARD = 8,
|
||||
BLYNK_INVALID_TOKEN = 9,
|
||||
BLYNK_ILLEGAL_COMMAND_BODY = 11,
|
||||
BLYNK_GET_GRAPH_DATA_EXCEPTION = 12,
|
||||
BLYNK_NO_DATA_EXCEPTION = 17,
|
||||
BLYNK_DEVICE_WENT_OFFLINE = 18,
|
||||
BLYNK_SERVER_EXCEPTION = 19,
|
||||
|
||||
BLYNK_NTF_INVALID_BODY = 13,
|
||||
BLYNK_NTF_NOT_AUTHORIZED = 14,
|
||||
BLYNK_NTF_ECXEPTION = 15,
|
||||
|
||||
BLYNK_TIMEOUT = 16,
|
||||
|
||||
BLYNK_NOT_SUPPORTED_VERSION = 20,
|
||||
BLYNK_ENERGY_LIMIT = 21
|
||||
};
|
||||
|
||||
struct BlynkHeader
|
||||
{
|
||||
uint8_t type;
|
||||
uint16_t msg_id;
|
||||
uint16_t length;
|
||||
}
|
||||
BLYNK_ATTR_PACKED;
|
||||
|
||||
#if !defined(htons) && (defined(ARDUINO) || defined(ESP8266) || defined(PARTICLE) || defined(__MBED__))
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) )
|
||||
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
|
||||
((x)<< 8 & 0x00FF0000UL) | \
|
||||
((x)>> 8 & 0x0000FF00UL) | \
|
||||
((x)>>24 & 0x000000FFUL) )
|
||||
#define ntohs(x) htons(x)
|
||||
#define ntohl(x) htonl(x)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define htons(x) (x)
|
||||
#define htonl(x) (x)
|
||||
#define ntohs(x) (x)
|
||||
#define ntohl(x) (x)
|
||||
#else
|
||||
#error byte order problem
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define BLYNK_STR_16(a,b) ((uint16_t(a) << 0) | (uint16_t(b) << 8))
|
||||
#define BLYNK_STR_32(a,b,c,d) ((uint32_t(a) << 0) | (uint32_t(b) << 8) | (uint32_t(c) << 16) | (uint32_t(d) << 24))
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define BLYNK_STR_16(a,b) ((uint16_t(b) << 0) | (uint16_t(a) << 8))
|
||||
#define BLYNK_STR_32(a,b,c,d) ((uint32_t(d) << 0) | (uint32_t(c) << 8) | (uint32_t(b) << 16) | (uint32_t(a) << 24))
|
||||
#else
|
||||
#error byte order problem
|
||||
#endif
|
||||
|
||||
#define BLYNK_HW_PM BLYNK_STR_16('p','m')
|
||||
#define BLYNK_HW_DW BLYNK_STR_16('d','w')
|
||||
#define BLYNK_HW_DR BLYNK_STR_16('d','r')
|
||||
#define BLYNK_HW_AW BLYNK_STR_16('a','w')
|
||||
#define BLYNK_HW_AR BLYNK_STR_16('a','r')
|
||||
#define BLYNK_HW_VW BLYNK_STR_16('v','w')
|
||||
#define BLYNK_HW_VR BLYNK_STR_16('v','r')
|
||||
|
||||
#define BLYNK_INT_RTC BLYNK_STR_32('r','t','c',0)
|
||||
#define BLYNK_INT_OTA BLYNK_STR_32('o','t','a',0)
|
||||
#define BLYNK_INT_ACON BLYNK_STR_32('a','c','o','n')
|
||||
#define BLYNK_INT_ADIS BLYNK_STR_32('a','d','i','s')
|
||||
|
||||
#endif
|
||||
47
wled00/src/dependencies/blynk/Blynk/BlynkTemplates.h
Normal file
47
wled00/src/dependencies/blynk/Blynk/BlynkTemplates.h
Normal file
@@ -0,0 +1,47 @@
|
||||
class BlynkStackOnly
|
||||
{
|
||||
protected:
|
||||
BlynkStackOnly() {}
|
||||
~BlynkStackOnly() {}
|
||||
|
||||
private:
|
||||
/// @brief Declared as private to prevent usage of dynamic memory
|
||||
void* operator new(size_t size);
|
||||
/// @brief Declared as private to prevent usage of dynamic memory
|
||||
void operator delete(void *p);
|
||||
};
|
||||
|
||||
class BlynkNonCopyable
|
||||
{
|
||||
protected:
|
||||
BlynkNonCopyable(){}
|
||||
~BlynkNonCopyable(){}
|
||||
|
||||
private:
|
||||
/// @brief Declared as private to prevent usage of copy constructor
|
||||
BlynkNonCopyable(const BlynkNonCopyable&);
|
||||
/// @brief Declared as private to prevent usage of assignment operator
|
||||
BlynkNonCopyable& operator=(const BlynkNonCopyable&);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class BlynkSingleton
|
||||
: public BlynkNonCopyable
|
||||
{
|
||||
public:
|
||||
/** @brief Returns the instance of the singleton type
|
||||
When called for the first time, the singleton instance will be
|
||||
created. All subsequent calls will return a reference to the
|
||||
previously created instance.
|
||||
@return The singleton instance
|
||||
*/
|
||||
static T* instance()
|
||||
{
|
||||
static T instance;
|
||||
return &instance;
|
||||
}
|
||||
protected:
|
||||
BlynkSingleton() {}
|
||||
~BlynkSingleton() {}
|
||||
};
|
||||
|
||||
291
wled00/src/dependencies/blynk/Blynk/BlynkTimer.cpp
Normal file
291
wled00/src/dependencies/blynk/Blynk/BlynkTimer.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* SimpleTimer.cpp
|
||||
*
|
||||
* SimpleTimer - A timer library for Arduino.
|
||||
* Author: mromani@ottotecnica.com
|
||||
* Copyright (c) 2010 OTTOTECNICA Italy
|
||||
*
|
||||
* Callback function parameters added & compiler warnings
|
||||
* removed by Bill Knight <billk@rosw.com> 20March2017
|
||||
*
|
||||
* This library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will
|
||||
* be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser
|
||||
* General Public License along with this library; if not,
|
||||
* write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "BlynkTimer.h"
|
||||
#include <string.h>
|
||||
|
||||
// Select time function:
|
||||
//static inline unsigned long elapsed() { return micros(); }
|
||||
static inline unsigned long elapsed() { return BlynkMillis(); }
|
||||
|
||||
|
||||
SimpleTimer::SimpleTimer()
|
||||
: numTimers (-1)
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleTimer::init() {
|
||||
unsigned long current_millis = elapsed();
|
||||
|
||||
for (int i = 0; i < MAX_TIMERS; i++) {
|
||||
memset(&timer[i], 0, sizeof (timer_t));
|
||||
timer[i].prev_millis = current_millis;
|
||||
}
|
||||
|
||||
numTimers = 0;
|
||||
}
|
||||
|
||||
|
||||
void SimpleTimer::run() {
|
||||
int i;
|
||||
unsigned long current_millis;
|
||||
|
||||
// get current time
|
||||
current_millis = elapsed();
|
||||
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
|
||||
timer[i].toBeCalled = DEFCALL_DONTRUN;
|
||||
|
||||
// no callback == no timer, i.e. jump over empty slots
|
||||
if (timer[i].callback != NULL) {
|
||||
|
||||
// is it time to process this timer ?
|
||||
// see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
|
||||
|
||||
if ((current_millis - timer[i].prev_millis) >= timer[i].delay) {
|
||||
|
||||
unsigned long skipTimes = (current_millis - timer[i].prev_millis) / timer[i].delay;
|
||||
// update time
|
||||
timer[i].prev_millis += timer[i].delay * skipTimes;
|
||||
|
||||
// check if the timer callback has to be executed
|
||||
if (timer[i].enabled) {
|
||||
|
||||
// "run forever" timers must always be executed
|
||||
if (timer[i].maxNumRuns == RUN_FOREVER) {
|
||||
timer[i].toBeCalled = DEFCALL_RUNONLY;
|
||||
}
|
||||
// other timers get executed the specified number of times
|
||||
else if (timer[i].numRuns < timer[i].maxNumRuns) {
|
||||
timer[i].toBeCalled = DEFCALL_RUNONLY;
|
||||
timer[i].numRuns++;
|
||||
|
||||
// after the last run, delete the timer
|
||||
if (timer[i].numRuns >= timer[i].maxNumRuns) {
|
||||
timer[i].toBeCalled = DEFCALL_RUNANDDEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer[i].toBeCalled == DEFCALL_DONTRUN)
|
||||
continue;
|
||||
|
||||
if (timer[i].hasParam)
|
||||
(*(timer_callback_p)timer[i].callback)(timer[i].param);
|
||||
else
|
||||
(*(timer_callback)timer[i].callback)();
|
||||
|
||||
if (timer[i].toBeCalled == DEFCALL_RUNANDDEL)
|
||||
deleteTimer(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// find the first available slot
|
||||
// return -1 if none found
|
||||
int SimpleTimer::findFirstFreeSlot() {
|
||||
// all slots are used
|
||||
if (numTimers >= MAX_TIMERS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// return the first slot with no callback (i.e. free)
|
||||
for (int i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer[i].callback == NULL) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// no free slots found
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int SimpleTimer::setupTimer(unsigned long d, void* f, void* p, bool h, unsigned n) {
|
||||
int freeTimer;
|
||||
|
||||
if (numTimers < 0) {
|
||||
init();
|
||||
}
|
||||
|
||||
freeTimer = findFirstFreeSlot();
|
||||
if (freeTimer < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (f == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
timer[freeTimer].delay = d;
|
||||
timer[freeTimer].callback = f;
|
||||
timer[freeTimer].param = p;
|
||||
timer[freeTimer].hasParam = h;
|
||||
timer[freeTimer].maxNumRuns = n;
|
||||
timer[freeTimer].enabled = true;
|
||||
timer[freeTimer].prev_millis = elapsed();
|
||||
|
||||
numTimers++;
|
||||
|
||||
return freeTimer;
|
||||
}
|
||||
|
||||
|
||||
int SimpleTimer::setTimer(unsigned long d, timer_callback f, unsigned n) {
|
||||
return setupTimer(d, (void *)f, NULL, false, n);
|
||||
}
|
||||
|
||||
int SimpleTimer::setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n) {
|
||||
return setupTimer(d, (void *)f, p, true, n);
|
||||
}
|
||||
|
||||
int SimpleTimer::setInterval(unsigned long d, timer_callback f) {
|
||||
return setupTimer(d, (void *)f, NULL, false, RUN_FOREVER);
|
||||
}
|
||||
|
||||
int SimpleTimer::setInterval(unsigned long d, timer_callback_p f, void* p) {
|
||||
return setupTimer(d, (void *)f, p, true, RUN_FOREVER);
|
||||
}
|
||||
|
||||
int SimpleTimer::setTimeout(unsigned long d, timer_callback f) {
|
||||
return setupTimer(d, (void *)f, NULL, false, RUN_ONCE);
|
||||
}
|
||||
|
||||
int SimpleTimer::setTimeout(unsigned long d, timer_callback_p f, void* p) {
|
||||
return setupTimer(d, (void *)f, p, true, RUN_ONCE);
|
||||
}
|
||||
|
||||
bool SimpleTimer::changeInterval(unsigned numTimer, unsigned long d) {
|
||||
if (numTimer >= MAX_TIMERS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Updates interval of existing specified timer
|
||||
if (timer[numTimer].callback != NULL) {
|
||||
timer[numTimer].delay = d;
|
||||
timer[numTimer].prev_millis = elapsed();
|
||||
return true;
|
||||
}
|
||||
// false return for non-used numTimer, no callback
|
||||
return false;
|
||||
}
|
||||
|
||||
void SimpleTimer::deleteTimer(unsigned timerId) {
|
||||
if (timerId >= MAX_TIMERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// nothing to delete if no timers are in use
|
||||
if (numTimers == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't decrease the number of timers if the
|
||||
// specified slot is already empty
|
||||
if (timer[timerId].callback != NULL) {
|
||||
memset(&timer[timerId], 0, sizeof (timer_t));
|
||||
timer[timerId].prev_millis = elapsed();
|
||||
|
||||
// update number of timers
|
||||
numTimers--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function contributed by code@rowansimms.com
|
||||
void SimpleTimer::restartTimer(unsigned numTimer) {
|
||||
if (numTimer >= MAX_TIMERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer[numTimer].prev_millis = elapsed();
|
||||
}
|
||||
|
||||
|
||||
bool SimpleTimer::isEnabled(unsigned numTimer) {
|
||||
if (numTimer >= MAX_TIMERS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return timer[numTimer].enabled;
|
||||
}
|
||||
|
||||
|
||||
void SimpleTimer::enable(unsigned numTimer) {
|
||||
if (numTimer >= MAX_TIMERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer[numTimer].enabled = true;
|
||||
}
|
||||
|
||||
|
||||
void SimpleTimer::disable(unsigned numTimer) {
|
||||
if (numTimer >= MAX_TIMERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer[numTimer].enabled = false;
|
||||
}
|
||||
|
||||
void SimpleTimer::enableAll() {
|
||||
// Enable all timers with a callback assigned (used)
|
||||
for (int i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer[i].callback != NULL && timer[i].numRuns == RUN_FOREVER) {
|
||||
timer[i].enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleTimer::disableAll() {
|
||||
// Disable all timers with a callback assigned (used)
|
||||
for (int i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer[i].callback != NULL && timer[i].numRuns == RUN_FOREVER) {
|
||||
timer[i].enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleTimer::toggle(unsigned numTimer) {
|
||||
if (numTimer >= MAX_TIMERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer[numTimer].enabled = !timer[numTimer].enabled;
|
||||
}
|
||||
|
||||
|
||||
unsigned SimpleTimer::getNumTimers() {
|
||||
return numTimers;
|
||||
}
|
||||
155
wled00/src/dependencies/blynk/Blynk/BlynkTimer.h
Normal file
155
wled00/src/dependencies/blynk/Blynk/BlynkTimer.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* SimpleTimer.h
|
||||
*
|
||||
* SimpleTimer - A timer library for Arduino.
|
||||
* Author: mromani@ottotecnica.com
|
||||
* Copyright (c) 2010 OTTOTECNICA Italy
|
||||
*
|
||||
* Modifications by Bill Knight <billk@rosw.com> 18March2017
|
||||
*
|
||||
* This library is free software; you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Lesser
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2.1 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will
|
||||
* be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser
|
||||
* General Public License along with this library; if not,
|
||||
* write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BLYNKTIMER_H
|
||||
#define BLYNKTIMER_H
|
||||
|
||||
#include "BlynkDebug.h"
|
||||
|
||||
// Replace SimpleTimer
|
||||
#define SIMPLETIMER_H
|
||||
#define SimpleTimer BlynkTimer
|
||||
|
||||
typedef void (*timer_callback)(void);
|
||||
typedef void (*timer_callback_p)(void *);
|
||||
|
||||
class SimpleTimer {
|
||||
|
||||
public:
|
||||
// maximum number of timers
|
||||
const static int MAX_TIMERS = 16;
|
||||
|
||||
// setTimer() constants
|
||||
const static int RUN_FOREVER = 0;
|
||||
const static int RUN_ONCE = 1;
|
||||
|
||||
// constructor
|
||||
SimpleTimer();
|
||||
|
||||
void init();
|
||||
|
||||
// this function must be called inside loop()
|
||||
void run();
|
||||
|
||||
// Timer will call function 'f' every 'd' milliseconds forever
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setInterval(unsigned long d, timer_callback f);
|
||||
|
||||
// Timer will call function 'f' with parameter 'p' every 'd' milliseconds forever
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setInterval(unsigned long d, timer_callback_p f, void* p);
|
||||
|
||||
// Timer will call function 'f' after 'd' milliseconds one time
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setTimeout(unsigned long d, timer_callback f);
|
||||
|
||||
// Timer will call function 'f' with parameter 'p' after 'd' milliseconds one time
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setTimeout(unsigned long d, timer_callback_p f, void* p);
|
||||
|
||||
// Timer will call function 'f' every 'd' milliseconds 'n' times
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setTimer(unsigned long d, timer_callback f, unsigned n);
|
||||
|
||||
// Timer will call function 'f' with parameter 'p' every 'd' milliseconds 'n' times
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n);
|
||||
|
||||
// updates interval of the specified timer
|
||||
bool changeInterval(unsigned numTimer, unsigned long d);
|
||||
|
||||
// destroy the specified timer
|
||||
void deleteTimer(unsigned numTimer);
|
||||
|
||||
// restart the specified timer
|
||||
void restartTimer(unsigned numTimer);
|
||||
|
||||
// returns true if the specified timer is enabled
|
||||
bool isEnabled(unsigned numTimer);
|
||||
|
||||
// enables the specified timer
|
||||
void enable(unsigned numTimer);
|
||||
|
||||
// disables the specified timer
|
||||
void disable(unsigned numTimer);
|
||||
|
||||
// enables all timers
|
||||
void enableAll();
|
||||
|
||||
// disables all timers
|
||||
void disableAll();
|
||||
|
||||
// enables the specified timer if it's currently disabled,
|
||||
// and vice-versa
|
||||
void toggle(unsigned numTimer);
|
||||
|
||||
// returns the number of used timers
|
||||
unsigned getNumTimers();
|
||||
|
||||
// returns the number of available timers
|
||||
unsigned getNumAvailableTimers() { return MAX_TIMERS - numTimers; };
|
||||
|
||||
private:
|
||||
// deferred call constants
|
||||
const static int DEFCALL_DONTRUN = 0; // don't call the callback function
|
||||
const static int DEFCALL_RUNONLY = 1; // call the callback function but don't delete the timer
|
||||
const static int DEFCALL_RUNANDDEL = 2; // call the callback function and delete the timer
|
||||
|
||||
// low level function to initialize and enable a new timer
|
||||
// returns the timer number (numTimer) on success or
|
||||
// -1 on failure (f == NULL) or no free timers
|
||||
int setupTimer(unsigned long d, void* f, void* p, bool h, unsigned n);
|
||||
|
||||
// find the first available slot
|
||||
int findFirstFreeSlot();
|
||||
|
||||
typedef struct {
|
||||
unsigned long prev_millis; // value returned by the millis() function in the previous run() call
|
||||
void* callback; // pointer to the callback function
|
||||
void* param; // function parameter
|
||||
bool hasParam; // true if callback takes a parameter
|
||||
unsigned long delay; // delay value
|
||||
unsigned maxNumRuns; // number of runs to be executed
|
||||
unsigned numRuns; // number of executed runs
|
||||
bool enabled; // true if enabled
|
||||
unsigned toBeCalled; // deferred function call (sort of) - N.B.: only used in run()
|
||||
} timer_t;
|
||||
|
||||
timer_t timer[MAX_TIMERS];
|
||||
|
||||
// actual number of timers in use (-1 means uninitialized)
|
||||
int numTimers;
|
||||
};
|
||||
|
||||
#endif
|
||||
64
wled00/src/dependencies/blynk/Blynk/BlynkUtility.h
Normal file
64
wled00/src/dependencies/blynk/Blynk/BlynkUtility.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @file BlynkUtility.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jun 2015
|
||||
* @brief Utility functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkUtility_h
|
||||
#define BlynkUtility_h
|
||||
|
||||
template<class T>
|
||||
const T& BlynkMin(const T& a, const T& b)
|
||||
{
|
||||
return (b < a) ? b : a;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T& BlynkMax(const T& a, const T& b)
|
||||
{
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
T BlynkMathMap(T x, T in_min, T in_max, T out_min, T out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T BlynkMathClamp(T val, T low, T high)
|
||||
{
|
||||
return (val < low) ? low : ((val > high) ? high : val);
|
||||
}
|
||||
|
||||
|
||||
template <unsigned WSIZE, typename T>
|
||||
void BlynkAverageSample (T& avg, const T& input) {
|
||||
avg -= avg/WSIZE;
|
||||
const T add = input/WSIZE;
|
||||
// Fix for shorter delays
|
||||
if (add > 0)
|
||||
avg += add;
|
||||
else
|
||||
avg -= 1;
|
||||
}
|
||||
|
||||
class BlynkHelperAutoInc {
|
||||
public:
|
||||
BlynkHelperAutoInc(uint8_t& counter) : c(counter) { ++c; }
|
||||
~BlynkHelperAutoInc() { --c; }
|
||||
private:
|
||||
uint8_t& c;
|
||||
};
|
||||
|
||||
#define BlynkBitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define BlynkBitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define BlynkBitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define BlynkBitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||
|
||||
#endif
|
||||
102
wled00/src/dependencies/blynk/Blynk/BlynkWiFiCommon.h
Normal file
102
wled00/src/dependencies/blynk/Blynk/BlynkWiFiCommon.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file BlynkWiFiCommon.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Jan 2015
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkWiFiCommon_h
|
||||
#define BlynkWiFiCommon_h
|
||||
|
||||
#ifndef BLYNK_INFO_CONNECTION
|
||||
#define BLYNK_INFO_CONNECTION "WiFi"
|
||||
#endif
|
||||
|
||||
#include "BlynkApiArduino.h"
|
||||
#include "BlynkProtocol.h"
|
||||
#include "BlynkArduinoClient.h"
|
||||
|
||||
class BlynkWifiCommon
|
||||
: public BlynkProtocol<BlynkArduinoClient>
|
||||
{
|
||||
typedef BlynkProtocol<BlynkArduinoClient> Base;
|
||||
public:
|
||||
BlynkWifiCommon(BlynkArduinoClient& transp)
|
||||
: Base(transp)
|
||||
{}
|
||||
|
||||
void connectWiFi(const char* ssid, const char* pass)
|
||||
{
|
||||
int status = WL_IDLE_STATUS;
|
||||
// check for the presence of the shield:
|
||||
if (WiFi.status() == WL_NO_SHIELD) {
|
||||
BLYNK_FATAL("WiFi shield not present");
|
||||
}
|
||||
|
||||
#ifdef BLYNK_DEBUG
|
||||
BLYNK_LOG2(BLYNK_F("WiFi firmware: "), WiFi.firmwareVersion());
|
||||
#endif
|
||||
|
||||
// attempt to connect to Wifi network:
|
||||
while (true) {
|
||||
BLYNK_LOG2(BLYNK_F("Connecting to "), ssid);
|
||||
if (pass && strlen(pass)) {
|
||||
status = WiFi.begin((char*)ssid, (char*)pass);
|
||||
} else {
|
||||
status = WiFi.begin((char*)ssid);
|
||||
}
|
||||
if (status == WL_CONNECTED) {
|
||||
break;
|
||||
} else {
|
||||
BlynkDelay(5000);
|
||||
}
|
||||
}
|
||||
|
||||
IPAddress myip = WiFi.localIP();
|
||||
BLYNK_LOG_IP("IP: ", myip);
|
||||
}
|
||||
|
||||
void config(const char* auth,
|
||||
const char* domain = BLYNK_DEFAULT_DOMAIN,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
Base::begin(auth);
|
||||
this->conn.begin(domain, port);
|
||||
}
|
||||
|
||||
void config(const char* auth,
|
||||
IPAddress ip,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
Base::begin(auth);
|
||||
this->conn.begin(ip, port);
|
||||
}
|
||||
|
||||
void begin(const char* auth,
|
||||
const char* ssid,
|
||||
const char* pass,
|
||||
const char* domain = BLYNK_DEFAULT_DOMAIN,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
connectWiFi(ssid, pass);
|
||||
config(auth, domain, port);
|
||||
while(this->connect() != true) {}
|
||||
}
|
||||
|
||||
void begin(const char* auth,
|
||||
const char* ssid,
|
||||
const char* pass,
|
||||
IPAddress ip,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
connectWiFi(ssid, pass);
|
||||
config(auth, ip, port);
|
||||
while(this->connect() != true) {}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
62
wled00/src/dependencies/blynk/Blynk/BlynkWidgetBase.h
Normal file
62
wled00/src/dependencies/blynk/Blynk/BlynkWidgetBase.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file BlynkWidgetBase.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
||||
* @date Nov 2016
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef BlynkWidgetBase_h
|
||||
#define BlynkWidgetBase_h
|
||||
|
||||
#include "BlynkApi.h"
|
||||
|
||||
class BlynkWidgetBase
|
||||
{
|
||||
public:
|
||||
BlynkWidgetBase(uint8_t vPin) : mPin(vPin) {}
|
||||
void setVPin(uint8_t vPin) { mPin = vPin; }
|
||||
|
||||
void onWrite(BlynkReq BLYNK_UNUSED &request, const BlynkParam BLYNK_UNUSED ¶m) {
|
||||
BLYNK_LOG1(BLYNK_F("BlynkWidgetBase::onWrite should not be called"));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void setLabel(Args... args) {
|
||||
Blynk.setProperty(mPin, "label", args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void setColor(Args... args) {
|
||||
Blynk.setProperty(mPin, "color", args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void setMin(Args... args) {
|
||||
Blynk.setProperty(mPin, "min", args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void setMax(Args... args) {
|
||||
Blynk.setProperty(mPin, "max", args...);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t mPin;
|
||||
};
|
||||
|
||||
class BlynkAttachWidgetHelper {
|
||||
public:
|
||||
template<typename T>
|
||||
explicit BlynkAttachWidgetHelper(T& widget, uint8_t vPin) {
|
||||
widget.setVPin(vPin);
|
||||
}
|
||||
};
|
||||
|
||||
// Could use __attribute__ ((constructor)), but hope for better portability
|
||||
#define BLYNK_ATTACH_WIDGET(widget, pin) \
|
||||
BlynkAttachWidgetHelper BLYNK_CONCAT2(blnk_widget_helper_, __COUNTER__)((widget), (pin)); \
|
||||
BLYNK_WRITE(pin) { (widget).onWrite(request, param); }
|
||||
|
||||
#endif
|
||||
198
wled00/src/dependencies/blynk/Blynk/utility.cpp
Normal file
198
wled00/src/dependencies/blynk/Blynk/utility.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "BlynkDebug.h"
|
||||
#include "BlynkDateTime.h"
|
||||
|
||||
#if !defined(BLYNK_NO_FLOAT) && defined(BLYNK_USE_INTERNAL_DTOSTRF)
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char* dtostrf_internal(double number, signed char BLYNK_UNUSED width, unsigned char prec, char *s) {
|
||||
if(isnan(number)) {
|
||||
strcpy(s, "nan");
|
||||
return s;
|
||||
}
|
||||
if(isinf(number)) {
|
||||
strcpy(s, "inf");
|
||||
return s;
|
||||
}
|
||||
|
||||
if(number > 4294967040.0 || number < -4294967040.0) {
|
||||
strcpy(s, "ovf");
|
||||
return s;
|
||||
}
|
||||
char* out = s;
|
||||
// Handle negative numbers
|
||||
if(number < 0.0) {
|
||||
*out = '-';
|
||||
++out;
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
double rounding = 0.5;
|
||||
for(uint8_t i = 0; i < prec; ++i) {
|
||||
rounding /= 10.0;
|
||||
}
|
||||
|
||||
number += rounding;
|
||||
|
||||
// Extract the integer part of the number and print it
|
||||
unsigned long int_part = (unsigned long) number;
|
||||
double remainder = number - (double) int_part;
|
||||
out += sprintf(out, "%lu", int_part);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if(prec > 0) {
|
||||
*out = '.';
|
||||
++out;
|
||||
}
|
||||
|
||||
while(prec-- > 0) {
|
||||
remainder *= 10.0;
|
||||
if((int)remainder == 0) {
|
||||
*out = '0';
|
||||
++out;
|
||||
}
|
||||
}
|
||||
sprintf(out, "%d", (int) remainder);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define YEAR_0 1900
|
||||
#define YEAR_EPOCH 1970
|
||||
#define SECS_IN_DAY (24L * 60L * 60L)
|
||||
#define IS_LEAP_YEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
|
||||
#define YEAR_DAYS(year) (IS_LEAP_YEAR(year) ? 366 : 365)
|
||||
|
||||
#define TIME_MAX 2147483647L
|
||||
|
||||
static const int month_tab[2][12] = {
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
};
|
||||
|
||||
struct blynk_tm* blynk_gmtime_r(const blynk_time_t* t, struct blynk_tm *tm) {
|
||||
blynk_time_t time = *t;
|
||||
unsigned long dayclock, dayno;
|
||||
int year = YEAR_EPOCH;
|
||||
|
||||
dayclock = (unsigned long) time % SECS_IN_DAY;
|
||||
dayno = (unsigned long) time / SECS_IN_DAY;
|
||||
|
||||
tm->tm_sec = dayclock % 60;
|
||||
tm->tm_min = (dayclock % 3600) / 60;
|
||||
tm->tm_hour = dayclock / 3600;
|
||||
tm->tm_wday = (dayno + 4) % 7;
|
||||
while (dayno >= (unsigned long) YEAR_DAYS(year)) {
|
||||
dayno -= YEAR_DAYS(year);
|
||||
year++;
|
||||
}
|
||||
tm->tm_year = year - YEAR_0;
|
||||
tm->tm_yday = dayno;
|
||||
tm->tm_mon = 0;
|
||||
while (dayno >= (unsigned long) month_tab[IS_LEAP_YEAR(year)][tm->tm_mon]) {
|
||||
dayno -= month_tab[IS_LEAP_YEAR(year)][tm->tm_mon];
|
||||
tm->tm_mon++;
|
||||
}
|
||||
tm->tm_mday = dayno + 1;
|
||||
tm->tm_isdst = 0;
|
||||
return tm;
|
||||
}
|
||||
|
||||
blynk_time_t blynk_mk_gmtime(struct blynk_tm *tm) {
|
||||
long day, year;
|
||||
int tm_year;
|
||||
int yday, month;
|
||||
long seconds;
|
||||
int overflow;
|
||||
|
||||
tm->tm_min += tm->tm_sec / 60;
|
||||
tm->tm_sec %= 60;
|
||||
if (tm->tm_sec < 0) {
|
||||
tm->tm_sec += 60;
|
||||
tm->tm_min--;
|
||||
}
|
||||
tm->tm_hour += tm->tm_min / 60;
|
||||
tm->tm_min = tm->tm_min % 60;
|
||||
if (tm->tm_min < 0) {
|
||||
tm->tm_min += 60;
|
||||
tm->tm_hour--;
|
||||
}
|
||||
day = tm->tm_hour / 24;
|
||||
tm->tm_hour = tm->tm_hour % 24;
|
||||
if (tm->tm_hour < 0) {
|
||||
tm->tm_hour += 24;
|
||||
day--;
|
||||
}
|
||||
tm->tm_year += tm->tm_mon / 12;
|
||||
tm->tm_mon %= 12;
|
||||
if (tm->tm_mon < 0) {
|
||||
tm->tm_mon += 12;
|
||||
tm->tm_year--;
|
||||
}
|
||||
day += (tm->tm_mday - 1);
|
||||
while (day < 0) {
|
||||
if (--tm->tm_mon < 0) {
|
||||
tm->tm_year--;
|
||||
tm->tm_mon = 11;
|
||||
}
|
||||
day += month_tab[IS_LEAP_YEAR(YEAR_0 + tm->tm_year)][tm->tm_mon];
|
||||
}
|
||||
while (day >= month_tab[IS_LEAP_YEAR(YEAR_0 + tm->tm_year)][tm->tm_mon]) {
|
||||
day -= month_tab[IS_LEAP_YEAR(YEAR_0 + tm->tm_year)][tm->tm_mon];
|
||||
if (++(tm->tm_mon) == 12) {
|
||||
tm->tm_mon = 0;
|
||||
tm->tm_year++;
|
||||
}
|
||||
}
|
||||
tm->tm_mday = day + 1;
|
||||
year = YEAR_EPOCH;
|
||||
if (tm->tm_year < year - YEAR_0)
|
||||
return (blynk_time_t) -1;
|
||||
seconds = 0;
|
||||
day = 0;
|
||||
overflow = 0;
|
||||
|
||||
tm_year = tm->tm_year + YEAR_0;
|
||||
|
||||
if (TIME_MAX / 365 < tm_year - year)
|
||||
overflow++;
|
||||
day = (tm_year - year) * 365;
|
||||
if (TIME_MAX - day < (tm_year - year) / 4 + 1)
|
||||
overflow++;
|
||||
day += (tm_year - year) / 4 + ((tm_year % 4) && tm_year % 4 < year % 4);
|
||||
day -= (tm_year - year) / 100
|
||||
+ ((tm_year % 100) && tm_year % 100 < year % 100);
|
||||
day += (tm_year - year) / 400
|
||||
+ ((tm_year % 400) && tm_year % 400 < year % 400);
|
||||
|
||||
yday = month = 0;
|
||||
while (month < tm->tm_mon) {
|
||||
yday += month_tab[IS_LEAP_YEAR(tm_year)][month];
|
||||
month++;
|
||||
}
|
||||
yday += (tm->tm_mday - 1);
|
||||
if (day + yday < 0)
|
||||
overflow++;
|
||||
day += yday;
|
||||
|
||||
tm->tm_yday = yday;
|
||||
tm->tm_wday = (day + 4) % 7;
|
||||
|
||||
seconds = ((tm->tm_hour * 60L) + tm->tm_min) * 60L + tm->tm_sec;
|
||||
|
||||
if ((TIME_MAX - seconds) / SECS_IN_DAY < day)
|
||||
overflow++;
|
||||
seconds += day * SECS_IN_DAY;
|
||||
|
||||
if (overflow)
|
||||
return (blynk_time_t) -1;
|
||||
|
||||
if ((blynk_time_t) seconds != seconds)
|
||||
return (blynk_time_t) -1;
|
||||
return (blynk_time_t) seconds;
|
||||
}
|
||||
96
wled00/src/dependencies/blynk/BlynkSimpleEsp.h
Normal file
96
wled00/src/dependencies/blynk/BlynkSimpleEsp.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file BlynkSimpleEsp32.h
|
||||
* @author Volodymyr Shymanskyy
|
||||
* @license This project is released under the MIT License (MIT)
|
||||
* @copyright Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
* @date Oct 2016
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BlynkSimpleEsp_h
|
||||
#define BlynkSimpleEsp_h
|
||||
|
||||
#define BLYNK_SEND_ATOMIC
|
||||
|
||||
#include "Blynk/BlynkApiArduino.h"
|
||||
#include "Blynk/BlynkProtocol.h"
|
||||
#include "Blynk/BlynkArduinoClient.h"
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
|
||||
class BlynkWifi
|
||||
: public BlynkProtocol<BlynkArduinoClient>
|
||||
{
|
||||
typedef BlynkProtocol<BlynkArduinoClient> Base;
|
||||
public:
|
||||
BlynkWifi(BlynkArduinoClient& transp)
|
||||
: Base(transp)
|
||||
{}
|
||||
|
||||
void connectWiFi(const char* ssid, const char* pass)
|
||||
{
|
||||
BLYNK_LOG2(BLYNK_F("Connecting to "), ssid);
|
||||
WiFi.mode(WIFI_STA);
|
||||
if (pass && strlen(pass)) {
|
||||
WiFi.begin(ssid, pass);
|
||||
} else {
|
||||
WiFi.begin(ssid);
|
||||
}
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
BlynkDelay(500);
|
||||
}
|
||||
BLYNK_LOG1(BLYNK_F("Connected to WiFi"));
|
||||
|
||||
IPAddress myip = WiFi.localIP();
|
||||
BLYNK_LOG_IP("IP: ", myip);
|
||||
}
|
||||
|
||||
void config(const char* auth,
|
||||
const char* domain = BLYNK_DEFAULT_DOMAIN,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
Base::begin(auth);
|
||||
this->conn.begin(domain, port);
|
||||
}
|
||||
|
||||
void config(const char* auth,
|
||||
IPAddress ip,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
Base::begin(auth);
|
||||
this->conn.begin(ip, port);
|
||||
}
|
||||
|
||||
void begin(const char* auth,
|
||||
const char* ssid,
|
||||
const char* pass,
|
||||
const char* domain = BLYNK_DEFAULT_DOMAIN,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
connectWiFi(ssid, pass);
|
||||
config(auth, domain, port);
|
||||
while(this->connect() != true) {}
|
||||
}
|
||||
|
||||
void begin(const char* auth,
|
||||
const char* ssid,
|
||||
const char* pass,
|
||||
IPAddress ip,
|
||||
uint16_t port = BLYNK_DEFAULT_PORT)
|
||||
{
|
||||
connectWiFi(ssid, pass);
|
||||
config(auth, ip, port);
|
||||
while(this->connect() != true) {}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static WiFiClient _blynkWifiClient;
|
||||
static BlynkArduinoClient _blynkTransport(_blynkWifiClient);
|
||||
BlynkWifi Blynk(_blynkTransport);
|
||||
|
||||
#endif
|
||||
21
wled00/src/dependencies/blynk/LICENSE.txt
Normal file
21
wled00/src/dependencies/blynk/LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Volodymyr Shymanskyy
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
82
wled00/src/dependencies/e131/E131.cpp
Normal file
82
wled00/src/dependencies/e131/E131.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
196
wled00/src/dependencies/e131/E131.h
Normal file
196
wled00/src/dependencies/e131/E131.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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_ */
|
||||
487
wled00/src/dependencies/espalexa/Espalexa.h
Normal file
487
wled00/src/dependencies/espalexa/Espalexa.h
Normal file
@@ -0,0 +1,487 @@
|
||||
#ifndef Espalexa_h
|
||||
#define Espalexa_h
|
||||
|
||||
/*
|
||||
* Alexa Voice On/Off/Brightness/Color Control. Emulates a Philips Hue bridge to Alexa.
|
||||
*
|
||||
* This was put together from these two excellent projects:
|
||||
* https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch
|
||||
* https://github.com/probonopd/ESP8266HueEmulator
|
||||
*/
|
||||
/*
|
||||
* @title Espalexa library
|
||||
* @version 2.3.3
|
||||
* @author Christian Schwinne
|
||||
* @license MIT
|
||||
* @contributors d-999
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
//you can use these defines for library config in your sketch. Just use them before #include <Espalexa.h>
|
||||
//#define ESPALEXA_ASYNC
|
||||
|
||||
#ifndef ESPALEXA_MAXDEVICES
|
||||
#define ESPALEXA_MAXDEVICES 10 //this limit only has memory reasons, set it higher should you need to
|
||||
#endif
|
||||
|
||||
//#define ESPALEXA_DEBUG
|
||||
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include <AsyncTCP.h>
|
||||
#else
|
||||
#include <ESPAsyncTCP.h>
|
||||
#endif
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#else
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include <WiFi.h>
|
||||
#include "../webserver/WebServer.h" //if you get an error here please update to ESP32 arduino core 1.0.0
|
||||
#else
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
#ifdef ESPALEXA_DEBUG
|
||||
#pragma message "Espalexa 2.3.3 debug mode"
|
||||
#define EA_DEBUG(x) Serial.print (x)
|
||||
#define EA_DEBUGLN(x) Serial.println (x)
|
||||
#else
|
||||
#define EA_DEBUG(x)
|
||||
#define EA_DEBUGLN(x)
|
||||
#endif
|
||||
|
||||
#include "EspalexaDevice.h"
|
||||
|
||||
class Espalexa {
|
||||
private:
|
||||
//private member vars
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
AsyncWebServer* serverAsync;
|
||||
AsyncWebServerRequest* server; //this saves many #defines
|
||||
String body = "";
|
||||
#elif defined ARDUINO_ARCH_ESP32
|
||||
WebServer* server;
|
||||
#else
|
||||
ESP8266WebServer* server;
|
||||
#endif
|
||||
uint8_t currentDeviceCount = 0;
|
||||
|
||||
EspalexaDevice* devices[ESPALEXA_MAXDEVICES] = {};
|
||||
//Keep in mind that Device IDs go from 1 to DEVICES, cpp arrays from 0 to DEVICES-1!!
|
||||
|
||||
WiFiUDP espalexaUdp;
|
||||
IPAddress ipMulti;
|
||||
bool udpConnected = false;
|
||||
char packetBuffer[255]; //buffer to hold incoming udp packet
|
||||
String escapedMac=""; //lowercase mac address
|
||||
|
||||
//private member functions
|
||||
String deviceJsonString(uint8_t deviceId)
|
||||
{
|
||||
if (deviceId < 1 || deviceId > currentDeviceCount) return "{}"; //error
|
||||
EspalexaDevice* dev = devices[deviceId-1];
|
||||
String json = "{\"type\":\"";
|
||||
json += dev->isColorDevice() ? "Extended color light" : "Dimmable light";
|
||||
json += "\",\"manufacturername\":\"OpenSource\",\"swversion\":\"0.1\",\"name\":\"";
|
||||
json += dev->getName();
|
||||
json += "\",\"uniqueid\":\""+ WiFi.macAddress() +"-"+ (deviceId+1) ;
|
||||
json += "\",\"modelid\":\"LST001\",\"state\":{\"on\":";
|
||||
json += boolString(dev->getValue()) +",\"bri\":"+ (String)(dev->getLastValue()-1) ;
|
||||
if (dev->isColorDevice())
|
||||
{
|
||||
json += ",\"xy\":[0.00000,0.00000],\"colormode\":\"";
|
||||
json += (dev->isColorTemperatureMode()) ? "ct":"hs";
|
||||
json += "\",\"effect\":\"none\",\"ct\":" + (String)(dev->getCt()) + ",\"hue\":" + (String)(dev->getHue()) + ",\"sat\":" + (String)(dev->getSat());
|
||||
}
|
||||
json +=",\"alert\":\"none\",\"reachable\":true}}";
|
||||
return json;
|
||||
}
|
||||
|
||||
//Espalexa status page /espalexa
|
||||
void servePage()
|
||||
{
|
||||
EA_DEBUGLN("HTTP Req espalexa ...\n");
|
||||
String res = "Hello from Espalexa!\r\n\r\n";
|
||||
for (int i=0; i<currentDeviceCount; i++)
|
||||
{
|
||||
res += "Value of device " + String(i+1) + " (" + devices[i]->getName() + "): " + String(devices[i]->getValue()) + "\r\n";
|
||||
}
|
||||
res += "\r\nFree Heap: " + (String)ESP.getFreeHeap();
|
||||
res += "\r\nUptime: " + (String)millis();
|
||||
res += "\r\n\r\nEspalexa library v2.3.3 by Christian Schwinne 2019";
|
||||
server->send(200, "text/plain", res);
|
||||
}
|
||||
|
||||
//not found URI (only if internal webserver is used)
|
||||
void serveNotFound()
|
||||
{
|
||||
EA_DEBUGLN("Not-Found HTTP call:");
|
||||
#ifndef ESPALEXA_ASYNC
|
||||
EA_DEBUGLN("URI: " + server->uri());
|
||||
EA_DEBUGLN("Body: " + server->arg(0));
|
||||
if(!handleAlexaApiCall(server->uri(), server->arg(0)))
|
||||
#else
|
||||
EA_DEBUGLN("URI: " + server->url());
|
||||
EA_DEBUGLN("Body: " + body);
|
||||
if(!handleAlexaApiCall(server))
|
||||
#endif
|
||||
server->send(404, "text/plain", "Not Found (espalexa-internal)");
|
||||
}
|
||||
|
||||
//send description.xml device property page
|
||||
void serveDescription()
|
||||
{
|
||||
EA_DEBUGLN("# Responding to description.xml ... #\n");
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String setup_xml = "<?xml version=\"1.0\" ?>"
|
||||
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
|
||||
"<specVersion><major>1</major><minor>0</minor></specVersion>"
|
||||
"<URLBase>http://"+ String(s) +":80/</URLBase>"
|
||||
"<device>"
|
||||
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
|
||||
"<friendlyName>Philips hue ("+ String(s) +")</friendlyName>"
|
||||
"<manufacturer>Royal Philips Electronics</manufacturer>"
|
||||
"<manufacturerURL>http://www.philips.com</manufacturerURL>"
|
||||
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
|
||||
"<modelName>Philips hue bridge 2012</modelName>"
|
||||
"<modelNumber>929000226503</modelNumber>"
|
||||
"<modelURL>http://www.meethue.com</modelURL>"
|
||||
"<serialNumber>"+ escapedMac +"</serialNumber>"
|
||||
"<UDN>uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"</UDN>"
|
||||
"<presentationURL>index.html</presentationURL>"
|
||||
"<iconList>"
|
||||
" <icon>"
|
||||
" <mimetype>image/png</mimetype>"
|
||||
" <height>48</height>"
|
||||
" <width>48</width>"
|
||||
" <depth>24</depth>"
|
||||
" <url>hue_logo_0.png</url>"
|
||||
" </icon>"
|
||||
" <icon>"
|
||||
" <mimetype>image/png</mimetype>"
|
||||
" <height>120</height>"
|
||||
" <width>120</width>"
|
||||
" <depth>24</depth>"
|
||||
" <url>hue_logo_3.png</url>"
|
||||
" </icon>"
|
||||
"</iconList>"
|
||||
"</device>"
|
||||
"</root>";
|
||||
|
||||
server->send(200, "text/xml", setup_xml.c_str());
|
||||
|
||||
EA_DEBUG("Sending :");
|
||||
EA_DEBUGLN(setup_xml);
|
||||
}
|
||||
|
||||
//init the server
|
||||
void startHttpServer()
|
||||
{
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
if (serverAsync == nullptr) {
|
||||
serverAsync = new AsyncWebServer(80);
|
||||
serverAsync->onNotFound([=](AsyncWebServerRequest *request){server = request; serveNotFound();});
|
||||
}
|
||||
|
||||
serverAsync->onRequestBody([=](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){
|
||||
char b[len +1];
|
||||
b[len] = 0;
|
||||
memcpy(b, data, len);
|
||||
body = b; //save the body so we can use it for the API call
|
||||
EA_DEBUG("Received body: ");
|
||||
EA_DEBUGLN(body);
|
||||
});
|
||||
serverAsync->on("/espalexa", HTTP_GET, [=](AsyncWebServerRequest *request){server = request; servePage();});
|
||||
serverAsync->on("/description.xml", HTTP_GET, [=](AsyncWebServerRequest *request){server = request; serveDescription();});
|
||||
serverAsync->begin();
|
||||
|
||||
#else
|
||||
if (server == nullptr) {
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
server = new WebServer(80);
|
||||
#else
|
||||
server = new ESP8266WebServer(80);
|
||||
#endif
|
||||
server->onNotFound([=](){serveNotFound();});
|
||||
}
|
||||
|
||||
server->on("/espalexa", HTTP_GET, [=](){servePage();});
|
||||
server->on("/description.xml", HTTP_GET, [=](){serveDescription();});
|
||||
server->begin();
|
||||
#endif
|
||||
}
|
||||
|
||||
//called when Alexa sends ON command
|
||||
void alexaOn(uint8_t deviceId)
|
||||
{
|
||||
devices[deviceId-1]->setValue(devices[deviceId-1]->getLastValue());
|
||||
devices[deviceId-1]->setPropertyChanged(1);
|
||||
devices[deviceId-1]->doCallback();
|
||||
}
|
||||
|
||||
//called when Alexa sends OFF command
|
||||
void alexaOff(uint8_t deviceId)
|
||||
{
|
||||
devices[deviceId-1]->setValue(0);
|
||||
devices[deviceId-1]->setPropertyChanged(2);
|
||||
devices[deviceId-1]->doCallback();
|
||||
}
|
||||
|
||||
//called when Alexa sends BRI command
|
||||
void alexaDim(uint8_t deviceId, uint8_t briL)
|
||||
{
|
||||
if (briL == 255)
|
||||
{
|
||||
devices[deviceId-1]->setValue(255);
|
||||
} else {
|
||||
devices[deviceId-1]->setValue(briL+1);
|
||||
}
|
||||
devices[deviceId-1]->setPropertyChanged(3);
|
||||
devices[deviceId-1]->doCallback();
|
||||
}
|
||||
|
||||
//called when Alexa sends HUE command
|
||||
void alexaCol(uint8_t deviceId, uint16_t hue, uint8_t sat)
|
||||
{
|
||||
devices[deviceId-1]->setColor(hue, sat);
|
||||
devices[deviceId-1]->setPropertyChanged(4);
|
||||
devices[deviceId-1]->doCallback();
|
||||
}
|
||||
|
||||
//called when Alexa sends CT command (color temperature)
|
||||
void alexaCt(uint8_t deviceId, uint16_t ct)
|
||||
{
|
||||
devices[deviceId-1]->setColor(ct);
|
||||
devices[deviceId-1]->setPropertyChanged(5);
|
||||
devices[deviceId-1]->doCallback();
|
||||
}
|
||||
|
||||
//respond to UDP SSDP M-SEARCH
|
||||
void respondToSearch()
|
||||
{
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String response =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"EXT:\r\n"
|
||||
"CACHE-CONTROL: max-age=100\r\n" // SSDP_INTERVAL
|
||||
"LOCATION: http://"+ String(s) +":80/description.xml\r\n"
|
||||
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber
|
||||
"hue-bridgeid: "+ escapedMac +"\r\n"
|
||||
"ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType
|
||||
"USN: uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"::upnp:rootdevice\r\n" // _uuid::_deviceType
|
||||
"\r\n";
|
||||
|
||||
espalexaUdp.beginPacket(espalexaUdp.remoteIP(), espalexaUdp.remotePort());
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
espalexaUdp.write((uint8_t*)response.c_str(), response.length());
|
||||
#else
|
||||
espalexaUdp.write(response.c_str());
|
||||
#endif
|
||||
espalexaUdp.endPacket();
|
||||
}
|
||||
|
||||
String boolString(bool st)
|
||||
{
|
||||
return(st)?"true":"false";
|
||||
}
|
||||
|
||||
public:
|
||||
Espalexa(){}
|
||||
|
||||
//initialize interfaces
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
bool begin(AsyncWebServer* externalServer = nullptr)
|
||||
#elif defined ARDUINO_ARCH_ESP32
|
||||
bool begin(WebServer* externalServer = nullptr)
|
||||
#else
|
||||
bool begin(ESP8266WebServer* externalServer = nullptr)
|
||||
#endif
|
||||
{
|
||||
EA_DEBUGLN("Espalexa Begin...");
|
||||
EA_DEBUG("MAXDEVICES ");
|
||||
EA_DEBUGLN(ESPALEXA_MAXDEVICES);
|
||||
escapedMac = WiFi.macAddress();
|
||||
escapedMac.replace(":", "");
|
||||
escapedMac.toLowerCase();
|
||||
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
serverAsync = externalServer;
|
||||
#else
|
||||
server = externalServer;
|
||||
#endif
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
udpConnected = espalexaUdp.beginMulticast(IPAddress(239, 255, 255, 250), 1900);
|
||||
#else
|
||||
udpConnected = espalexaUdp.beginMulticast(WiFi.localIP(), IPAddress(239, 255, 255, 250), 1900);
|
||||
#endif
|
||||
|
||||
if (udpConnected){
|
||||
|
||||
startHttpServer();
|
||||
EA_DEBUGLN("Done");
|
||||
return true;
|
||||
}
|
||||
EA_DEBUGLN("Failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
//service loop
|
||||
void loop() {
|
||||
#ifndef ESPALEXA_ASYNC
|
||||
if (server == nullptr) return; //only if begin() was not called
|
||||
server->handleClient();
|
||||
#endif
|
||||
|
||||
if (!udpConnected) return;
|
||||
int packetSize = espalexaUdp.parsePacket();
|
||||
if (!packetSize) return; //no new udp packet
|
||||
|
||||
EA_DEBUGLN("Got UDP!");
|
||||
int len = espalexaUdp.read(packetBuffer, 254);
|
||||
if (len > 0) {
|
||||
packetBuffer[len] = 0;
|
||||
}
|
||||
espalexaUdp.flush();
|
||||
|
||||
String request = packetBuffer;
|
||||
EA_DEBUGLN(request);
|
||||
if(request.indexOf("M-SEARCH") >= 0) {
|
||||
if(request.indexOf("upnp:rootdevice") > 0 || request.indexOf("asic:1") > 0) {
|
||||
EA_DEBUGLN("Responding search req...");
|
||||
respondToSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool addDevice(EspalexaDevice* d)
|
||||
{
|
||||
EA_DEBUG("Adding device ");
|
||||
EA_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
devices[currentDeviceCount] = d;
|
||||
currentDeviceCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool addDevice(String deviceName, CallbackBriFunction callback, uint8_t initialValue = 0)
|
||||
{
|
||||
EA_DEBUG("Constructing device ");
|
||||
EA_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
|
||||
return addDevice(d);
|
||||
}
|
||||
|
||||
bool addDevice(String deviceName, CallbackColFunction callback, uint8_t initialValue = 0)
|
||||
{
|
||||
EA_DEBUG("Constructing device ");
|
||||
EA_DEBUGLN((currentDeviceCount+1));
|
||||
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
|
||||
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
|
||||
return addDevice(d);
|
||||
}
|
||||
|
||||
//basic implementation of Philips hue api functions needed for basic Alexa control
|
||||
#ifdef ESPALEXA_ASYNC
|
||||
bool handleAlexaApiCall(AsyncWebServerRequest* request)
|
||||
{
|
||||
server = request; //copy request reference
|
||||
String req = request->url(); //body from global variable
|
||||
EA_DEBUGLN(request->contentType());
|
||||
if (request->hasParam("body", true)) // This is necessary, otherwise ESP crashes if there is no body
|
||||
{
|
||||
EA_DEBUG("BodyMethod2");
|
||||
body = request->getParam("body", true)->value();
|
||||
}
|
||||
EA_DEBUG("FinalBody: ");
|
||||
EA_DEBUGLN(body);
|
||||
#else
|
||||
bool handleAlexaApiCall(String req, String body)
|
||||
{
|
||||
#endif
|
||||
EA_DEBUGLN("AlexaApiCall");
|
||||
if (req.indexOf("api") <0) return false; //return if not an API call
|
||||
EA_DEBUGLN("ok");
|
||||
|
||||
if (body.indexOf("devicetype") > 0) //client wants a hue api username, we dont care and give static
|
||||
{
|
||||
EA_DEBUGLN("devType");
|
||||
body = "";
|
||||
server->send(200, "application/json", "[{\"success\":{\"username\": \"2WLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBQr\"}}]");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (req.indexOf("state") > 0) //client wants to control light
|
||||
{
|
||||
server->send(200, "application/json", "[{\"success\":true}]"); //short valid response
|
||||
|
||||
int tempDeviceId = req.substring(req.indexOf("lights")+7).toInt();
|
||||
EA_DEBUG("ls"); EA_DEBUGLN(tempDeviceId);
|
||||
if (body.indexOf("false")>0) {alexaOff(tempDeviceId); return true;}
|
||||
if (body.indexOf("bri")>0 ) {alexaDim(tempDeviceId, body.substring(body.indexOf("bri") +5).toInt()); return true;}
|
||||
if (body.indexOf("hue")>0 ) {alexaCol(tempDeviceId, body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt()); return true;}
|
||||
if (body.indexOf("ct") >0 ) {alexaCt (tempDeviceId, body.substring(body.indexOf("ct") +4).toInt()); return true;}
|
||||
alexaOn(tempDeviceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int pos = req.indexOf("lights");
|
||||
if (pos > 0) //client wants light info
|
||||
{
|
||||
int tempDeviceId = req.substring(pos+7).toInt();
|
||||
EA_DEBUG("l"); EA_DEBUGLN(tempDeviceId);
|
||||
|
||||
if (tempDeviceId == 0) //client wants all lights
|
||||
{
|
||||
EA_DEBUGLN("lAll");
|
||||
String jsonTemp = "{";
|
||||
for (int i = 0; i<currentDeviceCount; i++)
|
||||
{
|
||||
jsonTemp += "\"" + String(i+1) + "\":";
|
||||
jsonTemp += deviceJsonString(i+1);
|
||||
if (i < currentDeviceCount-1) jsonTemp += ",";
|
||||
}
|
||||
jsonTemp += "}";
|
||||
server->send(200, "application/json", jsonTemp);
|
||||
} else //client wants one light (tempDeviceId)
|
||||
{
|
||||
server->send(200, "application/json", deviceJsonString(tempDeviceId));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//we dont care about other api commands at this time and send empty JSON
|
||||
server->send(200, "application/json", "{}");
|
||||
return true;
|
||||
}
|
||||
|
||||
//is an unique device ID
|
||||
String getEscapedMac()
|
||||
{
|
||||
return escapedMac;
|
||||
}
|
||||
|
||||
//convert brightness (0-255) to percentage
|
||||
uint8_t toPercent(uint8_t bri)
|
||||
{
|
||||
uint16_t perc = bri * 100;
|
||||
return perc / 255;
|
||||
}
|
||||
|
||||
~Espalexa(){delete devices;} //note: Espalexa is NOT meant to be destructed
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
176
wled00/src/dependencies/espalexa/EspalexaDevice.cpp
Normal file
176
wled00/src/dependencies/espalexa/EspalexaDevice.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
//EspalexaDevice Class
|
||||
|
||||
#include "EspalexaDevice.h"
|
||||
|
||||
EspalexaDevice::EspalexaDevice(){}
|
||||
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, CallbackBriFunction gnCallback, uint8_t initialValue) { //constructor
|
||||
|
||||
_deviceName = deviceName;
|
||||
_callback = gnCallback;
|
||||
_val = initialValue;
|
||||
_val_last = _val;
|
||||
}
|
||||
|
||||
EspalexaDevice::EspalexaDevice(String deviceName, CallbackColFunction gnCallback, uint8_t initialValue) { //constructor for color device
|
||||
|
||||
_deviceName = deviceName;
|
||||
_callbackCol = gnCallback;
|
||||
_callback = nullptr;
|
||||
_val = initialValue;
|
||||
_val_last = _val;
|
||||
}
|
||||
|
||||
EspalexaDevice::~EspalexaDevice(){/*nothing to destruct*/}
|
||||
|
||||
bool EspalexaDevice::isColorDevice()
|
||||
{
|
||||
//if brightness-only callback is null, we have color device
|
||||
return (_callback == nullptr);
|
||||
}
|
||||
|
||||
bool EspalexaDevice::isColorTemperatureMode()
|
||||
{
|
||||
return _ct;
|
||||
}
|
||||
|
||||
String EspalexaDevice::getName()
|
||||
{
|
||||
return _deviceName;
|
||||
}
|
||||
|
||||
uint8_t EspalexaDevice::getLastChangedProperty()
|
||||
{
|
||||
return _changed;
|
||||
}
|
||||
|
||||
uint8_t EspalexaDevice::getValue()
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
uint16_t EspalexaDevice::getHue()
|
||||
{
|
||||
return _hue;
|
||||
}
|
||||
|
||||
uint8_t EspalexaDevice::getSat()
|
||||
{
|
||||
return _sat;
|
||||
}
|
||||
|
||||
uint16_t EspalexaDevice::getCt()
|
||||
{
|
||||
if (_ct == 0) return 500;
|
||||
return _ct;
|
||||
}
|
||||
|
||||
uint32_t EspalexaDevice::getColorRGB()
|
||||
{
|
||||
uint8_t rgb[3];
|
||||
|
||||
if (isColorTemperatureMode())
|
||||
{
|
||||
//TODO tweak a bit to match hue lamp characteristics
|
||||
//based on https://gist.github.com/paulkaplan/5184275
|
||||
float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100)
|
||||
float r, g, b;
|
||||
|
||||
if( temp <= 66 ){
|
||||
r = 255;
|
||||
g = temp;
|
||||
g = 99.470802 * log(g) - 161.119568;
|
||||
if( temp <= 19){
|
||||
b = 0;
|
||||
} else {
|
||||
b = temp-10;
|
||||
b = 138.517731 * log(b) - 305.044793;
|
||||
}
|
||||
} else {
|
||||
r = temp - 60;
|
||||
r = 329.698727 * pow(r, -0.13320476);
|
||||
g = temp - 60;
|
||||
g = 288.12217 * pow(g, -0.07551485 );
|
||||
b = 255;
|
||||
}
|
||||
|
||||
rgb[0] = (byte)constrain(r,0.1,255.1);
|
||||
rgb[1] = (byte)constrain(g,0.1,255.1);
|
||||
rgb[2] = (byte)constrain(b,0.1,255.1);
|
||||
}
|
||||
else
|
||||
{ //hue + sat mode
|
||||
float h = ((float)_hue)/65535.0;
|
||||
float s = ((float)_sat)/255.0;
|
||||
byte i = floor(h*6);
|
||||
float f = h * 6-i;
|
||||
float p = 255 * (1-s);
|
||||
float q = 255 * (1-f*s);
|
||||
float t = 255 * (1-(1-f)*s);
|
||||
switch (i%6) {
|
||||
case 0: rgb[0]=255,rgb[1]=t,rgb[2]=p;break;
|
||||
case 1: rgb[0]=q,rgb[1]=255,rgb[2]=p;break;
|
||||
case 2: rgb[0]=p,rgb[1]=255,rgb[2]=t;break;
|
||||
case 3: rgb[0]=p,rgb[1]=q,rgb[2]=255;break;
|
||||
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
|
||||
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
|
||||
}
|
||||
}
|
||||
return ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2]));
|
||||
}
|
||||
|
||||
uint8_t EspalexaDevice::getLastValue()
|
||||
{
|
||||
if (_val_last == 0) return 255;
|
||||
return _val_last;
|
||||
}
|
||||
|
||||
void EspalexaDevice::setPropertyChanged(uint8_t p)
|
||||
{
|
||||
//0: initial 1: on 2: off 3: bri 4: col 5: ct
|
||||
_changed = p;
|
||||
}
|
||||
|
||||
//you need to re-discover the device for the Alexa name to change
|
||||
void EspalexaDevice::setName(String name)
|
||||
{
|
||||
_deviceName = name;
|
||||
}
|
||||
|
||||
void EspalexaDevice::setValue(uint8_t val)
|
||||
{
|
||||
if (_val != 0)
|
||||
{
|
||||
_val_last = _val;
|
||||
}
|
||||
if (val != 0)
|
||||
{
|
||||
_val_last = val;
|
||||
}
|
||||
_val = val;
|
||||
}
|
||||
|
||||
void EspalexaDevice::setPercent(uint8_t perc)
|
||||
{
|
||||
uint16_t val = perc * 255;
|
||||
val /= 100;
|
||||
if (val > 255) val = 255;
|
||||
setValue(val);
|
||||
}
|
||||
|
||||
void EspalexaDevice::setColor(uint16_t hue, uint8_t sat)
|
||||
{
|
||||
_hue = hue;
|
||||
_sat = sat;
|
||||
_ct = 0;
|
||||
}
|
||||
|
||||
void EspalexaDevice::setColor(uint16_t ct)
|
||||
{
|
||||
_ct = ct;
|
||||
}
|
||||
|
||||
void EspalexaDevice::doCallback()
|
||||
{
|
||||
(_callback != nullptr) ? _callback(_val) : _callbackCol(_val, getColorRGB());
|
||||
}
|
||||
46
wled00/src/dependencies/espalexa/EspalexaDevice.h
Normal file
46
wled00/src/dependencies/espalexa/EspalexaDevice.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef EspalexaDevice_h
|
||||
#define EspalexaDevice_h
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
typedef void (*CallbackBriFunction) (uint8_t br);
|
||||
typedef void (*CallbackColFunction) (uint8_t br, uint32_t col);
|
||||
|
||||
class EspalexaDevice {
|
||||
private:
|
||||
String _deviceName;
|
||||
CallbackBriFunction _callback;
|
||||
CallbackColFunction _callbackCol;
|
||||
uint8_t _val, _val_last, _sat = 0;
|
||||
uint16_t _hue = 0, _ct = 0;
|
||||
uint8_t _changed = 0;
|
||||
|
||||
public:
|
||||
EspalexaDevice();
|
||||
~EspalexaDevice();
|
||||
EspalexaDevice(String deviceName, CallbackBriFunction gnCallback, uint8_t initialValue =0);
|
||||
EspalexaDevice(String deviceName, CallbackColFunction gnCallback, uint8_t initialValue =0);
|
||||
|
||||
bool isColorDevice();
|
||||
bool isColorTemperatureMode();
|
||||
String getName();
|
||||
uint8_t getLastChangedProperty();
|
||||
uint8_t getValue();
|
||||
uint16_t getHue();
|
||||
uint8_t getSat();
|
||||
uint16_t getCt();
|
||||
uint32_t getColorRGB();
|
||||
|
||||
void setPropertyChanged(uint8_t p);
|
||||
void setValue(uint8_t bri);
|
||||
void setPercent(uint8_t perc);
|
||||
void setName(String name);
|
||||
void setColor(uint16_t hue, uint8_t sat);
|
||||
void setColor(uint16_t ct);
|
||||
|
||||
void doCallback();
|
||||
|
||||
uint8_t getLastValue(); //last value that was not off (1-255)
|
||||
};
|
||||
|
||||
#endif
|
||||
21
wled00/src/dependencies/espalexa/LICENSE
Normal file
21
wled00/src/dependencies/espalexa/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Christian Schwinne
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
20
wled00/src/dependencies/pubsubclient/LICENSE.txt
Normal file
20
wled00/src/dependencies/pubsubclient/LICENSE.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2008-2015 Nicholas O'Leary
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
601
wled00/src/dependencies/pubsubclient/PubSubClient.cpp
Normal file
601
wled00/src/dependencies/pubsubclient/PubSubClient.cpp
Normal file
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
PubSubClient.cpp - A simple client for MQTT.
|
||||
Nick O'Leary
|
||||
http://knolleary.net
|
||||
*/
|
||||
|
||||
#include "PubSubClient.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
PubSubClient::PubSubClient() {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
this->_client = NULL;
|
||||
this->stream = NULL;
|
||||
setCallback(NULL);
|
||||
}
|
||||
|
||||
PubSubClient::PubSubClient(Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
|
||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(addr, port);
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(addr,port);
|
||||
setClient(client);
|
||||
setStream(stream);
|
||||
}
|
||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(addr, port);
|
||||
setCallback(callback);
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(addr,port);
|
||||
setCallback(callback);
|
||||
setClient(client);
|
||||
setStream(stream);
|
||||
}
|
||||
|
||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(ip, port);
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(ip,port);
|
||||
setClient(client);
|
||||
setStream(stream);
|
||||
}
|
||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(ip, port);
|
||||
setCallback(callback);
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(ip,port);
|
||||
setCallback(callback);
|
||||
setClient(client);
|
||||
setStream(stream);
|
||||
}
|
||||
|
||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(domain,port);
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(domain,port);
|
||||
setClient(client);
|
||||
setStream(stream);
|
||||
}
|
||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(domain,port);
|
||||
setCallback(callback);
|
||||
setClient(client);
|
||||
this->stream = NULL;
|
||||
}
|
||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(domain,port);
|
||||
setCallback(callback);
|
||||
setClient(client);
|
||||
setStream(stream);
|
||||
}
|
||||
|
||||
boolean PubSubClient::connect(const char *id) {
|
||||
return connect(id,NULL,NULL,0,0,0,0);
|
||||
}
|
||||
|
||||
boolean PubSubClient::connect(const char *id, const char *user, const char *pass) {
|
||||
return connect(id,user,pass,0,0,0,0);
|
||||
}
|
||||
|
||||
boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
|
||||
return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage);
|
||||
}
|
||||
|
||||
boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
|
||||
if (!connected()) {
|
||||
int result = 0;
|
||||
|
||||
if (domain != NULL) {
|
||||
result = _client->connect(this->domain, this->port);
|
||||
} else {
|
||||
result = _client->connect(this->ip, this->port);
|
||||
}
|
||||
if (result == 1) {
|
||||
nextMsgId = 1;
|
||||
// Leave room in the buffer for header and variable length field
|
||||
uint16_t length = 5;
|
||||
unsigned int j;
|
||||
|
||||
#if MQTT_VERSION == MQTT_VERSION_3_1
|
||||
uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION};
|
||||
#define MQTT_HEADER_VERSION_LENGTH 9
|
||||
#elif MQTT_VERSION == MQTT_VERSION_3_1_1
|
||||
uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION};
|
||||
#define MQTT_HEADER_VERSION_LENGTH 7
|
||||
#endif
|
||||
for (j = 0;j<MQTT_HEADER_VERSION_LENGTH;j++) {
|
||||
buffer[length++] = d[j];
|
||||
}
|
||||
|
||||
uint8_t v;
|
||||
if (willTopic) {
|
||||
v = 0x06|(willQos<<3)|(willRetain<<5);
|
||||
} else {
|
||||
v = 0x02;
|
||||
}
|
||||
|
||||
if(user != NULL) {
|
||||
v = v|0x80;
|
||||
|
||||
if(pass != NULL) {
|
||||
v = v|(0x80>>1);
|
||||
}
|
||||
}
|
||||
|
||||
buffer[length++] = v;
|
||||
|
||||
buffer[length++] = ((MQTT_KEEPALIVE) >> 8);
|
||||
buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF);
|
||||
length = writeString(id,buffer,length);
|
||||
if (willTopic) {
|
||||
length = writeString(willTopic,buffer,length);
|
||||
length = writeString(willMessage,buffer,length);
|
||||
}
|
||||
|
||||
if(user != NULL) {
|
||||
length = writeString(user,buffer,length);
|
||||
if(pass != NULL) {
|
||||
length = writeString(pass,buffer,length);
|
||||
}
|
||||
}
|
||||
|
||||
write(MQTTCONNECT,buffer,length-5);
|
||||
|
||||
lastInActivity = lastOutActivity = millis();
|
||||
|
||||
while (!_client->available()) {
|
||||
unsigned long t = millis();
|
||||
if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) {
|
||||
_state = MQTT_CONNECTION_TIMEOUT;
|
||||
_client->stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint8_t llen;
|
||||
uint16_t len = readPacket(&llen);
|
||||
|
||||
if (len == 4) {
|
||||
if (buffer[3] == 0) {
|
||||
lastInActivity = millis();
|
||||
pingOutstanding = false;
|
||||
_state = MQTT_CONNECTED;
|
||||
return true;
|
||||
} else {
|
||||
_state = buffer[3];
|
||||
}
|
||||
}
|
||||
_client->stop();
|
||||
} else {
|
||||
_state = MQTT_CONNECT_FAILED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// reads a byte into result
|
||||
boolean PubSubClient::readByte(uint8_t * result) {
|
||||
uint32_t previousMillis = millis();
|
||||
while(!_client->available()) {
|
||||
uint32_t currentMillis = millis();
|
||||
if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*result = _client->read();
|
||||
return true;
|
||||
}
|
||||
|
||||
// reads a byte into result[*index] and increments index
|
||||
boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
|
||||
uint16_t current_index = *index;
|
||||
uint8_t * write_address = &(result[current_index]);
|
||||
if(readByte(write_address)){
|
||||
*index = current_index + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
||||
uint16_t len = 0;
|
||||
if(!readByte(buffer, &len)) return 0;
|
||||
bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH;
|
||||
uint32_t multiplier = 1;
|
||||
uint16_t length = 0;
|
||||
uint8_t digit = 0;
|
||||
uint16_t skip = 0;
|
||||
uint8_t start = 0;
|
||||
|
||||
do {
|
||||
if (len == 6) {
|
||||
// Invalid remaining length encoding - kill the connection
|
||||
_state = MQTT_DISCONNECTED;
|
||||
_client->stop();
|
||||
return 0;
|
||||
}
|
||||
if(!readByte(&digit)) return 0;
|
||||
buffer[len++] = digit;
|
||||
length += (digit & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((digit & 128) != 0);
|
||||
*lengthLength = len-1;
|
||||
|
||||
if (isPublish) {
|
||||
// Read in topic length to calculate bytes to skip over for Stream writing
|
||||
if(!readByte(buffer, &len)) return 0;
|
||||
if(!readByte(buffer, &len)) return 0;
|
||||
skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2];
|
||||
start = 2;
|
||||
if (buffer[0]&MQTTQOS1) {
|
||||
// skip message id
|
||||
skip += 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint16_t i = start;i<length;i++) {
|
||||
if(!readByte(&digit)) return 0;
|
||||
if (this->stream) {
|
||||
if (isPublish && len-*lengthLength-2>skip) {
|
||||
this->stream->write(digit);
|
||||
}
|
||||
}
|
||||
if (len < MQTT_MAX_PACKET_SIZE) {
|
||||
buffer[len] = digit;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
|
||||
if (!this->stream && len > MQTT_MAX_PACKET_SIZE) {
|
||||
len = 0; // This will cause the packet to be ignored.
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
boolean PubSubClient::loop() {
|
||||
if (connected()) {
|
||||
unsigned long t = millis();
|
||||
if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) {
|
||||
if (pingOutstanding) {
|
||||
this->_state = MQTT_CONNECTION_TIMEOUT;
|
||||
_client->stop();
|
||||
return false;
|
||||
} else {
|
||||
buffer[0] = MQTTPINGREQ;
|
||||
buffer[1] = 0;
|
||||
_client->write(buffer,2);
|
||||
lastOutActivity = t;
|
||||
lastInActivity = t;
|
||||
pingOutstanding = true;
|
||||
}
|
||||
}
|
||||
if (_client->available()) {
|
||||
uint8_t llen;
|
||||
uint16_t len = readPacket(&llen);
|
||||
uint16_t msgId = 0;
|
||||
uint8_t *payload;
|
||||
if (len > 0) {
|
||||
lastInActivity = t;
|
||||
uint8_t type = buffer[0]&0xF0;
|
||||
if (type == MQTTPUBLISH) {
|
||||
if (callback) {
|
||||
uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */
|
||||
memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
|
||||
buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
|
||||
char *topic = (char*) buffer+llen+2;
|
||||
|
||||
// make sure payload can be interpreted as 'C' string
|
||||
buffer[(len < MQTT_MAX_PACKET_SIZE) ? len : MQTT_MAX_PACKET_SIZE -1] = 0;
|
||||
|
||||
// msgId only present for QOS>0
|
||||
if ((buffer[0]&0x06) == MQTTQOS1) {
|
||||
msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1];
|
||||
payload = buffer+llen+3+tl+2;
|
||||
callback(topic,payload,len-llen-3-tl-2);
|
||||
|
||||
buffer[0] = MQTTPUBACK;
|
||||
buffer[1] = 2;
|
||||
buffer[2] = (msgId >> 8);
|
||||
buffer[3] = (msgId & 0xFF);
|
||||
_client->write(buffer,4);
|
||||
lastOutActivity = t;
|
||||
|
||||
} else {
|
||||
payload = buffer+llen+3+tl;
|
||||
callback(topic,payload,len-llen-3-tl);
|
||||
}
|
||||
}
|
||||
} else if (type == MQTTPINGREQ) {
|
||||
buffer[0] = MQTTPINGRESP;
|
||||
buffer[1] = 0;
|
||||
_client->write(buffer,2);
|
||||
} else if (type == MQTTPINGRESP) {
|
||||
pingOutstanding = false;
|
||||
}
|
||||
} else if (!connected()) {
|
||||
// readPacket has closed the connection
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean PubSubClient::publish(const char* topic, const char* payload) {
|
||||
return publish(topic,(const uint8_t*)payload,strlen(payload),false);
|
||||
}
|
||||
|
||||
boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
|
||||
return publish(topic,(const uint8_t*)payload,strlen(payload),retained);
|
||||
}
|
||||
|
||||
boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) {
|
||||
return publish(topic, payload, plength, false);
|
||||
}
|
||||
|
||||
boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
|
||||
if (connected()) {
|
||||
if (MQTT_MAX_PACKET_SIZE < 5 + 2+strlen(topic) + plength) {
|
||||
// Too long
|
||||
return false;
|
||||
}
|
||||
// Leave room in the buffer for header and variable length field
|
||||
uint16_t length = 5;
|
||||
length = writeString(topic,buffer,length);
|
||||
uint16_t i;
|
||||
for (i=0;i<plength;i++) {
|
||||
buffer[length++] = payload[i];
|
||||
}
|
||||
uint8_t header = MQTTPUBLISH;
|
||||
if (retained) {
|
||||
header |= 1;
|
||||
}
|
||||
return write(header,buffer,length-5);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
|
||||
uint8_t llen = 0;
|
||||
uint8_t digit;
|
||||
unsigned int rc = 0;
|
||||
uint16_t tlen;
|
||||
unsigned int pos = 0;
|
||||
unsigned int i;
|
||||
uint8_t header;
|
||||
unsigned int len;
|
||||
|
||||
if (!connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tlen = strlen(topic);
|
||||
|
||||
header = MQTTPUBLISH;
|
||||
if (retained) {
|
||||
header |= 1;
|
||||
}
|
||||
buffer[pos++] = header;
|
||||
len = plength + 2 + tlen;
|
||||
do {
|
||||
digit = len % 128;
|
||||
len = len / 128;
|
||||
if (len > 0) {
|
||||
digit |= 0x80;
|
||||
}
|
||||
buffer[pos++] = digit;
|
||||
llen++;
|
||||
} while(len>0);
|
||||
|
||||
pos = writeString(topic,buffer,pos);
|
||||
|
||||
rc += _client->write(buffer,pos);
|
||||
|
||||
for (i=0;i<plength;i++) {
|
||||
rc += _client->write((char)pgm_read_byte_near(payload + i));
|
||||
}
|
||||
|
||||
lastOutActivity = millis();
|
||||
|
||||
return rc == tlen + 4 + plength;
|
||||
}
|
||||
|
||||
boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
||||
uint8_t lenBuf[4];
|
||||
uint8_t llen = 0;
|
||||
uint8_t digit;
|
||||
uint8_t pos = 0;
|
||||
uint16_t rc;
|
||||
uint16_t len = length;
|
||||
do {
|
||||
digit = len % 128;
|
||||
len = len / 128;
|
||||
if (len > 0) {
|
||||
digit |= 0x80;
|
||||
}
|
||||
lenBuf[pos++] = digit;
|
||||
llen++;
|
||||
} while(len>0);
|
||||
|
||||
buf[4-llen] = header;
|
||||
for (int i=0;i<llen;i++) {
|
||||
buf[5-llen+i] = lenBuf[i];
|
||||
}
|
||||
|
||||
#ifdef MQTT_MAX_TRANSFER_SIZE
|
||||
uint8_t* writeBuf = buf+(4-llen);
|
||||
uint16_t bytesRemaining = length+1+llen; //Match the length type
|
||||
uint8_t bytesToWrite;
|
||||
boolean result = true;
|
||||
while((bytesRemaining > 0) && result) {
|
||||
bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
|
||||
rc = _client->write(writeBuf,bytesToWrite);
|
||||
result = (rc == bytesToWrite);
|
||||
bytesRemaining -= rc;
|
||||
writeBuf += rc;
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
rc = _client->write(buf+(4-llen),length+1+llen);
|
||||
lastOutActivity = millis();
|
||||
return (rc == 1+llen+length);
|
||||
#endif
|
||||
}
|
||||
|
||||
boolean PubSubClient::subscribe(const char* topic) {
|
||||
return subscribe(topic, 0);
|
||||
}
|
||||
|
||||
boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
|
||||
if (qos > 1) {
|
||||
return false;
|
||||
}
|
||||
if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
|
||||
// Too long
|
||||
return false;
|
||||
}
|
||||
if (connected()) {
|
||||
// Leave room in the buffer for header and variable length field
|
||||
uint16_t length = 5;
|
||||
nextMsgId++;
|
||||
if (nextMsgId == 0) {
|
||||
nextMsgId = 1;
|
||||
}
|
||||
buffer[length++] = (nextMsgId >> 8);
|
||||
buffer[length++] = (nextMsgId & 0xFF);
|
||||
length = writeString((char*)topic, buffer,length);
|
||||
buffer[length++] = qos;
|
||||
return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-5);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean PubSubClient::unsubscribe(const char* topic) {
|
||||
if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
|
||||
// Too long
|
||||
return false;
|
||||
}
|
||||
if (connected()) {
|
||||
uint16_t length = 5;
|
||||
nextMsgId++;
|
||||
if (nextMsgId == 0) {
|
||||
nextMsgId = 1;
|
||||
}
|
||||
buffer[length++] = (nextMsgId >> 8);
|
||||
buffer[length++] = (nextMsgId & 0xFF);
|
||||
length = writeString(topic, buffer,length);
|
||||
return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-5);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PubSubClient::disconnect() {
|
||||
buffer[0] = MQTTDISCONNECT;
|
||||
buffer[1] = 0;
|
||||
_client->write(buffer,2);
|
||||
_state = MQTT_DISCONNECTED;
|
||||
_client->stop();
|
||||
lastInActivity = lastOutActivity = millis();
|
||||
}
|
||||
|
||||
uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) {
|
||||
const char* idp = string;
|
||||
uint16_t i = 0;
|
||||
pos += 2;
|
||||
while (*idp) {
|
||||
buf[pos++] = *idp++;
|
||||
i++;
|
||||
}
|
||||
buf[pos-i-2] = (i >> 8);
|
||||
buf[pos-i-1] = (i & 0xFF);
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
boolean PubSubClient::connected() {
|
||||
boolean rc;
|
||||
if (_client == NULL ) {
|
||||
rc = false;
|
||||
} else {
|
||||
rc = (int)_client->connected();
|
||||
if (!rc) {
|
||||
if (this->_state == MQTT_CONNECTED) {
|
||||
this->_state = MQTT_CONNECTION_LOST;
|
||||
_client->flush();
|
||||
_client->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
|
||||
IPAddress addr(ip[0],ip[1],ip[2],ip[3]);
|
||||
return setServer(addr,port);
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) {
|
||||
this->ip = ip;
|
||||
this->port = port;
|
||||
this->domain = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) {
|
||||
this->domain = domain;
|
||||
this->port = port;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) {
|
||||
this->callback = callback;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setClient(Client& client){
|
||||
this->_client = &client;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PubSubClient& PubSubClient::setStream(Stream& stream){
|
||||
this->stream = &stream;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int PubSubClient::state() {
|
||||
return this->_state;
|
||||
}
|
||||
144
wled00/src/dependencies/pubsubclient/PubSubClient.h
Normal file
144
wled00/src/dependencies/pubsubclient/PubSubClient.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
PubSubClient.h - A simple client for MQTT.
|
||||
Nick O'Leary
|
||||
http://knolleary.net
|
||||
*/
|
||||
|
||||
#ifndef PubSubClient_h
|
||||
#define PubSubClient_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "IPAddress.h"
|
||||
#include "Client.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#define MQTT_VERSION_3_1 3
|
||||
#define MQTT_VERSION_3_1_1 4
|
||||
|
||||
// MQTT_VERSION : Pick the version
|
||||
//#define MQTT_VERSION MQTT_VERSION_3_1
|
||||
#ifndef MQTT_VERSION
|
||||
#define MQTT_VERSION MQTT_VERSION_3_1_1
|
||||
#endif
|
||||
|
||||
// MQTT_MAX_PACKET_SIZE : Maximum packet size
|
||||
#ifndef MQTT_MAX_PACKET_SIZE
|
||||
#define MQTT_MAX_PACKET_SIZE 128
|
||||
#endif
|
||||
|
||||
// MQTT_KEEPALIVE : keepAlive interval in Seconds
|
||||
#ifndef MQTT_KEEPALIVE
|
||||
#define MQTT_KEEPALIVE 60
|
||||
#endif
|
||||
|
||||
// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
|
||||
#ifndef MQTT_SOCKET_TIMEOUT
|
||||
#define MQTT_SOCKET_TIMEOUT 62
|
||||
#endif
|
||||
|
||||
// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
|
||||
// in each write call. Needed for the Arduino Wifi Shield. Leave undefined to
|
||||
// pass the entire MQTT packet in each write call.
|
||||
//#define MQTT_MAX_TRANSFER_SIZE 80
|
||||
|
||||
// Possible values for client.state()
|
||||
#define MQTT_CONNECTION_TIMEOUT -4
|
||||
#define MQTT_CONNECTION_LOST -3
|
||||
#define MQTT_CONNECT_FAILED -2
|
||||
#define MQTT_DISCONNECTED -1
|
||||
#define MQTT_CONNECTED 0
|
||||
#define MQTT_CONNECT_BAD_PROTOCOL 1
|
||||
#define MQTT_CONNECT_BAD_CLIENT_ID 2
|
||||
#define MQTT_CONNECT_UNAVAILABLE 3
|
||||
#define MQTT_CONNECT_BAD_CREDENTIALS 4
|
||||
#define MQTT_CONNECT_UNAUTHORIZED 5
|
||||
|
||||
#define MQTTCONNECT 1 << 4 // Client request to connect to Server
|
||||
#define MQTTCONNACK 2 << 4 // Connect Acknowledgment
|
||||
#define MQTTPUBLISH 3 << 4 // Publish message
|
||||
#define MQTTPUBACK 4 << 4 // Publish Acknowledgment
|
||||
#define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1)
|
||||
#define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2)
|
||||
#define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3)
|
||||
#define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request
|
||||
#define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment
|
||||
#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request
|
||||
#define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment
|
||||
#define MQTTPINGREQ 12 << 4 // PING Request
|
||||
#define MQTTPINGRESP 13 << 4 // PING Response
|
||||
#define MQTTDISCONNECT 14 << 4 // Client is Disconnecting
|
||||
#define MQTTReserved 15 << 4 // Reserved
|
||||
|
||||
#define MQTTQOS0 (0 << 1)
|
||||
#define MQTTQOS1 (1 << 1)
|
||||
#define MQTTQOS2 (2 << 1)
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <functional>
|
||||
#define MQTT_CALLBACK_SIGNATURE std::function<void(char*, uint8_t*, unsigned int)> callback
|
||||
#else
|
||||
#define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int)
|
||||
#endif
|
||||
|
||||
class PubSubClient {
|
||||
private:
|
||||
Client* _client;
|
||||
uint8_t buffer[MQTT_MAX_PACKET_SIZE];
|
||||
uint16_t nextMsgId;
|
||||
unsigned long lastOutActivity;
|
||||
unsigned long lastInActivity;
|
||||
bool pingOutstanding;
|
||||
MQTT_CALLBACK_SIGNATURE;
|
||||
uint16_t readPacket(uint8_t*);
|
||||
boolean readByte(uint8_t * result);
|
||||
boolean readByte(uint8_t * result, uint16_t * index);
|
||||
boolean write(uint8_t header, uint8_t* buf, uint16_t length);
|
||||
uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos);
|
||||
IPAddress ip;
|
||||
const char* domain;
|
||||
uint16_t port;
|
||||
Stream* stream;
|
||||
int _state;
|
||||
public:
|
||||
PubSubClient();
|
||||
PubSubClient(Client& client);
|
||||
PubSubClient(IPAddress, uint16_t, Client& client);
|
||||
PubSubClient(IPAddress, uint16_t, Client& client, Stream&);
|
||||
PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
||||
PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
||||
PubSubClient(uint8_t *, uint16_t, Client& client);
|
||||
PubSubClient(uint8_t *, uint16_t, Client& client, Stream&);
|
||||
PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
||||
PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
||||
PubSubClient(const char*, uint16_t, Client& client);
|
||||
PubSubClient(const char*, uint16_t, Client& client, Stream&);
|
||||
PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
||||
PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
||||
|
||||
PubSubClient& setServer(IPAddress ip, uint16_t port);
|
||||
PubSubClient& setServer(uint8_t * ip, uint16_t port);
|
||||
PubSubClient& setServer(const char * domain, uint16_t port);
|
||||
PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
|
||||
PubSubClient& setClient(Client& client);
|
||||
PubSubClient& setStream(Stream& stream);
|
||||
|
||||
boolean connect(const char* id);
|
||||
boolean connect(const char* id, const char* user, const char* pass);
|
||||
boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
||||
boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
||||
void disconnect();
|
||||
boolean publish(const char* topic, const char* payload);
|
||||
boolean publish(const char* topic, const char* payload, boolean retained);
|
||||
boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
|
||||
boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
|
||||
boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
|
||||
boolean subscribe(const char* topic);
|
||||
boolean subscribe(const char* topic, uint8_t qos);
|
||||
boolean unsubscribe(const char* topic);
|
||||
boolean loop();
|
||||
boolean connected();
|
||||
int state();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,8 @@
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
#include <Time.h> //http://www.arduino.cc/playground/Code/Time
|
||||
|
||||
#include "../time/Time.h" //http://www.arduino.cc/playground/Code/Time
|
||||
|
||||
//convenient constants for dstRules
|
||||
enum week_t {Last, First, Second, Third, Fourth};
|
||||
|
||||
@@ -90,8 +90,8 @@ WebServer::~WebServer() {
|
||||
void WebServer::begin() {
|
||||
_currentStatus = HC_NONE;
|
||||
_server.begin();
|
||||
if(!_headerKeysCount)
|
||||
collectHeaders(0, 0);
|
||||
//if(!_headerKeysCount)
|
||||
//collectHeaders(0, 0);
|
||||
}
|
||||
|
||||
bool WebServer::authenticate(const char * username, const char * password){
|
||||
@@ -408,15 +408,13 @@ String WebServer::header(String name) {
|
||||
return String();
|
||||
}
|
||||
|
||||
void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
|
||||
_headerKeysCount = headerKeysCount + 1;
|
||||
if (_currentHeaders)
|
||||
delete[]_currentHeaders;
|
||||
_currentHeaders = new RequestArgument[_headerKeysCount];
|
||||
//Modified by Aircoookie to work for WLED
|
||||
void WebServer::collectHeaders(String headerKey) {
|
||||
_headerKeysCount = 2;
|
||||
if (_currentHeaders) delete[]_currentHeaders;
|
||||
_currentHeaders = new RequestArgument[2];
|
||||
_currentHeaders[0].key = AUTHORIZATION_HEADER;
|
||||
for (int i = 1; i < _headerKeysCount; i++){
|
||||
_currentHeaders[i].key = headerKeys[i-1];
|
||||
}
|
||||
_currentHeaders[1].key = headerKey;
|
||||
}
|
||||
|
||||
String WebServer::header(int i) {
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
String argName(int i); // get request argument name by number
|
||||
int args(); // get arguments count
|
||||
bool hasArg(String name); // check if argument exists
|
||||
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect
|
||||
void collectHeaders(String headerKey); // set the request headers to collect
|
||||
String header(String name); // get request header value by name
|
||||
String header(int i); // get request header value by number
|
||||
String headerName(int i); // get request header name by number
|
||||
|
||||
@@ -1,195 +1,320 @@
|
||||
/*
|
||||
* Main sketch
|
||||
* Main sketch, global variable declarations
|
||||
*/
|
||||
/*
|
||||
* @title WLED project sketch
|
||||
* @version 0.6.2
|
||||
* @version 0.8.3
|
||||
* @author Christian Schwinne
|
||||
*/
|
||||
|
||||
|
||||
//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
|
||||
|
||||
//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS).
|
||||
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
|
||||
|
||||
//You are required to disable over-the-air updates:
|
||||
//#define WLED_DISABLE_OTA
|
||||
|
||||
//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
|
||||
|
||||
//to toggle usb serial debug (un)comment following line(s)
|
||||
//#define WLED_DEBUG
|
||||
|
||||
|
||||
//library inclusions
|
||||
#include <Arduino.h>
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include "src/dependencies/webserver/WebServer.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include "src/dependencies/webserver/WebServer.h"
|
||||
#include <HTTPClient.h>
|
||||
/*#ifndef WLED_DISABLE_INFRARED
|
||||
#include <IRremote.h>
|
||||
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#ifndef WLED_DISABLE_INFRARED
|
||||
#include <IRremoteESP8266.h>
|
||||
#include <IRrecv.h>
|
||||
#include <IRutils.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <WiFiUDP.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <DNSServer.h>
|
||||
#include "src/dependencies/webserver/ESP8266HTTPUpdateServer.h"
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
#include <ArduinoOTA.h>
|
||||
#include "src/dependencies/webserver/ESP8266HTTPUpdateServer.h"
|
||||
#endif
|
||||
#include "src/dependencies/time/Time.h"
|
||||
#include "src/dependencies/time/TimeLib.h"
|
||||
#include "src/dependencies/timezone/Timezone.h"
|
||||
#include "htmls00.h"
|
||||
#include "htmls01.h"
|
||||
#include "htmls02.h"
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
#define ESPALEXA_MAXDEVICES 1
|
||||
#include "src/dependencies/espalexa/Espalexa.h"
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
#include "src/dependencies/blynk/BlynkSimpleEsp.h"
|
||||
#endif
|
||||
#include "src/dependencies/e131/E131.h"
|
||||
#include "src/dependencies/pubsubclient/PubSubClient.h"
|
||||
#include "html_classic.h"
|
||||
#include "html_mobile.h"
|
||||
#include "html_settings.h"
|
||||
#include "html_other.h"
|
||||
#include "WS2812FX.h"
|
||||
#include "ir_codes.h"
|
||||
|
||||
//version in format yymmddb (b = daily build)
|
||||
#define VERSION 1804011
|
||||
const String versionString = "0.6.2";
|
||||
|
||||
//AP and OTA default passwords (change them!)
|
||||
String apPass = "wled1234";
|
||||
String otaPass = "wledota";
|
||||
//version code in format yymmddb (b = daily build)
|
||||
#define VERSION 1902122
|
||||
char versionString[] = "0.8.3";
|
||||
|
||||
|
||||
//AP and OTA default passwords (for maximum change them!)
|
||||
char apPass[65] = "wled1234";
|
||||
char otaPass[33] = "wledota";
|
||||
|
||||
//If you have an RGBW strip, also uncomment first line in WS2812FX.h!
|
||||
bool useRGBW = false;
|
||||
|
||||
//spiffs FS only useful for debug (only ESP8266)
|
||||
//#define USEFS
|
||||
|
||||
//to toggle usb serial debug (un)comment following line(s)
|
||||
//#define DEBUG
|
||||
|
||||
//Hardware-settings (only changeble via code)
|
||||
#define LEDCOUNT 255 //maximum, exact count set-able via settings
|
||||
byte buttonPin = 0; //needs pull-up
|
||||
byte auxPin = 15; //use e.g. for external relay
|
||||
byte auxDefaultState = 0; //0: input 1: high 2: low
|
||||
byte auxTriggeredState = 0; //0: input 1: high 2: low
|
||||
//Hardware CONFIG (only changeble HERE, not at runtime)
|
||||
//LED strip pin, button pin and IR pin changeable in NpbWrapper.h!
|
||||
|
||||
//Default CONFIG
|
||||
String serverDescription = versionString;
|
||||
byte currentTheme = 0;
|
||||
String clientSSID = "Your_Network";
|
||||
String clientPass = "";
|
||||
String cmDNS = "led";
|
||||
byte ledCount = 10; //lowered to prevent accidental overcurrent
|
||||
String apSSID = ""; //AP off by default (unless setup)
|
||||
byte apChannel = 1;
|
||||
byte apHide = 0;
|
||||
byte apWaitTimeSecs = 32;
|
||||
bool recoveryAPDisabled = false;
|
||||
IPAddress staticIP(0, 0, 0, 0);
|
||||
IPAddress staticGateway(0, 0, 0, 0);
|
||||
IPAddress staticSubnet(255, 255, 255, 0);
|
||||
IPAddress staticDNS(8, 8, 8, 8); //only for NTP
|
||||
bool useHSB = true, useHSBDefault = true;
|
||||
bool turnOnAtBoot = true;
|
||||
bool initLedsLast = false;
|
||||
byte bootPreset = 0;
|
||||
byte colS[]{255, 159, 0};
|
||||
byte colSecS[]{0, 0, 0};
|
||||
byte whiteS = 0;
|
||||
byte whiteSecS = 0;
|
||||
byte briS = 127;
|
||||
byte nightlightTargetBri = 0;
|
||||
bool fadeTransition = true;
|
||||
bool sweepTransition = false, sweepDirection = true;
|
||||
uint16_t transitionDelay = 1200;
|
||||
bool reverseMode = false;
|
||||
bool otaLock = false, wifiLock = false;
|
||||
bool aOtaEnabled = true;
|
||||
bool buttonEnabled = true;
|
||||
bool notifyDirect = true, notifyButton = true, notifyDirectDefault = true, alexaNotify = false, macroNotify = false, notifyTwice = false;
|
||||
bool receiveNotifications = true, receiveNotificationBrightness = true, receiveNotificationColor = true, receiveNotificationEffects = true;
|
||||
byte briMultiplier = 100;
|
||||
byte nightlightDelayMins = 60;
|
||||
bool nightlightFade = true;
|
||||
uint16_t udpPort = 21324;
|
||||
byte effectDefault = 0;
|
||||
byte auxDefaultState = 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
|
||||
|
||||
|
||||
//WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
||||
char clientSSID[33] = "Your_Network";
|
||||
char clientPass[65] = "";
|
||||
char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local)
|
||||
char apSSID[65] = ""; //AP off by default (unless setup)
|
||||
byte apChannel = 1; //2.4GHz WiFi AP channel (1-13)
|
||||
byte apHide = 0; //hidden AP SSID
|
||||
byte apWaitTimeSecs = 32; //time to wait for connection before opening AP
|
||||
bool recoveryAPDisabled = false; //never open AP (not recommended)
|
||||
IPAddress staticIP(0, 0, 0, 0); //static IP of ESP
|
||||
IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP
|
||||
IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks
|
||||
IPAddress staticDNS(8, 8, 8, 8); //only for NTP, google DNS server
|
||||
|
||||
|
||||
//LED CONFIG
|
||||
uint16_t ledCount = 30; //overcurrent prevented by ABL
|
||||
bool useRGBW = false; //SK6812 strips can contain an extra White channel
|
||||
bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB
|
||||
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
|
||||
bool turnOnAtBoot = true; //turn on LEDs at power-up
|
||||
byte bootPreset = 0; //save preset to load after power-up
|
||||
|
||||
byte colS[]{255, 159, 0, 0}; //default RGB(W) color
|
||||
byte colSecS[]{0, 0, 0, 0}; //default RGB(W) secondary color
|
||||
byte briS = 127; //default brightness
|
||||
byte effectDefault = 0;
|
||||
byte effectSpeedDefault = 75;
|
||||
byte effectIntensityDefault = 128;
|
||||
//NTP stuff
|
||||
bool ntpEnabled = false;
|
||||
String ntpServerName = "0.wled.pool.ntp.org";
|
||||
//custom chase
|
||||
byte ccNumPrimary = 2;
|
||||
byte ccNumSecondary = 4;
|
||||
byte ccIndex1 = 0;
|
||||
byte ccIndex2 = ledCount -1;
|
||||
bool ccFromStart = true, ccFromEnd = false;
|
||||
byte ccStep = 1;
|
||||
byte ccStart = 0;
|
||||
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
|
||||
|
||||
//alexa
|
||||
bool alexaEnabled = true;
|
||||
String alexaInvocationName = "Light";
|
||||
bool useGammaCorrectionBri = false; //gamma correct brightness (not recommended)
|
||||
bool useGammaCorrectionRGB = true; //gamma correct colors (strongly recommended)
|
||||
|
||||
byte macroBoot = 0, macroNl = 0;
|
||||
byte nightlightTargetBri = 0; //brightness after nightlight is over
|
||||
byte nightlightDelayMins = 60;
|
||||
bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over
|
||||
bool fadeTransition = true; //enable crossfading color transition
|
||||
bool enableSecTransition = true; //also enable transition for secondary color
|
||||
uint16_t transitionDelay = 900; //default crossfade duration in ms
|
||||
|
||||
bool reverseMode = false; //flip entire LED strip (reverses all effect directions)
|
||||
bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater)
|
||||
byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127)
|
||||
|
||||
|
||||
//User Interface CONFIG
|
||||
char serverDescription[33] = "WLED Light"; //Name of module
|
||||
byte currentTheme = 0; //UI theme index for settings and classic UI
|
||||
byte uiConfiguration = 0; //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
|
||||
bool buttonEnabled = true;
|
||||
bool irEnabled = false; //Infrared receiver
|
||||
|
||||
uint16_t udpPort = 21324; //WLED notifier default port
|
||||
uint16_t udpRgbPort = 19446; //Hyperion port
|
||||
|
||||
bool receiveNotificationBrightness = true; //apply brightness from incoming notifications
|
||||
bool receiveNotificationColor = true; //apply color
|
||||
bool receiveNotificationEffects = true; //apply effects setup
|
||||
bool notifyDirect = true; //send notification if change via UI or HTTP API
|
||||
bool notifyButton = true; //send if updated by button or infrared remote
|
||||
bool notifyAlexa = false; //send notification if updated via Alexa
|
||||
bool notifyMacro = false; //send notification for macro
|
||||
bool notifyHue = true; //send notification if Hue light changes
|
||||
bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably
|
||||
|
||||
bool alexaEnabled = true; //enable device discovery by Amazon Echo
|
||||
char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand
|
||||
|
||||
char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made
|
||||
|
||||
uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode
|
||||
int arlsOffset = 0; //realtime LED offset
|
||||
bool receiveDirect = true; //receive UDP realtime
|
||||
bool enableRealtimeUI = false; //web UI accessible during realtime mode (works on ESP32, lags out ESP8266)
|
||||
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 e131Enabled = true; //settings for E1.31 (sACN) protocol
|
||||
uint16_t e131Universe = 1;
|
||||
bool e131Multicast = false;
|
||||
|
||||
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
|
||||
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
|
||||
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
|
||||
|
||||
bool huePollingEnabled = false; //poll hue bridge for light state
|
||||
uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response
|
||||
char hueApiKey[47] = "api"; //key token will be obtained from bridge
|
||||
byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section)
|
||||
IPAddress hueIP = (0,0,0,0); //IP address of the bridge
|
||||
bool hueApplyOnOff = true;
|
||||
bool hueApplyBri = true;
|
||||
bool hueApplyColor = true;
|
||||
|
||||
|
||||
//Time CONFIG
|
||||
bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros
|
||||
bool useAMPM = false; //12h/24h clock format
|
||||
byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino
|
||||
int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation
|
||||
|
||||
byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie
|
||||
byte overlayMin = 0, overlayMax = ledCount-1; //boundaries of overlay mode
|
||||
|
||||
byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be
|
||||
bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel
|
||||
bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position
|
||||
|
||||
char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino
|
||||
bool cronixieBacklight = true; //Allow digits to be back-illuminated
|
||||
|
||||
bool countdownMode = false; //Clock will count down towards date
|
||||
byte countdownYear = 19, countdownMonth = 1; //Countdown target date, year is last two digits
|
||||
byte countdownDay = 1, countdownHour = 0;
|
||||
byte countdownMin = 0, countdownSec = 0;
|
||||
|
||||
|
||||
byte macroBoot = 0; //macro loaded after startup
|
||||
byte macroNl = 0; //after nightlight delay over
|
||||
byte macroCountdown = 0;
|
||||
byte macroAlexaOn = 0, macroAlexaOff = 0;
|
||||
byte macroButton = 0, macroCountdown = 0, macroLongPress = 0;
|
||||
byte macroButton = 0, macroLongPress = 0;
|
||||
|
||||
unsigned long countdownTime = 1514764800L;
|
||||
|
||||
double transitionResolution = 0.011;
|
||||
//Security CONFIG
|
||||
bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks
|
||||
bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled
|
||||
bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on
|
||||
|
||||
//hue
|
||||
bool huePollingEnabled = false, hueAttempt = false;
|
||||
uint16_t huePollIntervalMs = 2500;
|
||||
String hueApiKey = "api";
|
||||
byte huePollLightId = 1;
|
||||
IPAddress hueIP = (0,0,0,0);
|
||||
bool notifyHue = true;
|
||||
bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true;
|
||||
|
||||
//Internal vars
|
||||
byte col[]{0, 0, 0};
|
||||
byte colOld[]{0, 0, 0};
|
||||
byte colT[]{0, 0, 0};
|
||||
byte colIT[]{0, 0, 0};
|
||||
byte colSec[]{0, 0, 0};
|
||||
byte colSecIT[]{0, 0, 0};
|
||||
byte white, whiteOld, whiteT, whiteIT;
|
||||
byte whiteSec, whiteSecIT;
|
||||
byte lastRandomIndex = 0;
|
||||
uint16_t userVar0 = 0, userVar1 = 0;
|
||||
|
||||
|
||||
|
||||
//internal global variable declarations
|
||||
//color
|
||||
byte col[]{255, 159, 0, 0}; //target RGB(W) color
|
||||
byte colOld[]{0, 0, 0, 0}; //color before transition
|
||||
byte colT[]{0, 0, 0, 0}; //current color
|
||||
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 colSecOld[]{0, 0, 0, 0};
|
||||
byte colSecIT[]{0, 0, 0, 0};
|
||||
|
||||
byte lastRandomIndex = 0; //used to save last random color so the new one is not the same
|
||||
|
||||
//transitions
|
||||
bool transitionActive = false;
|
||||
uint16_t transitionDelayDefault = transitionDelay;
|
||||
uint16_t transitionDelayTemp = transitionDelay;
|
||||
unsigned long transitionStartTime;
|
||||
float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f
|
||||
|
||||
//nightlight
|
||||
bool nightlightActive = false;
|
||||
bool nightlightActiveOld = false;
|
||||
uint32_t nightlightDelayMs = 10;
|
||||
uint8_t nightlightDelayMinsDefault = nightlightDelayMins;
|
||||
unsigned long nightlightStartTime;
|
||||
float tperLast = 0;
|
||||
byte bri = 0;
|
||||
byte briNlT = 0; //current nightlight brightness
|
||||
|
||||
//brightness
|
||||
bool offMode = false;
|
||||
unsigned long lastOnTime = 0;
|
||||
byte bri = briS;
|
||||
byte briOld = 0;
|
||||
byte briT = 0;
|
||||
byte briIT = 0;
|
||||
byte briLast = 127;
|
||||
bool transitionActive = false;
|
||||
byte briLast = 127; //brightness before turned off. Used for toggle function
|
||||
|
||||
//button
|
||||
bool buttonPressedBefore = false;
|
||||
unsigned long buttonPressedTime = 0;
|
||||
|
||||
//notifications
|
||||
bool notifyDirectDefault = notifyDirect;
|
||||
bool receiveNotifications = true;
|
||||
unsigned long notificationSentTime = 0;
|
||||
byte notificationSentCallMode = 0;
|
||||
bool notificationTwoRequired = false;
|
||||
bool nightlightActive = false;
|
||||
bool nightlightActiveOld = false;
|
||||
uint32_t nightlightDelayMs;
|
||||
byte briNlT;
|
||||
byte effectCurrent = 0;
|
||||
byte effectSpeed = 75;
|
||||
byte effectIntensity = 128;
|
||||
bool onlyAP = false;
|
||||
bool udpConnected = false;
|
||||
String cssCol[]={"","","","","",""};
|
||||
String cssFont="Verdana";
|
||||
String cssColorString="";
|
||||
//NTP stuff
|
||||
bool ntpConnected = false;
|
||||
byte currentTimezone = 0;
|
||||
time_t local;
|
||||
int utcOffsetSecs = 0;
|
||||
|
||||
//effects
|
||||
byte effectCurrent = effectDefault;
|
||||
byte effectSpeed = effectSpeedDefault;
|
||||
byte effectIntensity = effectIntensityDefault;
|
||||
byte effectPalette = effectPaletteDefault;
|
||||
|
||||
//network
|
||||
bool onlyAP = false; //only Access Point active, no connection to home network
|
||||
bool udpConnected = false, udpRgbConnected = false;
|
||||
|
||||
//ui style
|
||||
char cssCol[6][9]={"","","","","",""};
|
||||
bool showWelcomePage = false;
|
||||
|
||||
//hue
|
||||
String hueError = "Inactive";
|
||||
char hueError[25] = "Inactive";
|
||||
uint16_t hueFailCount = 0;
|
||||
float hueXLast=0, hueYLast=0;
|
||||
uint16_t hueHueLast=0, hueCtLast=0;
|
||||
byte hueSatLast=0, hueBriLast=0;
|
||||
long hueLastRequestSent = 0;
|
||||
uint32_t huePollIntervalMsTemp = huePollIntervalMs;
|
||||
unsigned long hueLastRequestSent = 0;
|
||||
unsigned long huePollIntervalMsTemp = huePollIntervalMs;
|
||||
bool hueAttempt = false;
|
||||
|
||||
//overlay stuff
|
||||
byte overlayDefault = 0;
|
||||
byte overlayCurrent = 0;
|
||||
byte overlayMin = 0, overlayMax = ledCount-1;
|
||||
byte analogClock12pixel = 0;
|
||||
bool analogClockSecondsTrail = false;
|
||||
bool analogClock5MinuteMarks = false;
|
||||
//overlays
|
||||
byte overlayCurrent = overlayDefault;
|
||||
byte overlaySpeed = 200;
|
||||
unsigned long overlayRefreshMs = 200;
|
||||
unsigned long overlayRefreshedTime;
|
||||
@@ -197,79 +322,120 @@ int overlayArr[6];
|
||||
uint16_t overlayDur[6];
|
||||
uint16_t overlayPauseDur[6];
|
||||
int nixieClockI = -1;
|
||||
bool nixiePause;
|
||||
byte countdownYear=19, countdownMonth=1, countdownDay=1, countdownHour=0, countdownMin=0, countdownSec=0; //year is actual year -2000
|
||||
bool countdownOverTriggered = true;
|
||||
bool nixiePause = false;
|
||||
|
||||
//cronixie
|
||||
String cronixieDisplay = "HHMMSS";
|
||||
byte dP[]{0,0,0,0,0,0};
|
||||
bool useAMPM = false;
|
||||
bool cronixieBacklight = true;
|
||||
bool countdownMode = false;
|
||||
bool cronixieInit = false;
|
||||
|
||||
uint32_t arlsTimeoutMillis = 2500;
|
||||
bool arlsTimeout = false;
|
||||
unsigned long arlsTimeoutTime;
|
||||
byte auxTime = 0;
|
||||
unsigned long auxStartTime;
|
||||
bool auxActive, auxActiveBefore;
|
||||
bool showWelcomePage = false;
|
||||
//countdown
|
||||
unsigned long countdownTime = 1514764800L;
|
||||
bool countdownOverTriggered = true;
|
||||
|
||||
bool useGammaCorrectionBri = false;
|
||||
bool useGammaCorrectionRGB = true;
|
||||
int arlsOffset = -22; //10: -22 assuming arls52
|
||||
//timer
|
||||
byte lastTimerMinute = 0;
|
||||
byte timerHours[] = {0,0,0,0,0,0,0,0};
|
||||
byte timerMinutes[] = {0,0,0,0,0,0,0,0};
|
||||
byte timerMacro[] = {0,0,0,0,0,0,0,0};
|
||||
byte timerWeekday[] = {255,255,255,255,255,255,255,255}; //weekdays to activate on
|
||||
//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity
|
||||
|
||||
//blynk
|
||||
bool blynkEnabled = false;
|
||||
|
||||
//preset cycling
|
||||
bool presetCyclingEnabled = false;
|
||||
byte presetCycleMin = 1, presetCycleMax = 5;
|
||||
uint16_t presetCycleTime = 1250;
|
||||
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
|
||||
bool presetApplyBri = false, presetApplyCol = true, presetApplyFx = true;
|
||||
bool saveCurrPresetCycConf = false;
|
||||
|
||||
//realtime
|
||||
bool realtimeActive = false;
|
||||
IPAddress realtimeIP = (0,0,0,0);
|
||||
unsigned long realtimeTimeout = 0;
|
||||
|
||||
//mqtt
|
||||
bool mqttInit = false;
|
||||
long lastMQTTReconnectAttempt = 0;
|
||||
long lastInterfaceUpdate = 0;
|
||||
byte interfaceUpdateCallMode = 0;
|
||||
uint32_t mqttFailedConAttempts = 0;
|
||||
|
||||
//auxiliary debug pin
|
||||
byte auxTime = 0;
|
||||
unsigned long auxStartTime = 0;
|
||||
bool auxActive = false, auxActiveBefore = false;
|
||||
|
||||
//alexa udp
|
||||
WiFiUDP UDP;
|
||||
IPAddress ipMulti(239, 255, 255, 250);
|
||||
unsigned int portMulti = 1900;
|
||||
char packetBuffer[255];
|
||||
String escapedMac;
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
Espalexa espalexa;
|
||||
EspalexaDevice* espalexaDevice;
|
||||
#endif
|
||||
|
||||
//dns server
|
||||
DNSServer dnsServer;
|
||||
bool dnsActive = false;
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WebServer server(80);
|
||||
#else
|
||||
ESP8266WebServer server(80);
|
||||
#endif
|
||||
HTTPClient hueClient;
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
WiFiUDP notifierUdp;
|
||||
WiFiUDP ntpUdp;
|
||||
IPAddress ntpServerIP;
|
||||
unsigned int ntpLocalPort = 2390;
|
||||
const uint16_t NTP_PACKET_SIZE = 48;
|
||||
byte ntpPacketBuffer[NTP_PACKET_SIZE];
|
||||
//network time
|
||||
bool ntpConnected = false;
|
||||
time_t local = 0;
|
||||
unsigned long ntpLastSyncTime = 999000000L;
|
||||
unsigned long ntpPacketSentTime = 999000000L;
|
||||
IPAddress ntpServerIP;
|
||||
unsigned int ntpLocalPort = 2390;
|
||||
#define NTP_PACKET_SIZE 48
|
||||
|
||||
WS2812FX strip = WS2812FX(LEDCOUNT);
|
||||
//string temp buffer
|
||||
#define OMAX 2000
|
||||
char obuf[OMAX];
|
||||
uint16_t olen = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
//server library objects
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WebServer server(80);
|
||||
#else
|
||||
ESP8266WebServer server(80);
|
||||
#endif
|
||||
HTTPClient* hueClient = NULL;
|
||||
WiFiClient* mqttTCPClient = NULL;
|
||||
PubSubClient* mqtt = NULL;
|
||||
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
#endif
|
||||
|
||||
//udp interface objects
|
||||
WiFiUDP notifierUdp, rgbUdp;
|
||||
WiFiUDP ntpUdp;
|
||||
E131* e131;
|
||||
|
||||
//led fx library object
|
||||
WS2812FX strip = WS2812FX();
|
||||
|
||||
//debug macros
|
||||
#ifdef WLED_DEBUG
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
#define DEBUG_PRINTLN(x) Serial.println (x)
|
||||
#define DEBUG_PRINTF(x) Serial.printf (x)
|
||||
unsigned long debugTime = 0;
|
||||
int lastWifiState = 3;
|
||||
unsigned long wifiStateChangedTime = 0;
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINTF(x)
|
||||
#endif
|
||||
|
||||
//filesystem
|
||||
#ifdef USEFS
|
||||
#include <FS.h>;
|
||||
File fsUploadFile;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
long debugTime = 0;
|
||||
int lastWifiState = 3;
|
||||
long wifiStateChangedTime = 0;
|
||||
#include <FS.h>;
|
||||
File fsUploadFile;
|
||||
#endif
|
||||
|
||||
//gamma 2.4 lookup table used for color correction
|
||||
const byte gamma8[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
@@ -290,67 +456,113 @@ const byte gamma8[] = {
|
||||
|
||||
String txd = "Please disable OTA Lock in security settings!";
|
||||
|
||||
//function prototypes
|
||||
void serveMessage(int,String,String,int=255);
|
||||
|
||||
void down()
|
||||
{
|
||||
briT = 0;
|
||||
setAllLeds();
|
||||
DEBUG_PRINTLN("MODULE TERMINATED");
|
||||
while (1) {delay(1000);}
|
||||
}
|
||||
|
||||
//turns all LEDs off and restarts ESP
|
||||
void reset()
|
||||
{
|
||||
briT = 0;
|
||||
delay(250); //enough time to send response to client
|
||||
setAllLeds();
|
||||
DEBUG_PRINTLN("MODULE RESET");
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
|
||||
//append new c string to temp buffer efficiently
|
||||
bool oappend(char* txt)
|
||||
{
|
||||
uint16_t len = strlen(txt);
|
||||
if (olen + len >= OMAX) return false; //buffer full
|
||||
strcpy(obuf + olen, txt);
|
||||
olen += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//append new number to temp buffer efficiently
|
||||
bool oappendi(int i)
|
||||
{
|
||||
char s[11];
|
||||
sprintf(s,"%ld", i);
|
||||
return oappend(s);
|
||||
}
|
||||
|
||||
|
||||
//boot starts here
|
||||
void setup() {
|
||||
wledInit();
|
||||
wledInit();
|
||||
}
|
||||
|
||||
|
||||
//main program loop
|
||||
void loop() {
|
||||
server.handleClient();
|
||||
handleNotifications();
|
||||
handleTransitions();
|
||||
userLoop();
|
||||
yield();
|
||||
handleButton();
|
||||
handleNetworkTime();
|
||||
if (!otaLock && aOtaEnabled) ArduinoOTA.handle();
|
||||
server.handleClient();
|
||||
handleSerial();
|
||||
handleNotifications();
|
||||
handleTransitions();
|
||||
userLoop();
|
||||
|
||||
yield();
|
||||
handleButton();
|
||||
handleIR();
|
||||
handleNetworkTime();
|
||||
if (!onlyAP)
|
||||
{
|
||||
handleAlexa();
|
||||
handleOverlays();
|
||||
if (!arlsTimeout) //block stuff if WARLS is enabled
|
||||
{
|
||||
if (dnsActive) dnsServer.processNextRequest();
|
||||
handleHue();
|
||||
handleNightlight();
|
||||
if (briT) strip.service(); //do not update strip if off, prevents flicker on ESP32
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
#ifdef DEBUG
|
||||
if (millis() - debugTime > 5000)
|
||||
{
|
||||
DEBUG_PRINTLN("---MODULE DEBUG INFO---");
|
||||
DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis());
|
||||
DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now());
|
||||
DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status());
|
||||
if (WiFi.status() != lastWifiState)
|
||||
{
|
||||
wifiStateChangedTime = millis();
|
||||
}
|
||||
lastWifiState = WiFi.status();
|
||||
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(wifiStateChangedTime);
|
||||
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
|
||||
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
|
||||
debugTime = millis();
|
||||
}
|
||||
handleMQTT();
|
||||
}
|
||||
|
||||
handleOverlays();
|
||||
|
||||
yield();
|
||||
|
||||
if (!realtimeActive) //block stuff if WARLS/Adalight is enabled
|
||||
{
|
||||
if (dnsActive) dnsServer.processNextRequest();
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
if (aOtaEnabled) ArduinoOTA.handle();
|
||||
#endif
|
||||
handleNightlight();
|
||||
if (!onlyAP) {
|
||||
handleHue();
|
||||
handleBlynk();
|
||||
}
|
||||
if (briT) lastOnTime = millis();
|
||||
if (millis() - lastOnTime < 600)
|
||||
{
|
||||
offMode = false;
|
||||
strip.service();
|
||||
} else if (!offMode)
|
||||
{
|
||||
/*#if LEDPIN == 2 //turn off onboard LED
|
||||
pinMode(2, OUTPUT);
|
||||
digitalWrite(2, HIGH);
|
||||
#endif*/
|
||||
offMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
//DEBUG serial logging
|
||||
#ifdef WLED_DEBUG
|
||||
if (millis() - debugTime > 5000)
|
||||
{
|
||||
DEBUG_PRINTLN("---MODULE DEBUG INFO---");
|
||||
DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis());
|
||||
DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now());
|
||||
DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status());
|
||||
if (WiFi.status() != lastWifiState)
|
||||
{
|
||||
wifiStateChangedTime = millis();
|
||||
}
|
||||
lastWifiState = WiFi.status();
|
||||
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
|
||||
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
|
||||
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
|
||||
debugTime = millis();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define EEPSIZE 3072
|
||||
|
||||
//eeprom Version code, enables default settings instead of 0 init on update
|
||||
#define EEPVER 6
|
||||
#define EEPVER 10
|
||||
//0 -> old version, default
|
||||
//1 -> 0.4p 1711272 and up
|
||||
//2 -> 0.4p 1711302 and up
|
||||
@@ -14,8 +14,15 @@
|
||||
//4 -> 0.5.0 and up
|
||||
//5 -> 0.5.1 and up
|
||||
//6 -> 0.6.0 and up
|
||||
//7 -> 0.7.1 and up
|
||||
//8 -> 0.8.0-a and up
|
||||
//9 -> 0.8.0
|
||||
//10-> 0.8.2
|
||||
|
||||
//todo add settings
|
||||
|
||||
/*
|
||||
* Erase all configuration data
|
||||
*/
|
||||
void clearEEPROM()
|
||||
{
|
||||
for (int i = 0; i < EEPSIZE; i++)
|
||||
@@ -25,141 +32,146 @@ void clearEEPROM()
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
|
||||
void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len)
|
||||
{
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
EEPROM.write(pos + i, str[i]);
|
||||
if (str[i] == 0) return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len)
|
||||
{
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
str[i] = EEPROM.read(pos + i);
|
||||
if (str[i] == 0) return;
|
||||
}
|
||||
str[len] = 0; //make sure every string is properly terminated. str must be at least len +1 big.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write configuration to flash
|
||||
*/
|
||||
void saveSettingsToEEPROM()
|
||||
{
|
||||
if (EEPROM.read(233) != 233) //set no first boot flag
|
||||
{
|
||||
clearEEPROM();
|
||||
EEPROM.write(233, 233);
|
||||
} else
|
||||
{
|
||||
showWelcomePage = false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
EEPROM.write(i, clientSSID.charAt(i));
|
||||
}
|
||||
for (int i = 32; i < 96; ++i)
|
||||
{
|
||||
EEPROM.write(i, clientPass.charAt(i-32));
|
||||
}
|
||||
for (int i = 96; i < 128; ++i)
|
||||
{
|
||||
EEPROM.write(i, cmDNS.charAt(i-96));
|
||||
}
|
||||
for (int i = 128; i < 160; ++i)
|
||||
{
|
||||
EEPROM.write(i, apSSID.charAt(i-128));
|
||||
}
|
||||
for (int i = 160; i < 224; ++i)
|
||||
{
|
||||
EEPROM.write(i, apPass.charAt(i-160));
|
||||
}
|
||||
EEPROM.write(224, nightlightDelayMins);
|
||||
writeStringToEEPROM( 0, clientSSID, 32);
|
||||
writeStringToEEPROM( 32, clientPass, 64);
|
||||
writeStringToEEPROM( 96, cmDNS, 32);
|
||||
writeStringToEEPROM(128, apSSID, 32);
|
||||
writeStringToEEPROM(160, apPass, 64);
|
||||
|
||||
EEPROM.write(224, nightlightDelayMinsDefault);
|
||||
EEPROM.write(225, nightlightFade);
|
||||
EEPROM.write(226, notifyDirectDefault);
|
||||
EEPROM.write(227, apChannel);
|
||||
EEPROM.write(228, apHide);
|
||||
EEPROM.write(229, ledCount);
|
||||
EEPROM.write(229, ledCount & 0xFF);
|
||||
EEPROM.write(230, notifyButton);
|
||||
EEPROM.write(231, notifyTwice);
|
||||
EEPROM.write(232, buttonEnabled);
|
||||
//233 reserved for first boot flag
|
||||
EEPROM.write(234, staticIP[0]);
|
||||
EEPROM.write(235, staticIP[1]);
|
||||
EEPROM.write(236, staticIP[2]);
|
||||
EEPROM.write(237, staticIP[3]);
|
||||
EEPROM.write(238, staticGateway[0]);
|
||||
EEPROM.write(239, staticGateway[1]);
|
||||
EEPROM.write(240, staticGateway[2]);
|
||||
EEPROM.write(241, staticGateway[3]);
|
||||
EEPROM.write(242, staticSubnet[0]);
|
||||
EEPROM.write(243, staticSubnet[1]);
|
||||
EEPROM.write(244, staticSubnet[2]);
|
||||
EEPROM.write(245, staticSubnet[3]);
|
||||
|
||||
for (int i = 0; i<4; i++) //ip addresses
|
||||
{
|
||||
EEPROM.write(234+i, staticIP[i]);
|
||||
EEPROM.write(238+i, staticGateway[i]);
|
||||
EEPROM.write(242+i, staticSubnet[i]);
|
||||
}
|
||||
|
||||
EEPROM.write(246, colS[0]);
|
||||
EEPROM.write(247, colS[1]);
|
||||
EEPROM.write(248, colS[2]);
|
||||
EEPROM.write(249, briS);
|
||||
|
||||
EEPROM.write(250, receiveNotificationBrightness);
|
||||
EEPROM.write(251, fadeTransition);
|
||||
EEPROM.write(252, reverseMode);
|
||||
EEPROM.write(253, (transitionDelay >> 0) & 0xFF);
|
||||
EEPROM.write(254, (transitionDelay >> 8) & 0xFF);
|
||||
EEPROM.write(253, transitionDelayDefault & 0xFF);
|
||||
EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF);
|
||||
EEPROM.write(255, briMultiplier);
|
||||
|
||||
//255,250,231,230,226 notifier bytes
|
||||
for (int i = 256; i < 288; ++i)
|
||||
{
|
||||
EEPROM.write(i, otaPass.charAt(i-256));
|
||||
}
|
||||
writeStringToEEPROM(256, otaPass, 32);
|
||||
|
||||
EEPROM.write(288, nightlightTargetBri);
|
||||
EEPROM.write(289, otaLock);
|
||||
EEPROM.write(290, (udpPort >> 0) & 0xFF);
|
||||
EEPROM.write(290, udpPort & 0xFF);
|
||||
EEPROM.write(291, (udpPort >> 8) & 0xFF);
|
||||
for (int i = 292; i < 324; ++i)
|
||||
{
|
||||
EEPROM.write(i, serverDescription.charAt(i-292));
|
||||
}
|
||||
writeStringToEEPROM(292, serverDescription, 32);
|
||||
|
||||
EEPROM.write(324, effectDefault);
|
||||
EEPROM.write(325, effectSpeedDefault);
|
||||
EEPROM.write(326, effectIntensityDefault);
|
||||
|
||||
EEPROM.write(327, ntpEnabled);
|
||||
EEPROM.write(328, currentTimezone);
|
||||
EEPROM.write(329, useAMPM);
|
||||
EEPROM.write(330, useGammaCorrectionBri);
|
||||
EEPROM.write(331, useGammaCorrectionRGB);
|
||||
EEPROM.write(332, overlayDefault);
|
||||
|
||||
EEPROM.write(333, alexaEnabled);
|
||||
for (int i = 334; i < 366; ++i)
|
||||
{
|
||||
EEPROM.write(i, alexaInvocationName.charAt(i-334));
|
||||
}
|
||||
EEPROM.write(366, alexaNotify);
|
||||
writeStringToEEPROM(334, alexaInvocationName, 32);
|
||||
EEPROM.write(366, notifyAlexa);
|
||||
|
||||
EEPROM.write(367, (arlsOffset>=0));
|
||||
EEPROM.write(368, abs(arlsOffset));
|
||||
EEPROM.write(369, turnOnAtBoot);
|
||||
EEPROM.write(370, useHSBDefault);
|
||||
EEPROM.write(371, whiteS);
|
||||
EEPROM.write(371, colS[3]); //white default
|
||||
EEPROM.write(372, useRGBW);
|
||||
EEPROM.write(373, sweepTransition);
|
||||
EEPROM.write(374, sweepDirection);
|
||||
EEPROM.write(373, effectPaletteDefault);
|
||||
EEPROM.write(374, strip.paletteFade);
|
||||
EEPROM.write(375, apWaitTimeSecs);
|
||||
EEPROM.write(376, recoveryAPDisabled);
|
||||
|
||||
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, whiteSecS);
|
||||
EEPROM.write(382, ccIndex1);
|
||||
EEPROM.write(383, ccIndex2);
|
||||
EEPROM.write(384, ccNumPrimary);
|
||||
EEPROM.write(385, ccNumSecondary);
|
||||
EEPROM.write(386, ccFromStart);
|
||||
EEPROM.write(387, ccFromEnd);
|
||||
EEPROM.write(388, ccStep);
|
||||
EEPROM.write(381, colSecS[3]);
|
||||
EEPROM.write(382, strip.paletteBlend);
|
||||
EEPROM.write(383, strip.colorOrder);
|
||||
|
||||
EEPROM.write(385, irEnabled);
|
||||
|
||||
EEPROM.write(387, strip.ablMilliampsMax & 0xFF);
|
||||
EEPROM.write(388, (strip.ablMilliampsMax >> 8) & 0xFF);
|
||||
EEPROM.write(389, bootPreset);
|
||||
EEPROM.write(390, aOtaEnabled);
|
||||
EEPROM.write(391, receiveNotificationColor);
|
||||
EEPROM.write(392, receiveNotificationEffects);
|
||||
EEPROM.write(393, wifiLock);
|
||||
EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF);
|
||||
|
||||
EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
|
||||
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
||||
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
||||
EEPROM.write(397, initLedsLast);
|
||||
//397 was initLedsLast
|
||||
EEPROM.write(398, (ledCount >> 8) & 0xFF);
|
||||
EEPROM.write(399, !enableSecTransition);
|
||||
|
||||
//favorite setting (preset) memory (25 slots/ each 20byte)
|
||||
//400 - 899 reserved
|
||||
|
||||
for (int k=0;k<6;k++){
|
||||
int in = 900+k*8;
|
||||
for (int i=in; i < in+8; ++i)
|
||||
{
|
||||
EEPROM.write(i, cssCol[k].charAt(i-in));
|
||||
}}
|
||||
writeStringToEEPROM(in, cssCol[k], 8);
|
||||
}
|
||||
|
||||
EEPROM.write(948,currentTheme);
|
||||
for (int i = 950; i < 982; ++i)
|
||||
{
|
||||
EEPROM.write(i, cssFont.charAt(i-950));
|
||||
}
|
||||
writeStringToEEPROM(950, cssFont, 32);
|
||||
|
||||
EEPROM.write(2048, huePollingEnabled);
|
||||
//EEPROM.write(2049, hueUpdatingEnabled);
|
||||
@@ -167,11 +179,8 @@ void saveSettingsToEEPROM()
|
||||
{
|
||||
EEPROM.write(i, hueIP[i-2050]);
|
||||
}
|
||||
for (int i = 2054; i < 2100; ++i)
|
||||
{
|
||||
EEPROM.write(i, hueApiKey.charAt(i-2054));
|
||||
}
|
||||
EEPROM.write(2100, (huePollIntervalMs >> 0) & 0xFF);
|
||||
writeStringToEEPROM(2054, hueApiKey, 46);
|
||||
EEPROM.write(2100, huePollIntervalMs & 0xFF);
|
||||
EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF);
|
||||
EEPROM.write(2102, notifyHue);
|
||||
EEPROM.write(2103, hueApplyOnOff);
|
||||
@@ -184,6 +193,7 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(2152, analogClock12pixel);
|
||||
EEPROM.write(2153, analogClock5MinuteMarks);
|
||||
EEPROM.write(2154, analogClockSecondsTrail);
|
||||
|
||||
EEPROM.write(2155, countdownMode);
|
||||
EEPROM.write(2156, countdownYear);
|
||||
EEPROM.write(2157, countdownMonth);
|
||||
@@ -193,10 +203,7 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(2161, countdownSec);
|
||||
setCountdown();
|
||||
|
||||
for (int i = 2165; i < 2171; ++i)
|
||||
{
|
||||
EEPROM.write(i, cronixieDisplay.charAt(i-2165));
|
||||
}
|
||||
writeStringToEEPROM(2165, cronixieDisplay, 6);
|
||||
EEPROM.write(2171, cronixieBacklight);
|
||||
setCronixie();
|
||||
|
||||
@@ -207,62 +214,89 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(2179, macroLongPress);
|
||||
EEPROM.write(2180, macroCountdown);
|
||||
EEPROM.write(2181, macroNl);
|
||||
|
||||
EEPROM.write(2190, e131Universe & 0xFF);
|
||||
EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
|
||||
EEPROM.write(2192, e131Multicast);
|
||||
EEPROM.write(2193, realtimeTimeoutMs & 0xFF);
|
||||
EEPROM.write(2194, (realtimeTimeoutMs >> 8) & 0xFF);
|
||||
EEPROM.write(2195, arlsForceMaxBri);
|
||||
EEPROM.write(2196, arlsDisableGammaCorrection);
|
||||
|
||||
EEPROM.write(2200, !receiveDirect);
|
||||
EEPROM.write(2201, enableRealtimeUI);
|
||||
EEPROM.write(2202, uiConfiguration);
|
||||
EEPROM.write(2203, autoRGBtoRGBW);
|
||||
EEPROM.write(2204, skipFirstLed);
|
||||
|
||||
if (saveCurrPresetCycConf)
|
||||
{
|
||||
EEPROM.write(2205, presetCyclingEnabled);
|
||||
EEPROM.write(2206, presetCycleTime & 0xFF);
|
||||
EEPROM.write(2207, (presetCycleTime >> 8) & 0xFF);
|
||||
EEPROM.write(2208, presetCycleMin);
|
||||
EEPROM.write(2209, presetCycleMax);
|
||||
EEPROM.write(2210, presetApplyBri);
|
||||
EEPROM.write(2211, presetApplyCol);
|
||||
EEPROM.write(2212, presetApplyFx);
|
||||
saveCurrPresetCycConf = false;
|
||||
}
|
||||
|
||||
writeStringToEEPROM(2220, blynkApiKey, 35);
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
EEPROM.write(2260 + i, timerHours[i] );
|
||||
EEPROM.write(2270 + i, timerMinutes[i]);
|
||||
EEPROM.write(2280 + i, timerWeekday[i]);
|
||||
EEPROM.write(2290 + i, timerMacro[i] );
|
||||
}
|
||||
|
||||
writeStringToEEPROM(2300, mqttServer, 32);
|
||||
writeStringToEEPROM(2333, mqttDeviceTopic, 32);
|
||||
writeStringToEEPROM(2366, mqttGroupTopic, 32);
|
||||
|
||||
EEPROM.commit();
|
||||
commit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read all configuration from flash
|
||||
*/
|
||||
void loadSettingsFromEEPROM(bool first)
|
||||
{
|
||||
if (EEPROM.read(233) != 233) //first boot/reset to default
|
||||
{
|
||||
showWelcomePage=true;
|
||||
DEBUG_PRINT("Settings invalid, restoring defaults...");
|
||||
saveSettingsToEEPROM();
|
||||
DEBUG_PRINTLN("done");
|
||||
return;
|
||||
}
|
||||
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
|
||||
|
||||
clientSSID = "";
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
clientSSID += char(EEPROM.read(i));
|
||||
}
|
||||
clientPass = "";
|
||||
for (int i = 32; i < 96; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
clientPass += char(EEPROM.read(i));
|
||||
}
|
||||
cmDNS = "";
|
||||
for (int i = 96; i < 128; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cmDNS += char(EEPROM.read(i));
|
||||
}
|
||||
apSSID = "";
|
||||
for (int i = 128; i < 160; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
apSSID += char(EEPROM.read(i));
|
||||
}
|
||||
apPass = "";
|
||||
for (int i = 160; i < 224; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
apPass += char(EEPROM.read(i));
|
||||
}
|
||||
nightlightDelayMins = EEPROM.read(224);
|
||||
|
||||
readStringFromEEPROM( 0, clientSSID, 32);
|
||||
readStringFromEEPROM( 32, clientPass, 64);
|
||||
readStringFromEEPROM( 96, cmDNS, 32);
|
||||
readStringFromEEPROM(128, apSSID, 32);
|
||||
readStringFromEEPROM(160, apPass, 64);
|
||||
|
||||
nightlightDelayMinsDefault = EEPROM.read(224);
|
||||
nightlightDelayMins = nightlightDelayMinsDefault;
|
||||
nightlightFade = EEPROM.read(225);
|
||||
notifyDirectDefault = EEPROM.read(226);
|
||||
notifyDirect = notifyDirectDefault;
|
||||
|
||||
apChannel = EEPROM.read(227);
|
||||
if (apChannel > 13 || apChannel < 1) apChannel = 1;
|
||||
apHide = EEPROM.read(228);
|
||||
if (apHide > 1) apHide = 1;
|
||||
ledCount = EEPROM.read(229); if (ledCount > LEDCOUNT) ledCount = LEDCOUNT;
|
||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 30;
|
||||
|
||||
notifyButton = EEPROM.read(230);
|
||||
notifyTwice = EEPROM.read(231);
|
||||
buttonEnabled = EEPROM.read(232);
|
||||
|
||||
staticIP[0] = EEPROM.read(234);
|
||||
staticIP[1] = EEPROM.read(235);
|
||||
staticIP[2] = EEPROM.read(236);
|
||||
@@ -275,6 +309,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
staticSubnet[1] = EEPROM.read(243);
|
||||
staticSubnet[2] = EEPROM.read(244);
|
||||
staticSubnet[3] = EEPROM.read(245);
|
||||
|
||||
colS[0] = EEPROM.read(246); col[0] = colS[0];
|
||||
colS[1] = EEPROM.read(247); col[1] = colS[1];
|
||||
colS[2] = EEPROM.read(248); col[2] = colS[2];
|
||||
@@ -286,23 +321,18 @@ void loadSettingsFromEEPROM(bool first)
|
||||
receiveNotificationBrightness = EEPROM.read(250);
|
||||
fadeTransition = EEPROM.read(251);
|
||||
reverseMode = EEPROM.read(252);
|
||||
transitionDelay = ((EEPROM.read(253) << 0) & 0xFF) + ((EEPROM.read(254) << 8) & 0xFF00);
|
||||
transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00);
|
||||
transitionDelay = transitionDelayDefault;
|
||||
briMultiplier = EEPROM.read(255);
|
||||
otaPass = "";
|
||||
for (int i = 256; i < 288; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
otaPass += char(EEPROM.read(i));
|
||||
}
|
||||
|
||||
readStringFromEEPROM(256, otaPass, 32);
|
||||
|
||||
nightlightTargetBri = EEPROM.read(288);
|
||||
otaLock = EEPROM.read(289);
|
||||
udpPort = ((EEPROM.read(290) << 0) & 0xFF) + ((EEPROM.read(291) << 8) & 0xFF00);
|
||||
serverDescription = "";
|
||||
for (int i = 292; i < 324; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
serverDescription += char(EEPROM.read(i));
|
||||
}
|
||||
udpPort = EEPROM.read(290) + ((EEPROM.read(291) << 8) & 0xFF00);
|
||||
|
||||
readStringFromEEPROM(292, serverDescription, 32);
|
||||
|
||||
effectDefault = EEPROM.read(324); effectCurrent = effectDefault;
|
||||
effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault;
|
||||
ntpEnabled = EEPROM.read(327);
|
||||
@@ -311,52 +341,40 @@ void loadSettingsFromEEPROM(bool first)
|
||||
useGammaCorrectionBri = EEPROM.read(330);
|
||||
useGammaCorrectionRGB = EEPROM.read(331);
|
||||
overlayDefault = EEPROM.read(332);
|
||||
if (lastEEPROMversion < 8 && overlayDefault > 0) overlayDefault--; //overlay mode 1 (solid) was removed
|
||||
|
||||
alexaEnabled = EEPROM.read(333);
|
||||
alexaInvocationName = "";
|
||||
for (int i = 334; i < 366; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
alexaInvocationName += char(EEPROM.read(i));
|
||||
}
|
||||
alexaNotify = EEPROM.read(366);
|
||||
|
||||
readStringFromEEPROM(334, alexaInvocationName, 32);
|
||||
|
||||
notifyAlexa = EEPROM.read(366);
|
||||
arlsOffset = EEPROM.read(368);
|
||||
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
|
||||
turnOnAtBoot = EEPROM.read(369);
|
||||
useHSBDefault = EEPROM.read(370);
|
||||
whiteS = EEPROM.read(371); white = whiteS;
|
||||
colS[3] = EEPROM.read(371); col[3] = colS[3];
|
||||
useRGBW = EEPROM.read(372);
|
||||
sweepTransition = EEPROM.read(373);
|
||||
sweepDirection = EEPROM.read(374);
|
||||
effectPaletteDefault = EEPROM.read(373); effectPalette = effectPaletteDefault;
|
||||
//374 - strip.paletteFade
|
||||
|
||||
if (lastEEPROMversion > 0) {
|
||||
apWaitTimeSecs = EEPROM.read(375);
|
||||
recoveryAPDisabled = EEPROM.read(376);
|
||||
}
|
||||
//377 = lastEEPROMversion
|
||||
if (lastEEPROMversion > 1) {
|
||||
colSecS[0] = EEPROM.read(378); colSec[0] = colSecS[0];
|
||||
colSecS[1] = EEPROM.read(379); colSec[1] = colSecS[1];
|
||||
colSecS[2] = EEPROM.read(380); colSec[2] = colSecS[2];
|
||||
whiteSecS = EEPROM.read(381); whiteSec = whiteSecS;
|
||||
ccIndex1 = EEPROM.read(382);
|
||||
ccIndex2 = EEPROM.read(383);
|
||||
ccNumPrimary = EEPROM.read(384);
|
||||
ccNumSecondary = EEPROM.read(385);
|
||||
ccFromStart = EEPROM.read(386);
|
||||
ccFromEnd = EEPROM.read(387);
|
||||
ccStep = EEPROM.read(388);
|
||||
strip.setCustomChase(ccIndex1, ccIndex2, ccStart, ccNumPrimary, ccNumSecondary, ccStep, ccFromStart, ccFromEnd);
|
||||
for (byte i=0; i<4; i++)
|
||||
{
|
||||
colSecS[i] = EEPROM.read(378+i); colSec[i] = colSecS[i];
|
||||
}
|
||||
}
|
||||
if (lastEEPROMversion > 3) {
|
||||
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
|
||||
aOtaEnabled = EEPROM.read(390);
|
||||
receiveNotificationColor = EEPROM.read(391);
|
||||
receiveNotificationEffects = EEPROM.read(392);
|
||||
cssFont = "";
|
||||
for (int i = 950; i < 982; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cssFont += char(EEPROM.read(i));
|
||||
}
|
||||
|
||||
readStringFromEEPROM(950, cssFont, 32);
|
||||
} else //keep receiving notification behavior from pre0.5.0 after update
|
||||
{
|
||||
receiveNotificationColor = receiveNotificationBrightness;
|
||||
@@ -370,13 +388,10 @@ void loadSettingsFromEEPROM(bool first)
|
||||
{
|
||||
hueIP[i-2050] = EEPROM.read(i);
|
||||
}
|
||||
hueApiKey = "";
|
||||
for (int i = 2054; i < 2100; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
hueApiKey += char(EEPROM.read(i));
|
||||
}
|
||||
huePollIntervalMs = ((EEPROM.read(2100) << 0) & 0xFF) + ((EEPROM.read(2101) << 8) & 0xFF00);
|
||||
|
||||
readStringFromEEPROM(2054, hueApiKey, 46);
|
||||
|
||||
huePollIntervalMs = EEPROM.read(2100) + ((EEPROM.read(2101) << 8) & 0xFF00);
|
||||
notifyHue = EEPROM.read(2102);
|
||||
hueApplyOnOff = EEPROM.read(2103);
|
||||
hueApplyBri = EEPROM.read(2104);
|
||||
@@ -398,12 +413,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
countdownSec = EEPROM.read(2161);
|
||||
setCountdown();
|
||||
|
||||
cronixieDisplay = "";
|
||||
for (int i = 2165; i < 2171; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cronixieDisplay += char(EEPROM.read(i));
|
||||
}
|
||||
readStringFromEEPROM(2165, cronixieDisplay, 6);
|
||||
cronixieBacklight = EEPROM.read(2171);
|
||||
|
||||
macroBoot = EEPROM.read(2175);
|
||||
@@ -414,76 +424,133 @@ void loadSettingsFromEEPROM(bool first)
|
||||
macroCountdown = EEPROM.read(2180);
|
||||
macroNl = EEPROM.read(2181);
|
||||
}
|
||||
|
||||
if (lastEEPROMversion > 6)
|
||||
{
|
||||
e131Universe = EEPROM.read(2190) + ((EEPROM.read(2191) << 8) & 0xFF00);
|
||||
e131Multicast = EEPROM.read(2192);
|
||||
realtimeTimeoutMs = EEPROM.read(2193) + ((EEPROM.read(2194) << 8) & 0xFF00);
|
||||
arlsForceMaxBri = EEPROM.read(2195);
|
||||
arlsDisableGammaCorrection = EEPROM.read(2196);
|
||||
}
|
||||
|
||||
if (lastEEPROMversion > 7)
|
||||
{
|
||||
strip.paletteFade = EEPROM.read(374);
|
||||
strip.paletteBlend = EEPROM.read(382);
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
timerHours[i] = EEPROM.read(2260 + i);
|
||||
timerMinutes[i] = EEPROM.read(2270 + i);
|
||||
timerWeekday[i] = EEPROM.read(2280 + i);
|
||||
timerMacro[i] = EEPROM.read(2290 + i);
|
||||
if (timerWeekday[i] == 0) timerWeekday[i] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastEEPROMversion > 8)
|
||||
{
|
||||
readStringFromEEPROM(2300, mqttServer, 32);
|
||||
readStringFromEEPROM(2333, mqttDeviceTopic, 32);
|
||||
readStringFromEEPROM(2366, mqttGroupTopic, 32);
|
||||
}
|
||||
|
||||
if (lastEEPROMversion > 9)
|
||||
{
|
||||
strip.colorOrder = EEPROM.read(383);
|
||||
irEnabled = EEPROM.read(385);
|
||||
strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00);
|
||||
} else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.2
|
||||
{
|
||||
strip.ablMilliampsMax = 65000;
|
||||
} else {
|
||||
strip.ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
|
||||
}
|
||||
|
||||
receiveDirect = !EEPROM.read(2200);
|
||||
enableRealtimeUI = EEPROM.read(2201);
|
||||
uiConfiguration = EEPROM.read(2202);
|
||||
|
||||
#ifdef WLED_DISABLE_MOBILE_UI
|
||||
uiConfiguration = 1;
|
||||
//force default UI since mobile is unavailable
|
||||
#endif
|
||||
|
||||
autoRGBtoRGBW = EEPROM.read(2203);
|
||||
skipFirstLed = EEPROM.read(2204);
|
||||
|
||||
if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
|
||||
{
|
||||
presetCyclingEnabled = EEPROM.read(2205);
|
||||
presetCycleTime = EEPROM.read(2206) + ((EEPROM.read(2207) << 8) & 0xFF00);
|
||||
presetCycleMin = EEPROM.read(2208);
|
||||
presetCycleMax = EEPROM.read(2209);
|
||||
presetApplyBri = EEPROM.read(2210);
|
||||
presetApplyCol = EEPROM.read(2211);
|
||||
presetApplyFx = EEPROM.read(2212);
|
||||
}
|
||||
|
||||
bootPreset = EEPROM.read(389);
|
||||
wifiLock = EEPROM.read(393);
|
||||
utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00);
|
||||
utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
|
||||
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
|
||||
initLedsLast = EEPROM.read(397);
|
||||
enableSecTransition = !EEPROM.read(399);
|
||||
|
||||
//favorite setting memory (25 slots/ each 20byte)
|
||||
//favorite setting (preset) memory (25 slots/ each 20byte)
|
||||
//400 - 899 reserved
|
||||
|
||||
currentTheme = EEPROM.read(948);
|
||||
for (int k=0;k<6;k++){
|
||||
int in=900+k*8;
|
||||
for (int i=in; i < in+8; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cssCol[k] += char(EEPROM.read(i));
|
||||
}}
|
||||
readStringFromEEPROM(in, cssCol[k], 8);
|
||||
}
|
||||
|
||||
//custom macro memory (16 slots/ each 64byte)
|
||||
//1024-2047 reserved
|
||||
|
||||
readStringFromEEPROM(2220, blynkApiKey, 35);
|
||||
|
||||
//user MOD memory
|
||||
//2944 - 3071 reserved
|
||||
|
||||
useHSB = useHSBDefault;
|
||||
|
||||
strip.setMode(effectCurrent);
|
||||
strip.setSpeed(effectSpeed);
|
||||
strip.setIntensity(effectIntensity);
|
||||
overlayCurrent = overlayDefault;
|
||||
}
|
||||
|
||||
|
||||
//PRESET PROTOCOL 20 bytes
|
||||
//0: preset purpose byte 0:invalid 1:valid preset 1.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-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
|
||||
|
||||
void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX)
|
||||
bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool loadFX = true)
|
||||
{
|
||||
if (index == 255 || index == 0) loadSettingsFromEEPROM(false);//load boot defaults
|
||||
if (index > 25 || index < 1) return;
|
||||
if (index == 255 || index == 0)
|
||||
{
|
||||
loadSettingsFromEEPROM(false);//load boot defaults
|
||||
return true;
|
||||
}
|
||||
if (index > 25 || index < 1) return false;
|
||||
uint16_t i = 380 + index*20;
|
||||
if (EEPROM.read(i) == 0) return;
|
||||
if (EEPROM.read(i) == 0) return false;
|
||||
if (loadBri) bri = EEPROM.read(i+1);
|
||||
if (loadCol)
|
||||
{
|
||||
col[0] = EEPROM.read(i+2);
|
||||
col[1] = EEPROM.read(i+3);
|
||||
col[2] = EEPROM.read(i+4);
|
||||
white = EEPROM.read(i+5);
|
||||
colSec[0] = EEPROM.read(i+6);
|
||||
colSec[1] = EEPROM.read(i+7);
|
||||
colSec[2] = EEPROM.read(i+8);
|
||||
whiteSec = EEPROM.read(i+9);
|
||||
for (byte j=0; j<4; j++)
|
||||
{
|
||||
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);
|
||||
ccNumPrimary = EEPROM.read(i+12);
|
||||
ccNumSecondary = EEPROM.read(i+13);
|
||||
ccFromEnd = EEPROM.read(i+14);
|
||||
ccFromStart = (EEPROM.read(i+14)<2);
|
||||
ccStep = EEPROM.read(i+15);
|
||||
strip.setCustomChase(ccIndex1, ccIndex2, ccStart, ccNumPrimary, ccNumSecondary, ccStep, ccFromStart, ccFromEnd);
|
||||
strip.setMode(effectCurrent);
|
||||
strip.setSpeed(effectSpeed);
|
||||
strip.setIntensity(effectIntensity);
|
||||
effectPalette = EEPROM.read(i+17);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void savePreset(byte index)
|
||||
@@ -493,27 +560,20 @@ void savePreset(byte index)
|
||||
uint16_t i = 380 + index*20;//min400
|
||||
EEPROM.write(i, 1);
|
||||
EEPROM.write(i+1, bri);
|
||||
EEPROM.write(i+2, col[0]);
|
||||
EEPROM.write(i+3, col[1]);
|
||||
EEPROM.write(i+4, col[2]);
|
||||
EEPROM.write(i+5, white);
|
||||
EEPROM.write(i+6, colSec[0]);
|
||||
EEPROM.write(i+7, colSec[1]);
|
||||
EEPROM.write(i+8, colSec[2]);
|
||||
EEPROM.write(i+9, whiteSec);
|
||||
for (uint16_t j=0; j<4; 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+12, ccNumPrimary);
|
||||
EEPROM.write(i+13, ccNumSecondary);
|
||||
byte m = 1;
|
||||
if (!ccFromStart) m = 2;
|
||||
if (!ccFromEnd) m = 0;
|
||||
EEPROM.write(i+14, m);
|
||||
EEPROM.write(i+15, ccStep);
|
||||
|
||||
EEPROM.write(i+16, effectIntensity);
|
||||
EEPROM.commit();
|
||||
EEPROM.write(i+17, effectPalette);
|
||||
commit();
|
||||
}
|
||||
|
||||
|
||||
String loadMacro(byte index)
|
||||
{
|
||||
index-=1;
|
||||
@@ -524,10 +584,10 @@ String loadMacro(byte index)
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
m += char(EEPROM.read(i));
|
||||
}
|
||||
if (m.charAt(0) < 65 || m.charAt(0) > 90) return ""; //do simple check if macro is valid (capital first letter)
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
void applyMacro(byte index)
|
||||
{
|
||||
index-=1;
|
||||
@@ -535,7 +595,7 @@ void applyMacro(byte index)
|
||||
String mc="win&";
|
||||
mc += loadMacro(index+1);
|
||||
mc += "&IN"; //internal, no XML response
|
||||
if (!macroNotify) mc += "&NN";
|
||||
if (!notifyMacro) mc += "&NN";
|
||||
String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop
|
||||
/*
|
||||
* NOTE: loop is still possible if you call a different macro from a macro, which then calls the first macro again.
|
||||
@@ -546,6 +606,7 @@ void applyMacro(byte index)
|
||||
handleSet(mc);
|
||||
}
|
||||
|
||||
|
||||
void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings
|
||||
{
|
||||
index-=1;
|
||||
@@ -555,6 +616,23 @@ void saveMacro(byte index, String mc, bool sing=true) //only commit on single sa
|
||||
{
|
||||
EEPROM.write(i, mc.charAt(i-s));
|
||||
}
|
||||
if (sing) EEPROM.commit();
|
||||
if (sing) commit();
|
||||
}
|
||||
|
||||
|
||||
void commit()
|
||||
{
|
||||
DEBUG_PRINT("s");
|
||||
//this is to support IR on ESP32, needs work
|
||||
/*#ifdef ARDUINO_ARCH_ESP32
|
||||
portMUX_TYPE mMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
portENTER_CRITICAL(&mMux);
|
||||
#endif*/
|
||||
|
||||
EEPROM.commit();
|
||||
|
||||
/*#ifdef ARDUINO_ARCH_ESP32
|
||||
portEXIT_CRITICAL(&mMux);
|
||||
#endif*/
|
||||
DEBUG_PRINT(".");
|
||||
}
|
||||
|
||||
@@ -2,255 +2,388 @@
|
||||
* Sending XML status files to client
|
||||
*/
|
||||
|
||||
void XML_response()
|
||||
//build XML response to HTTP /win API request
|
||||
void XML_response(bool isHTTP, bool includeTheme)
|
||||
{
|
||||
String resp;
|
||||
resp = resp + "<?xml version = \"1.0\" ?>";
|
||||
resp = resp + "<vs>";
|
||||
resp = resp + "<ac>";
|
||||
if (nightlightActive && nightlightFade)
|
||||
{
|
||||
resp = resp + briT;
|
||||
} else
|
||||
{
|
||||
resp = resp + bri;
|
||||
}
|
||||
resp = resp + "</ac>";
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
resp = resp + "<cl>";
|
||||
resp = resp + col[i];
|
||||
resp = resp + "</cl>";
|
||||
}
|
||||
resp = resp + "<ns>";
|
||||
resp = resp + notifyDirect;
|
||||
resp = resp + "</ns><nr>";
|
||||
resp = resp + receiveNotifications;
|
||||
resp = resp + "</nr><nl>";
|
||||
resp = resp + nightlightActive;
|
||||
resp = resp + "</nl><nf>";
|
||||
resp = resp + nightlightFade;
|
||||
resp = resp + "</nf><nd>";
|
||||
resp = resp + nightlightDelayMins;
|
||||
resp = resp + "</nd><nt>";
|
||||
resp = resp + nightlightTargetBri;
|
||||
resp = resp + "</nt><fx>";
|
||||
resp = resp + effectCurrent;
|
||||
resp = resp + "</fx><sx>";
|
||||
resp = resp + effectSpeed;
|
||||
resp = resp + "</sx><ix>";
|
||||
resp = resp + effectIntensity;
|
||||
resp = resp + "</ix><wv>";
|
||||
if (useRGBW) {
|
||||
resp = resp + white;
|
||||
} else {
|
||||
resp = resp + "-1";
|
||||
}
|
||||
resp = resp + "</wv><md>";
|
||||
resp = resp + useHSB;
|
||||
resp = resp + "</md><ds>";
|
||||
resp = resp + serverDescription;
|
||||
resp = resp + "</ds>";
|
||||
resp = resp + "</vs>";
|
||||
server.send(200, "text/xml", resp);
|
||||
olen = 0;
|
||||
oappend("<?xml version = \"1.0\" ?><vs><ac>");
|
||||
oappendi((nightlightActive && nightlightFade) ? briT : bri);
|
||||
oappend("</ac>");
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
oappend("<cl>");
|
||||
oappendi(col[i]);
|
||||
oappend("</cl>");
|
||||
}
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
oappend("<cs>");
|
||||
oappendi(colSec[i]);
|
||||
oappend("</cs>");
|
||||
}
|
||||
|
||||
oappend("<ns>");
|
||||
oappendi(notifyDirect);
|
||||
oappend("</ns><nr>");
|
||||
oappendi(receiveNotifications);
|
||||
oappend("</nr><nl>");
|
||||
oappendi(nightlightActive);
|
||||
oappend("</nl><nf>");
|
||||
oappendi(nightlightFade);
|
||||
oappend("</nf><nd>");
|
||||
oappendi(nightlightDelayMins);
|
||||
oappend("</nd><nt>");
|
||||
oappendi(nightlightTargetBri);
|
||||
oappend("</nt><fx>");
|
||||
oappendi(effectCurrent);
|
||||
oappend("</fx><sx>");
|
||||
oappendi(effectSpeed);
|
||||
oappend("</sx><ix>");
|
||||
oappendi(effectIntensity);
|
||||
oappend("</ix><fp>");
|
||||
oappendi(effectPalette);
|
||||
oappend("</fp><wv>");
|
||||
if (useRGBW && !autoRGBtoRGBW) {
|
||||
oappendi(col[3]);
|
||||
} else {
|
||||
oappend("-1");
|
||||
}
|
||||
oappend("</wv><ws>");
|
||||
oappendi(colSec[3]);
|
||||
oappend("</ws><md>");
|
||||
oappendi(useHSB);
|
||||
oappend("</md><cy>");
|
||||
oappendi(presetCyclingEnabled);
|
||||
oappend("</cy><ds>");
|
||||
oappend(serverDescription);
|
||||
oappend("</ds>");
|
||||
if (includeTheme)
|
||||
{
|
||||
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 (isHTTP) server.send(200, "text/xml", obuf);
|
||||
}
|
||||
|
||||
String getSettings(byte subPage)
|
||||
//append a numeric setting to string buffer
|
||||
void sappend(char stype, char* key, int val)
|
||||
{
|
||||
char ds[] = "d.Sf.";
|
||||
|
||||
switch(stype)
|
||||
{
|
||||
case 'c': //checkbox
|
||||
oappend(ds);
|
||||
oappend(key);
|
||||
oappend(".checked=");
|
||||
oappendi(val);
|
||||
oappend(";");
|
||||
break;
|
||||
case 'v': //numeric
|
||||
oappend(ds);
|
||||
oappend(key);
|
||||
oappend(".value=");
|
||||
oappendi(val);
|
||||
oappend(";");
|
||||
break;
|
||||
case 'i': //selectedIndex
|
||||
oappend(ds);
|
||||
oappend(key);
|
||||
oappend(".selectedIndex=");
|
||||
oappendi(val);
|
||||
oappend(";");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//append a string setting to buffer
|
||||
void sappends(char stype, char* key, char* val)
|
||||
{
|
||||
switch(stype)
|
||||
{
|
||||
case 's': //string (we can interpret val as char*)
|
||||
oappend("d.Sf.");
|
||||
oappend(key);
|
||||
oappend(".value=\"");
|
||||
oappend(val);
|
||||
oappend("\";");
|
||||
break;
|
||||
case 'm': //message
|
||||
oappend("d.getElementsByClassName");
|
||||
oappend(key);
|
||||
oappend(".innerHTML=\"");
|
||||
oappend(val);
|
||||
oappend("\";");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//get values for settings form in javascript
|
||||
void getSettingsJS(byte subPage)
|
||||
{
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
|
||||
DEBUG_PRINT("settings resp");
|
||||
DEBUG_PRINTLN(subPage);
|
||||
|
||||
String resp = "";
|
||||
if (subPage <1 || subPage >6) return resp;
|
||||
|
||||
String ds = "d.Sf.";
|
||||
String dg = "d.getElementsByClassName";
|
||||
String v = ".value=";
|
||||
String c = ".checked=";
|
||||
String ih = ".innerHTML=";
|
||||
String si = ".selectedIndex=";
|
||||
olen = 0; obuf[0] = 0; //clear buffer
|
||||
if (subPage <1 || subPage >6) return;
|
||||
|
||||
if (subPage == 1) {
|
||||
resp += ds + "CS" + v + "\"" + clientSSID + "\";";
|
||||
resp += ds + "CP" + v + "\"";
|
||||
for (int i = 0; i < clientPass.length(); i++)
|
||||
sappends('s',"CS",clientSSID);
|
||||
|
||||
byte l = strlen(clientPass);
|
||||
char fpass[l+1]; //fill password field with ***
|
||||
fpass[l] = 0;
|
||||
memset(fpass,'*',l);
|
||||
sappends('s',"CP",fpass);
|
||||
|
||||
char k[3]; k[2] = 0; //IP addresses
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
resp += "*";
|
||||
k[1] = 48+i; //ascii 0,1,2,3
|
||||
k[0] = 'I'; sappend('v',k,staticIP[i]);
|
||||
k[0] = 'G'; sappend('v',k,staticGateway[i]);
|
||||
k[0] = 'S'; sappend('v',k,staticSubnet[i]);
|
||||
}
|
||||
resp += "\";";
|
||||
resp += ds + "I0" + v + staticIP[0] +";";
|
||||
resp += ds + "I1" + v + staticIP[1] +";";
|
||||
resp += ds + "I2" + v + staticIP[2] +";";
|
||||
resp += ds + "I3" + v + staticIP[3] +";";
|
||||
resp += ds + "G0" + v + staticGateway[0] +";";
|
||||
resp += ds + "G1" + v + staticGateway[1] +";";
|
||||
resp += ds + "G2" + v + staticGateway[2] +";";
|
||||
resp += ds + "G3" + v + staticGateway[3] +";";
|
||||
resp += ds + "S0" + v + staticSubnet[0] +";";
|
||||
resp += ds + "S1" + v + staticSubnet[1] +";";
|
||||
resp += ds + "S2" + v + staticSubnet[2] +";";
|
||||
resp += ds + "S3" + v + staticSubnet[3] +";";
|
||||
resp += ds + "CM" + v + "\"" + cmDNS + "\";";
|
||||
resp += ds + "AT" + v + apWaitTimeSecs +";";
|
||||
resp += ds + "AS" + v + "\"" + apSSID + "\";";
|
||||
resp += ds + "AH" + c + apHide + ";";
|
||||
resp += ds + "AP" + v + "\"";
|
||||
for (int i = 0; i < apPass.length(); i++)
|
||||
|
||||
sappends('s',"CM",cmDNS);
|
||||
sappend('v',"AT",apWaitTimeSecs);
|
||||
sappends('s',"AS",apSSID);
|
||||
sappend('c',"AH",apHide);
|
||||
|
||||
l = strlen(apPass);
|
||||
char fapass[l+1]; //fill password field with ***
|
||||
fapass[l] = 0;
|
||||
memset(fapass,'*',l);
|
||||
sappends('s',"AP",fapass);
|
||||
|
||||
sappend('v',"AC",apChannel);
|
||||
|
||||
if (WiFi.localIP()[0] != 0) //is connected
|
||||
{
|
||||
resp += "*";
|
||||
}
|
||||
resp += "\";";
|
||||
resp += ds + "AC" + v + apChannel +";";
|
||||
resp += dg + "(\"sip\")[0]" + ih + "\"";
|
||||
if (!WiFi.localIP()[0] == 0)
|
||||
{
|
||||
resp += WiFi.localIP()[0];
|
||||
resp += + ".";
|
||||
resp += WiFi.localIP()[1];
|
||||
resp += ".";
|
||||
resp += WiFi.localIP()[2];
|
||||
resp += ".";
|
||||
resp += WiFi.localIP()[3];
|
||||
char s[16];
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
sappends('m',"(\"sip\")[0]",s);
|
||||
} else
|
||||
{
|
||||
resp += "Not connected";
|
||||
sappends('m',"(\"sip\")[0]","Not connected");
|
||||
}
|
||||
resp += "\";";
|
||||
resp += dg + "(\"sip\")[1]" + ih + "\"";
|
||||
if (!WiFi.softAPIP()[0] == 0)
|
||||
|
||||
if (WiFi.softAPIP()[0] != 0) //is active
|
||||
{
|
||||
resp += WiFi.softAPIP()[0];
|
||||
resp += + ".";
|
||||
resp += WiFi.softAPIP()[1];
|
||||
resp += ".";
|
||||
resp += WiFi.softAPIP()[2];
|
||||
resp += ".";
|
||||
resp += WiFi.softAPIP()[3];
|
||||
char s[16];
|
||||
IPAddress apIP = WiFi.softAPIP();
|
||||
sprintf(s, "%d.%d.%d.%d", apIP[0], apIP[1], apIP[2], apIP[3]);
|
||||
sappends('m',"(\"sip\")[1]",s);
|
||||
} else
|
||||
{
|
||||
resp += "Not active";
|
||||
sappends('m',"(\"sip\")[1]","Not active");
|
||||
}
|
||||
resp += "\";";
|
||||
}
|
||||
|
||||
if (subPage == 2) {
|
||||
resp += ds + "LC" + v + ledCount +";";
|
||||
resp += ds + "CR" + v + colS[0] +";";
|
||||
resp += ds + "CG" + v + colS[1] +";";
|
||||
resp += ds + "CB" + v + colS[2] +";";
|
||||
resp += ds + "CA" + v + briS +";";
|
||||
if (useRGBW) {
|
||||
resp += ds + "CW" + v + whiteS +";";
|
||||
} else {
|
||||
resp += ds + "CW" + v + "-1;";
|
||||
sappend('v',"LC",ledCount);
|
||||
sappend('v',"MA",strip.ablMilliampsMax);
|
||||
if (strip.currentMilliamps)
|
||||
{
|
||||
sappends('m',"(\"pow\")[0]","");
|
||||
olen -= 2; //delete ";
|
||||
oappendi(strip.currentMilliamps);
|
||||
oappend("mA\";");
|
||||
}
|
||||
resp += ds + "SR" + v + colSecS[0] +";";
|
||||
resp += ds + "SG" + v + colSecS[1] +";";
|
||||
resp += ds + "SB" + v + colSecS[2] +";";
|
||||
resp += ds + "SW" + v + whiteSecS +";";
|
||||
resp += ds + "BO" + c + turnOnAtBoot +";";
|
||||
resp += ds + "BP" + v + bootPreset +";";
|
||||
resp += ds + "FX" + v + effectDefault +";";
|
||||
resp += ds + "SX" + v + effectSpeedDefault +";";
|
||||
resp += ds + "IX" + v + effectIntensityDefault +";";
|
||||
resp += ds + "GB" + c + useGammaCorrectionBri +";";
|
||||
resp += ds + "GC" + c + useGammaCorrectionRGB +";";
|
||||
resp += ds + "TF" + c + fadeTransition +";";
|
||||
resp += ds + "TS" + c + sweepTransition +";";
|
||||
resp += ds + "TI" + c + !sweepDirection +";";
|
||||
resp += ds + "TD" + v + transitionDelay +";";
|
||||
resp += ds + "BF" + v + briMultiplier +";";
|
||||
resp += ds + "TB" + v + nightlightTargetBri +";";
|
||||
resp += ds + "TL" + v + nightlightDelayMins +";";
|
||||
resp += ds + "TW" + c + nightlightFade +";";
|
||||
resp += ds + "RV" + c + reverseMode +";";
|
||||
resp += ds + "EI" + c + initLedsLast +";";
|
||||
resp += ds + "WO" + v + arlsOffset +";";
|
||||
sappend('v',"CR",colS[0]);
|
||||
sappend('v',"CG",colS[1]);
|
||||
sappend('v',"CB",colS[2]);
|
||||
sappend('v',"CA",briS);
|
||||
sappend('c',"EW",useRGBW);
|
||||
sappend('i',"CO",strip.colorOrder);
|
||||
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('v',"BP",bootPreset);
|
||||
sappend('v',"FX",effectDefault);
|
||||
sappend('v',"SX",effectSpeedDefault);
|
||||
sappend('v',"IX",effectIntensityDefault);
|
||||
sappend('v',"FP",effectPaletteDefault);
|
||||
sappend('c',"GB",useGammaCorrectionBri);
|
||||
sappend('c',"GC",useGammaCorrectionRGB);
|
||||
sappend('c',"TF",fadeTransition);
|
||||
sappend('v',"TD",transitionDelay);
|
||||
sappend('c',"PF",strip.paletteFade);
|
||||
sappend('c',"T2",enableSecTransition);
|
||||
sappend('v',"BF",briMultiplier);
|
||||
sappend('v',"TB",nightlightTargetBri);
|
||||
sappend('v',"TL",nightlightDelayMinsDefault);
|
||||
sappend('c',"TW",nightlightFade);
|
||||
sappend('i',"PB",strip.paletteBlend);
|
||||
sappend('c',"RV",reverseMode);
|
||||
sappend('c',"SL",skipFirstLed);
|
||||
}
|
||||
|
||||
if (subPage == 3)
|
||||
{
|
||||
resp += ds + "DS" + v + "\"" + serverDescription + "\";";
|
||||
resp += ds + "MD" + c + useHSBDefault + ";";
|
||||
resp += ds + "TH" + si + String(currentTheme) + ";";
|
||||
for(int i=0;i<6;i++)
|
||||
resp += ds + "C" + i + v + "\"" + cssCol[i] + "\";";
|
||||
resp += ds + "CF" + v + "\"" + cssFont + "\";";
|
||||
sappend('i',"UI",uiConfiguration);
|
||||
sappends('s',"DS",serverDescription);
|
||||
sappend('c',"MD",useHSBDefault);
|
||||
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)
|
||||
{
|
||||
resp += ds + "BT" + c + buttonEnabled +";";
|
||||
resp += ds + "UP" + v + udpPort +";";
|
||||
resp += ds + "RB" + c + receiveNotificationBrightness +";";
|
||||
resp += ds + "RC" + c + receiveNotificationColor +";";
|
||||
resp += ds + "RX" + c + receiveNotificationEffects +";";
|
||||
resp += ds + "SD" + c + notifyDirectDefault +";";
|
||||
resp += ds + "SB" + c + notifyButton +";";
|
||||
resp += ds + "SH" + c + notifyHue +";";
|
||||
resp += ds + "S2" + c + notifyTwice +";";
|
||||
resp += ds + "AL" + c + alexaEnabled +";";
|
||||
resp += ds + "AI" + v + "\"" + alexaInvocationName + "\";";
|
||||
resp += ds + "SA" + c + alexaNotify +";";
|
||||
resp += ds + "H0" + v + hueIP[0] +";";
|
||||
resp += ds + "H1" + v + hueIP[1] +";";
|
||||
resp += ds + "H2" + v + hueIP[2] +";";
|
||||
resp += ds + "H3" + v + hueIP[3] +";";
|
||||
resp += ds + "HL" + v + huePollLightId +";";
|
||||
resp += ds + "HI" + v + huePollIntervalMs +";";
|
||||
resp += ds + "HP" + c + huePollingEnabled +";";
|
||||
resp += ds + "HO" + c + hueApplyOnOff +";";
|
||||
resp += ds + "HB" + c + hueApplyBri +";";
|
||||
resp += ds + "HC" + c + hueApplyColor +";";
|
||||
resp += dg + "(\"hms\")[0]" + ih + "\"" + hueError + "\";";
|
||||
sappend('c',"BT",buttonEnabled);
|
||||
sappend('c',"IR",irEnabled);
|
||||
sappend('v',"UP",udpPort);
|
||||
sappend('c',"RB",receiveNotificationBrightness);
|
||||
sappend('c',"RC",receiveNotificationColor);
|
||||
sappend('c',"RX",receiveNotificationEffects);
|
||||
sappend('c',"SD",notifyDirectDefault);
|
||||
sappend('c',"SB",notifyButton);
|
||||
sappend('c',"SH",notifyHue);
|
||||
sappend('c',"S2",notifyTwice);
|
||||
sappend('c',"RD",receiveDirect);
|
||||
sappend('c',"EM",e131Multicast);
|
||||
sappend('v',"EU",e131Universe);
|
||||
sappend('v',"ET",realtimeTimeoutMs);
|
||||
sappend('c',"FB",arlsForceMaxBri);
|
||||
sappend('c',"RG",arlsDisableGammaCorrection);
|
||||
sappend('v',"WO",arlsOffset);
|
||||
sappend('c',"RU",enableRealtimeUI);
|
||||
sappend('c',"AL",alexaEnabled);
|
||||
sappends('s',"AI",alexaInvocationName);
|
||||
sappend('c',"SA",notifyAlexa);
|
||||
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
|
||||
sappends('s',"MS",mqttServer);
|
||||
sappends('s',"MD",mqttDeviceTopic);
|
||||
sappends('s',"MG",mqttGroupTopic);
|
||||
sappend('v',"H0",hueIP[0]);
|
||||
sappend('v',"H1",hueIP[1]);
|
||||
sappend('v',"H2",hueIP[2]);
|
||||
sappend('v',"H3",hueIP[3]);
|
||||
sappend('v',"HL",huePollLightId);
|
||||
sappend('v',"HI",huePollIntervalMs);
|
||||
sappend('c',"HP",huePollingEnabled);
|
||||
sappend('c',"HO",hueApplyOnOff);
|
||||
sappend('c',"HB",hueApplyBri);
|
||||
sappend('c',"HC",hueApplyColor);
|
||||
sappends('m',"(\"hms\")[0]",hueError);
|
||||
}
|
||||
|
||||
if (subPage == 5)
|
||||
{
|
||||
resp += ds + "NT" + c + ntpEnabled +";";
|
||||
resp += ds + "CF" + c + !useAMPM +";";
|
||||
resp += ds + "TZ" + si + String(currentTimezone) + ";";
|
||||
resp += ds + "UO" + v + utcOffsetSecs +";";
|
||||
resp += dg + "(\"times\")[0]" + ih + "\"" + getTimeString() + "\";";
|
||||
resp += ds + "OL" + si + String(overlayCurrent) + ";";
|
||||
resp += ds + "O1" + v + overlayMin +";";
|
||||
resp += ds + "O2" + v + overlayMax +";";
|
||||
resp += ds + "OM" + v + analogClock12pixel +";";
|
||||
resp += ds + "OS" + c + analogClockSecondsTrail +";";
|
||||
resp += ds + "O5" + c + analogClock5MinuteMarks +";";
|
||||
resp += ds + "CX" + v + "\"" + cronixieDisplay + "\";";
|
||||
resp += ds + "CB" + c + cronixieBacklight +";";
|
||||
resp += ds + "CE" + c + countdownMode +";";
|
||||
resp += ds + "CY" + v + countdownYear +";";
|
||||
resp += ds + "CI" + v + countdownMonth +";";
|
||||
resp += ds + "CD" + v + countdownDay +";";
|
||||
resp += ds + "CH" + v + countdownHour +";";
|
||||
resp += ds + "CM" + v + countdownMin +";";
|
||||
resp += ds + "CS" + v + countdownSec +";";
|
||||
sappend('c',"NT",ntpEnabled);
|
||||
sappend('c',"CF",!useAMPM);
|
||||
sappend('i',"TZ",currentTimezone);
|
||||
sappend('v',"UO",utcOffsetSecs);
|
||||
sappends('m',"(\"times\")[0]",(char*)getTimeString().c_str());
|
||||
sappend('i',"OL",overlayCurrent);
|
||||
sappend('v',"O1",overlayMin);
|
||||
sappend('v',"O2",overlayMax);
|
||||
sappend('v',"OM",analogClock12pixel);
|
||||
sappend('c',"OS",analogClockSecondsTrail);
|
||||
sappend('c',"O5",analogClock5MinuteMarks);
|
||||
sappends('s',"CX",cronixieDisplay);
|
||||
sappend('c',"CB",cronixieBacklight);
|
||||
sappend('c',"CE",countdownMode);
|
||||
sappend('v',"CY",countdownYear);
|
||||
sappend('v',"CI",countdownMonth);
|
||||
sappend('v',"CD",countdownDay);
|
||||
sappend('v',"CH",countdownHour);
|
||||
sappend('v',"CM",countdownMin);
|
||||
sappend('v',"CS",countdownSec);
|
||||
|
||||
char k[4]; k[0]= 'M';
|
||||
for (int i=1;i<17;i++)
|
||||
{
|
||||
resp += ds + "M" + String(i) + v + "\"" + loadMacro(i) + "\";";
|
||||
sprintf(k+1,"%i",i);
|
||||
sappends('s',k,(char*)loadMacro(i).c_str());
|
||||
}
|
||||
|
||||
sappend('v',"MB",macroBoot);
|
||||
sappend('v',"A0",macroAlexaOn);
|
||||
sappend('v',"A1",macroAlexaOff);
|
||||
sappend('v',"MP",macroButton);
|
||||
sappend('v',"ML",macroLongPress);
|
||||
sappend('v',"MC",macroCountdown);
|
||||
sappend('v',"MN",macroNl);
|
||||
|
||||
k[2] = 0; //Time macros
|
||||
for (int i = 0; i<8; i++)
|
||||
{
|
||||
k[1] = 48+i; //ascii 0,1,2,3
|
||||
k[0] = 'H'; sappend('v',k,timerHours[i]);
|
||||
k[0] = 'N'; sappend('v',k,timerMinutes[i]);
|
||||
k[0] = 'T'; sappend('v',k,timerMacro[i]);
|
||||
k[0] = 'W'; sappend('v',k,timerWeekday[i]);
|
||||
}
|
||||
resp += ds + "MB" + v + macroBoot +";";
|
||||
resp += ds + "A0" + v + macroAlexaOn +";";
|
||||
resp += ds + "A1" + v + macroAlexaOff +";";
|
||||
resp += ds + "MP" + v + macroButton +";";
|
||||
resp += ds + "ML" + v + macroLongPress +";";
|
||||
resp += ds + "MC" + v + macroCountdown +";";
|
||||
resp += ds + "MN" + v + macroNl +";";
|
||||
}
|
||||
|
||||
if (subPage == 6)
|
||||
{
|
||||
resp += ds + "NO" + c + otaLock +";";
|
||||
resp += ds + "OW" + c + wifiLock +";";
|
||||
resp += ds + "AO" + c + aOtaEnabled +";";
|
||||
resp += ds + "NA" + c + recoveryAPDisabled +";";
|
||||
resp += dg + "(\"msg\")[0]" + ih + "\"WLED "+ versionString +" (build " + VERSION + ") OK\";";
|
||||
sappend('c',"NO",otaLock);
|
||||
sappend('c',"OW",wifiLock);
|
||||
sappend('c',"AO",aOtaEnabled);
|
||||
sappend('c',"NA",recoveryAPDisabled);
|
||||
sappends('m',"(\"msg\")[0]","WLED ");
|
||||
olen -= 2; //delete ";
|
||||
oappend(versionString);
|
||||
oappend(" (build ");
|
||||
oappendi(VERSION);
|
||||
oappend(") OK\";");
|
||||
}
|
||||
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
|
||||
}
|
||||
resp += "}</script>";
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,42 @@
|
||||
/*
|
||||
* Utility for SPIFFS filesystem
|
||||
* Utility for SPIFFS filesystem & Serial console
|
||||
*/
|
||||
void handleSerial()
|
||||
{
|
||||
if (Serial.available() > 0) //support for Adalight protocol to high-speed control LEDs over serial
|
||||
{
|
||||
if (!Serial.find("Ada")) return;
|
||||
|
||||
if (!realtimeActive && bri == 0) strip.setBrightness(briLast);
|
||||
arlsLock(realtimeTimeoutMs);
|
||||
|
||||
delay(1);
|
||||
byte hi = Serial.read();
|
||||
byte ledc = Serial.read();
|
||||
byte chk = Serial.read();
|
||||
if(chk != (hi ^ ledc ^ 0x55)) return;
|
||||
if (ledCount < ledc) ledc = ledCount;
|
||||
|
||||
byte sc[3]; int t =-1; int to = 0;
|
||||
for (int i=0; i < ledc; i++)
|
||||
{
|
||||
for (byte j=0; j<3; j++)
|
||||
{
|
||||
while (Serial.peek()<0) //no data yet available
|
||||
{
|
||||
delay(1);
|
||||
to++;
|
||||
if (to>5) {strip.show(); return;} //unexpected end of transmission
|
||||
}
|
||||
to = 0;
|
||||
sc[j] = Serial.read();
|
||||
}
|
||||
setRealtimePixel(i,sc[0],sc[1],sc[2],0);
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USEFS
|
||||
|
||||
String formatBytes(size_t bytes){
|
||||
|
||||
@@ -3,24 +3,31 @@
|
||||
*/
|
||||
|
||||
void wledInit()
|
||||
{
|
||||
{
|
||||
EEPROM.begin(EEPSIZE);
|
||||
if (!EEPROM.read(397)) strip.init(); //quick init
|
||||
|
||||
ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
|
||||
if (ledCount > 1200 || ledCount == 0) ledCount = 30;
|
||||
//RMT eats up too much RAM
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (ledCount > 600) ledCount = 600;
|
||||
#endif
|
||||
Serial.begin(115200);
|
||||
Serial.setTimeout(50);
|
||||
|
||||
strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly
|
||||
|
||||
#ifdef USEFS
|
||||
SPIFFS.begin();
|
||||
SPIFFS.begin();
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTLN("Load EEPROM");
|
||||
loadSettingsFromEEPROM(true);
|
||||
if (!initLedsLast) initStrip();
|
||||
DEBUG_PRINT("C-SSID: ");
|
||||
beginStrip();
|
||||
DEBUG_PRINT("CSSID: ");
|
||||
DEBUG_PRINT(clientSSID);
|
||||
buildCssColorString();
|
||||
userBeginPreConnection();
|
||||
|
||||
if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true;
|
||||
WiFi.persistent(false);
|
||||
initCon();
|
||||
|
||||
DEBUG_PRINTLN("");
|
||||
@@ -33,294 +40,123 @@ void wledInit()
|
||||
hueIP[1] = WiFi.localIP()[1];
|
||||
hueIP[2] = WiFi.localIP()[2];
|
||||
}
|
||||
|
||||
// Set up mDNS responder:
|
||||
if (cmDNS != NULL && !onlyAP && !MDNS.begin(cmDNS.c_str())) {
|
||||
DEBUG_PRINTLN("Error setting up MDNS responder!");
|
||||
down();
|
||||
}
|
||||
DEBUG_PRINTLN("mDNS responder started");
|
||||
|
||||
if (udpPort > 0 && udpPort != ntpLocalPort && WiFi.status() == WL_CONNECTED)
|
||||
if (udpPort > 0 && udpPort != ntpLocalPort)
|
||||
{
|
||||
udpConnected = notifierUdp.begin(udpPort);
|
||||
if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||
}
|
||||
if (ntpEnabled && WiFi.status() == WL_CONNECTED)
|
||||
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||
|
||||
//start captive portal
|
||||
if (onlyAP || apSSID.length() > 0)
|
||||
//start captive portal if AP active
|
||||
if (onlyAP || strlen(apSSID) > 0)
|
||||
{
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::ServerFailure);
|
||||
dnsServer.start(53, "wled.me", WiFi.softAPIP());
|
||||
dnsActive = true;
|
||||
}
|
||||
|
||||
//SERVER INIT
|
||||
//seasonal greetings
|
||||
server.on("/easter", HTTP_GET, [](){
|
||||
if (currentTheme == 12)
|
||||
{
|
||||
effectCurrent = 6;
|
||||
strip.setMode(effectCurrent);
|
||||
effectSpeed = 200;
|
||||
strip.setSpeed(effectSpeed);
|
||||
uint8_t chance = random(255);
|
||||
if (chance > 250) {serveMessage(200, "🐣🐣🐣🐣🐣", "You are super special! Here are 5 chicks for you!", 254);}
|
||||
else if (chance > 230) {serveMessage(200, "🐣🐣🐣🐣", "You are genuinely special! Here are 4 chicks for you!", 254);}
|
||||
else if (chance > 200) {serveMessage(200, "🐣🐣🐣", "You are very special! Here are 3 chicks for you!", 254);}
|
||||
else if (chance > 140) {serveMessage(200, "🐣🐣", "You are quite special! Here are 2 chicks for you!", 254);}
|
||||
else if (chance > 1) {serveMessage(200, "🐣", "Happy Easter to you! Here's your personal chick!", 254);}
|
||||
else {serveMessage(200, "🐰My basket is empty!🐰", "So sorry you always have bad luck... Why not try again?", 254);}
|
||||
} else
|
||||
{
|
||||
serveMessage(200, "😈April Fools!😈", "You could try to <a href=\"/settings/ui\">decorate</a> for Easter first!", 254);
|
||||
}
|
||||
});
|
||||
//settings page
|
||||
server.on("/settings", HTTP_GET, [](){
|
||||
serveSettings(0);
|
||||
});
|
||||
server.on("/settings/wifi", HTTP_GET, [](){
|
||||
if (!(wifiLock && otaLock))
|
||||
{
|
||||
serveSettings(1);
|
||||
}else{
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
}
|
||||
});
|
||||
server.on("/settings/leds", HTTP_GET, [](){
|
||||
serveSettings(2);
|
||||
});
|
||||
server.on("/settings/ui", HTTP_GET, [](){
|
||||
serveSettings(3);
|
||||
});
|
||||
server.on("/settings/sync", HTTP_GET, [](){
|
||||
serveSettings(4);
|
||||
});
|
||||
server.on("/settings/time", HTTP_GET, [](){
|
||||
serveSettings(5);
|
||||
});
|
||||
server.on("/settings/sec", HTTP_GET, [](){
|
||||
serveSettings(6);
|
||||
});
|
||||
|
||||
server.on("/favicon.ico", HTTP_GET, [](){
|
||||
if(!handleFileRead("/favicon.ico"))
|
||||
{
|
||||
server.send_P(200, "image/x-icon", favicon, 156);
|
||||
}
|
||||
});
|
||||
|
||||
server.on("/", HTTP_GET, [](){
|
||||
serveIndexOrWelcome();
|
||||
});
|
||||
|
||||
server.on("/generate_204", HTTP_GET, [](){
|
||||
serveIndexOrWelcome();
|
||||
});
|
||||
|
||||
server.on("/fwlink", HTTP_GET, [](){
|
||||
serveIndexOrWelcome();
|
||||
});
|
||||
|
||||
server.on("/sliders", HTTP_GET, serveIndex);
|
||||
|
||||
server.on("/welcome", HTTP_GET, [](){
|
||||
serveSettings(255);
|
||||
});
|
||||
|
||||
server.on("/reset", HTTP_GET, [](){
|
||||
serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",79);
|
||||
reset();
|
||||
});
|
||||
|
||||
server.on("/settings/wifi", HTTP_POST, [](){
|
||||
if (!(wifiLock && otaLock)) handleSettingsSet(1);
|
||||
serveMessage(200,"WiFi settings saved.","Rebooting now... (takes ~20 seconds, wait for auto-redirect)",139);
|
||||
reset();
|
||||
});
|
||||
|
||||
server.on("/settings/leds", HTTP_POST, [](){
|
||||
handleSettingsSet(2);
|
||||
serveMessage(200,"LED settings saved.","Redirecting...",1);
|
||||
});
|
||||
|
||||
server.on("/settings/ui", HTTP_POST, [](){
|
||||
handleSettingsSet(3);
|
||||
serveMessage(200,"UI settings saved.","Reloading to apply theme...",122);
|
||||
});
|
||||
|
||||
server.on("/settings/sync", HTTP_POST, [](){
|
||||
handleSettingsSet(4);
|
||||
if (hueAttempt)
|
||||
{
|
||||
serveMessage(200,"Hue setup result",hueError,253);
|
||||
} else {
|
||||
serveMessage(200,"Sync settings saved.","Redirecting...",1);
|
||||
}
|
||||
hueAttempt = false;
|
||||
});
|
||||
|
||||
server.on("/settings/time", HTTP_POST, [](){
|
||||
handleSettingsSet(5);
|
||||
serveMessage(200,"Time settings saved.","Redirecting...",1);
|
||||
});
|
||||
|
||||
server.on("/settings/sec", HTTP_POST, [](){
|
||||
handleSettingsSet(6);
|
||||
serveMessage(200,"Security settings saved.","Rebooting now... (takes ~20 seconds, wait for auto-redirect)",139);
|
||||
reset();
|
||||
});
|
||||
|
||||
server.on("/version", HTTP_GET, [](){
|
||||
server.send(200, "text/plain", (String)VERSION);
|
||||
});
|
||||
|
||||
server.on("/uptime", HTTP_GET, [](){
|
||||
server.send(200, "text/plain", (String)millis());
|
||||
});
|
||||
|
||||
server.on("/freeheap", HTTP_GET, [](){
|
||||
server.send(200, "text/plain", (String)ESP.getFreeHeap());
|
||||
});
|
||||
|
||||
server.on("/power", HTTP_GET, [](){
|
||||
String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness());
|
||||
val += "mA currently";
|
||||
serveMessage(200,val,"This is just an estimate (does not take into account several factors like effects and wire resistance). It is NOT an accurate measurement!",254);
|
||||
});
|
||||
|
||||
server.on("/teapot", HTTP_GET, [](){
|
||||
serveMessage(418, "418. I'm a teapot.","(Tangible Embedded Advanced Project Of Twinkling)",254);
|
||||
});
|
||||
|
||||
server.on("/build", HTTP_GET, [](){
|
||||
String info = "hard-coded build info:\r\n\n";
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
info += "platform: esp32\r\n";
|
||||
#else
|
||||
info += "platform: esp8266\r\n";
|
||||
#endif
|
||||
info += "version: " + versionString + "\r\n";
|
||||
info += "build: " + (String)VERSION + "\r\n";
|
||||
info += "eepver: " + String(EEPVER) + "\r\n";
|
||||
#ifdef RGBW
|
||||
info += "rgbw: true\r\n";
|
||||
#else
|
||||
info += "rgbw: false\r\n";
|
||||
#endif
|
||||
info += "max-leds: " + (String)LEDCOUNT + "\r\n";
|
||||
#ifdef USEFS
|
||||
info += "spiffs: true\r\n";
|
||||
#else
|
||||
info += "spiffs: false\r\n";
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
info += "debug: true\r\n";
|
||||
#else
|
||||
info += "debug: false\r\n";
|
||||
#endif
|
||||
info += "button-pin: gpio" + String(buttonPin) + "\r\n";
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
info += "strip-pin: gpio" + String(PIN) + "\r\n";
|
||||
#else
|
||||
info += "strip-pin: gpio2\r\n";
|
||||
#endif
|
||||
server.send(200, "text/plain", info);
|
||||
});
|
||||
//if OTA is allowed
|
||||
if (!otaLock){
|
||||
server.on("/edit", HTTP_GET, [](){
|
||||
if(!handleFileRead("/edit.htm")) server.send(200, "text/html", PAGE_edit);
|
||||
});
|
||||
#ifdef USEFS
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
#endif
|
||||
server.on("/down", HTTP_GET, down);
|
||||
server.on("/cleareeprom", HTTP_GET, clearEEPROM);
|
||||
//init ota page
|
||||
httpUpdater.setup(&server);
|
||||
} else
|
||||
prepareIds(); //UUID from MAC (for Alexa and MQTT)
|
||||
if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default
|
||||
{
|
||||
server.on("/edit", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
server.on("/down", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
server.on("/cleareeprom", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
server.on("/update", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
server.on("/list", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
strcpy(cmDNS, "wled-");
|
||||
strcat(cmDNS, escapedMac.c_str());
|
||||
}
|
||||
//called when the url is not defined here, ajax-in; get-settings
|
||||
server.onNotFound([](){
|
||||
DEBUG_PRINTLN("Not-Found HTTP call:");
|
||||
DEBUG_PRINTLN("URI: " + server.uri());
|
||||
DEBUG_PRINTLN("Body: " + server.arg(0));
|
||||
if(!handleSet(server.uri())){
|
||||
if(!handleAlexaApiCall(server.uri(),server.arg(0)))
|
||||
server.send(404, "text/plain", "Not Found");
|
||||
}
|
||||
});
|
||||
if (mqttDeviceTopic[0] == 0)
|
||||
{
|
||||
strcpy(mqttDeviceTopic, "wled/");
|
||||
strcat(mqttDeviceTopic, escapedMac.c_str());
|
||||
}
|
||||
|
||||
//smartInit, we only init some resources when connected
|
||||
if (!onlyAP && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
mqttTCPClient = new WiFiClient();
|
||||
mqtt = new PubSubClient(*mqttTCPClient);
|
||||
mqttInit = initMQTT();
|
||||
}
|
||||
|
||||
strip.service();
|
||||
|
||||
//HTTP server page init
|
||||
initServer();
|
||||
|
||||
strip.service();
|
||||
//init Alexa hue emulation
|
||||
if (alexaEnabled) alexaInit();
|
||||
if (alexaEnabled && !onlyAP) alexaInit();
|
||||
|
||||
server.begin();
|
||||
DEBUG_PRINTLN("HTTP server started");
|
||||
// Add service to MDNS
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
|
||||
//init ArduinoOTA
|
||||
if (aOtaEnabled)
|
||||
{
|
||||
ArduinoOTA.onStart([]() {
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
wifi_set_sleep_type(NONE_SLEEP_T);
|
||||
#endif
|
||||
DEBUG_PRINTLN("Start ArduinoOTA");
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
if (!onlyAP) {
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
if (aOtaEnabled)
|
||||
{
|
||||
ArduinoOTA.onStart([]() {
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
wifi_set_sleep_type(NONE_SLEEP_T);
|
||||
#endif
|
||||
DEBUG_PRINTLN("Start ArduinoOTA");
|
||||
});
|
||||
if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS);
|
||||
ArduinoOTA.begin();
|
||||
}
|
||||
#endif
|
||||
|
||||
strip.service();
|
||||
// Set up mDNS responder:
|
||||
if (strlen(cmDNS) > 0 && !onlyAP)
|
||||
{
|
||||
MDNS.begin(cmDNS);
|
||||
DEBUG_PRINTLN("mDNS responder started");
|
||||
// Add service to MDNS
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("wled", "tcp", 80);
|
||||
}
|
||||
strip.service();
|
||||
|
||||
initBlynk(blynkApiKey);
|
||||
initE131();
|
||||
|
||||
hueClient = new HTTPClient();
|
||||
} else {
|
||||
e131Enabled = false;
|
||||
}
|
||||
|
||||
if (initLedsLast) initStrip();
|
||||
userBegin();
|
||||
|
||||
if (macroBoot>0) applyMacro(macroBoot);
|
||||
Serial.println("Ada");
|
||||
}
|
||||
|
||||
void initStrip()
|
||||
|
||||
void beginStrip()
|
||||
{
|
||||
// Initialize NeoPixel Strip and button
|
||||
if (initLedsLast) strip.init();
|
||||
strip.setLedCount(ledCount);
|
||||
strip.setReverseMode(reverseMode);
|
||||
strip.setColor(0);
|
||||
strip.setBrightness(255);
|
||||
strip.start();
|
||||
|
||||
pinMode(buttonPin, INPUT_PULLUP);
|
||||
pinMode(BTNPIN, INPUT_PULLUP);
|
||||
|
||||
if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
|
||||
colorUpdated(0);
|
||||
if(digitalRead(buttonPin) == LOW) buttonEnabled = false; //disable button if it is "pressed" unintentionally
|
||||
|
||||
//disable button if it is "pressed" unintentionally
|
||||
if(digitalRead(BTNPIN) == LOW) buttonEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
void initAP(){
|
||||
String save = apSSID;
|
||||
if (apSSID.length() <1) apSSID = "WLED-AP";
|
||||
WiFi.softAP(apSSID.c_str(), apPass.c_str(), apChannel, apHide);
|
||||
apSSID = save;
|
||||
bool set = apSSID[0];
|
||||
if (!set) strcpy(apSSID,"WLED-AP");
|
||||
WiFi.softAP(apSSID, apPass, apChannel, apHide);
|
||||
if (!set) apSSID[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
void initCon()
|
||||
{
|
||||
WiFi.disconnect(); //close old connections
|
||||
@@ -333,31 +169,35 @@ void initCon()
|
||||
WiFi.config(0U, 0U, 0U);
|
||||
}
|
||||
|
||||
if (apSSID.length()>0)
|
||||
if (strlen(apSSID)>0)
|
||||
{
|
||||
DEBUG_PRINT("USING AP");
|
||||
DEBUG_PRINTLN(apSSID.length());
|
||||
DEBUG_PRINT(" USING AP");
|
||||
DEBUG_PRINTLN(strlen(apSSID));
|
||||
initAP();
|
||||
} else
|
||||
{
|
||||
DEBUG_PRINTLN("NO AP");
|
||||
DEBUG_PRINTLN(" NO AP");
|
||||
WiFi.softAPdisconnect(true);
|
||||
}
|
||||
int fail_count = 0;
|
||||
if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2;
|
||||
WiFi.begin(clientSSID.c_str(), clientPass.c_str());
|
||||
if (strlen(clientSSID) <1 || strcmp(clientSSID,"Your_Network") == 0)
|
||||
fail_count = apWaitTimeSecs*2; //instantly go to ap mode
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
WiFi.hostname(serverDescription);
|
||||
#endif
|
||||
WiFi.begin(clientSSID, clientPass);
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WiFi.setHostname(serverDescription);
|
||||
#endif
|
||||
unsigned long lastTry = 0;
|
||||
bool con = false;
|
||||
while(!con)
|
||||
{
|
||||
yield();
|
||||
if (!initLedsLast)
|
||||
{
|
||||
handleTransitions();
|
||||
handleButton();
|
||||
handleOverlays();
|
||||
if (briT) strip.service();
|
||||
}
|
||||
handleTransitions();
|
||||
handleButton();
|
||||
handleOverlays();
|
||||
if (briT) strip.service();
|
||||
if (millis()-lastTry > 499) {
|
||||
con = (WiFi.status() == WL_CONNECTED);
|
||||
lastTry = millis();
|
||||
@@ -375,158 +215,72 @@ void initCon()
|
||||
}
|
||||
}
|
||||
|
||||
void buildCssColorString()
|
||||
{
|
||||
String cs[]={"","","","","",""};
|
||||
switch (currentTheme)
|
||||
{
|
||||
default: cs[0]="D9B310"; cs[1]="0B3C5D"; cs[2]="1D2731"; cs[3]="328CC1"; cs[4]="000"; cs[5]="328CC1"; break; //night
|
||||
case 1: cs[0]="eee"; cs[1]="ddd"; cs[2]="b9b9b9"; cs[3]="049"; cs[4]="777"; cs[5]="049"; break; //modern
|
||||
case 2: cs[0]="abc"; cs[1]="fff"; cs[2]="ddd"; cs[3]="000"; cs[4]="0004"; cs[5]="000"; break; //bright
|
||||
case 3: cs[0]="c09f80"; cs[1]="d7cec7"; cs[2]="76323f"; cs[3]="888"; cs[4]="3334"; cs[5]="888"; break; //wine
|
||||
case 4: cs[0]="3cc47c"; cs[1]="828081"; cs[2]="d9a803"; cs[3]="1e392a"; cs[4]="000a"; cs[5]="1e392a"; break; //electric
|
||||
case 5: cs[0]="57bc90"; cs[1]="a5a5af"; cs[2]="015249"; cs[3]="88c9d4"; cs[4]="0004"; cs[5]="88c9d4"; break; //mint
|
||||
case 6: cs[0]="f7c331"; cs[1]="dcc7aa"; cs[2]="6b7a8f"; cs[3]="f7882f"; cs[4]="0007"; cs[5]="f7882f"; break; //amber
|
||||
case 7: cs[0]="fc3"; cs[1]="124"; cs[2]="334"; cs[3]="f1d"; cs[4]="f00"; cs[5]="f1d"; break;//club
|
||||
case 8: cs[0]="0ac"; cs[1]="124"; cs[2]="224"; cs[3]="003eff"; cs[4]="003eff"; cs[5]="003eff"; break;//air
|
||||
case 9: cs[0]="f70"; cs[1]="421"; cs[2]="221"; cs[3]="a50"; cs[4]="f70"; cs[5]="f70"; break;//nixie
|
||||
case 10: cs[0]="2d2"; cs[1]="010"; cs[2]="121"; cs[3]="060"; cs[4]="040"; cs[5]="3f3"; break; //terminal
|
||||
case 11: cs[0]="867ADE"; cs[1]="4033A3"; cs[2]="483AAA"; cs[3]="483AAA"; cs[4]=""; cs[5]="867ADE"; break; //c64
|
||||
case 12: cs[0]="fbe8a6"; cs[1]="d2fdff"; cs[2]="b4dfe5"; cs[3]="f4976c"; cs[4]=""; cs[5]="303c6c"; break; //c64
|
||||
case 14: cs[0]="fc7"; cs[1]="49274a"; cs[2]="94618e"; cs[3]="f4decb"; cs[4]="0008"; cs[5]="f4decb"; break; //end
|
||||
case 15: for (int i=0;i<6;i++)cs[i]=cssCol[i];//custom
|
||||
}
|
||||
cssColorString="<style>:root{--aCol:#";
|
||||
cssColorString+=cs[0];
|
||||
cssColorString+=";--bCol:#";
|
||||
cssColorString+=cs[1];
|
||||
cssColorString+=";--cCol:#";
|
||||
cssColorString+=cs[2];
|
||||
cssColorString+=";--dCol:#";
|
||||
cssColorString+=cs[3];
|
||||
cssColorString+=";--sCol:#";
|
||||
cssColorString+=cs[4];
|
||||
cssColorString+=";--tCol:#";
|
||||
cssColorString+=cs[5];
|
||||
cssColorString+=";--cFn:";
|
||||
cssColorString+=cssFont;
|
||||
cssColorString+=";}";
|
||||
}
|
||||
|
||||
void serveIndexOrWelcome()
|
||||
//fill string buffer with build info
|
||||
void getBuildInfo()
|
||||
{
|
||||
if (!showWelcomePage){
|
||||
if(!handleFileRead("/index.htm")) {
|
||||
serveIndex();
|
||||
}
|
||||
}else{
|
||||
if(!handleFileRead("/welcome.htm")) {
|
||||
serveSettings(255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void serveIndex()
|
||||
{
|
||||
if (!arlsTimeout) //do not serve while receiving realtime
|
||||
{
|
||||
server.setContentLength(strlen_P(PAGE_index0) + cssColorString.length() + strlen_P(PAGE_index1) + strlen_P(PAGE_index2) + strlen_P(PAGE_index3));
|
||||
server.send(200, "text/html", "");
|
||||
server.sendContent_P(PAGE_index0);
|
||||
server.sendContent(cssColorString);
|
||||
server.sendContent_P(PAGE_index1);
|
||||
server.sendContent_P(PAGE_index2);
|
||||
server.sendContent_P(PAGE_index3);
|
||||
} else {
|
||||
server.send(200, "text/plain", "The WLED UI is not available while receiving real-time data.");
|
||||
}
|
||||
}
|
||||
|
||||
void serveMessage(int code, String headl, String subl="", int optionType)
|
||||
{
|
||||
String messageBody = "<h2>";
|
||||
messageBody += headl;
|
||||
messageBody += "</h2>";
|
||||
messageBody += subl;
|
||||
switch(optionType)
|
||||
{
|
||||
case 255: break; //simple message
|
||||
case 254: messageBody += "<br><br><button type=\"button\" onclick=\"B()\">Back</button>"; break; //back button
|
||||
case 253: messageBody += "<br><br><form action=/settings><button type=submit>Back</button></form>"; //button to settings
|
||||
}
|
||||
if (optionType < 60) //redirect to settings after optionType seconds
|
||||
{
|
||||
messageBody += "<script>setTimeout(RS," + String(optionType*1000) + ")</script>";
|
||||
} else if (optionType < 120) //redirect back after optionType-60 seconds
|
||||
{
|
||||
messageBody += "<script>setTimeout(B," + String((optionType-60)*1000) + ")</script>";
|
||||
} else if (optionType < 180) //reload parent after optionType-120 seconds
|
||||
{
|
||||
messageBody += "<script>setTimeout(RP," + String((optionType-120)*1000) + ")</script>";
|
||||
}
|
||||
messageBody += "</body></html>";
|
||||
server.setContentLength(strlen_P(PAGE_msg0) + cssColorString.length() + strlen_P(PAGE_msg1) + messageBody.length());
|
||||
server.send(code, "text/html", "");
|
||||
server.sendContent_P(PAGE_msg0);
|
||||
server.sendContent(cssColorString);
|
||||
server.sendContent_P(PAGE_msg1);
|
||||
server.sendContent(messageBody);
|
||||
}
|
||||
|
||||
void serveSettings(byte subPage)
|
||||
{
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
|
||||
if (!arlsTimeout) //do not serve while receiving realtime
|
||||
{
|
||||
int pl0, pl1;
|
||||
switch (subPage)
|
||||
{
|
||||
case 1: pl0 = strlen_P(PAGE_settings_wifi0); pl1 = strlen_P(PAGE_settings_wifi1); break;
|
||||
case 2: pl0 = strlen_P(PAGE_settings_leds0); pl1 = strlen_P(PAGE_settings_leds1); break;
|
||||
case 3: pl0 = strlen_P(PAGE_settings_ui0); pl1 = strlen_P(PAGE_settings_ui1); break;
|
||||
case 4: pl0 = strlen_P(PAGE_settings_sync0); pl1 = strlen_P(PAGE_settings_sync1); break;
|
||||
case 5: pl0 = strlen_P(PAGE_settings_time0); pl1 = strlen_P(PAGE_settings_time1); break;
|
||||
case 6: pl0 = strlen_P(PAGE_settings_sec0); pl1 = strlen_P(PAGE_settings_sec1); break;
|
||||
case 255: pl0 = strlen_P(PAGE_welcome0); pl1 = strlen_P(PAGE_welcome1); break;
|
||||
default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1);
|
||||
}
|
||||
|
||||
String settingsBuffer = getSettings(subPage);
|
||||
int sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0;
|
||||
|
||||
server.setContentLength(pl0 + cssColorString.length() + settingsBuffer.length() + sCssLength + pl1);
|
||||
server.send(200, "text/html", "");
|
||||
|
||||
switch (subPage)
|
||||
{
|
||||
case 1: server.sendContent_P(PAGE_settings_wifi0); break;
|
||||
case 2: server.sendContent_P(PAGE_settings_leds0); break;
|
||||
case 3: server.sendContent_P(PAGE_settings_ui0); break;
|
||||
case 4: server.sendContent_P(PAGE_settings_sync0); break;
|
||||
case 5: server.sendContent_P(PAGE_settings_time0); break;
|
||||
case 6: server.sendContent_P(PAGE_settings_sec0); break;
|
||||
case 255: server.sendContent_P(PAGE_welcome0); break;
|
||||
default: server.sendContent_P(PAGE_settings0);
|
||||
}
|
||||
server.sendContent(settingsBuffer);
|
||||
server.sendContent(cssColorString);
|
||||
if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss);
|
||||
switch (subPage)
|
||||
{
|
||||
case 1: server.sendContent_P(PAGE_settings_wifi1); break;
|
||||
case 2: server.sendContent_P(PAGE_settings_leds1); break;
|
||||
case 3: server.sendContent_P(PAGE_settings_ui1); break;
|
||||
case 4: server.sendContent_P(PAGE_settings_sync1); break;
|
||||
case 5: server.sendContent_P(PAGE_settings_time1); break;
|
||||
case 6: server.sendContent_P(PAGE_settings_sec1); break;
|
||||
case 255: server.sendContent_P(PAGE_welcome1); break;
|
||||
default: server.sendContent_P(PAGE_settings1);
|
||||
}
|
||||
} else {
|
||||
server.send(200, "text/plain", "The settings are not available while receiving real-time data.");
|
||||
}
|
||||
olen = 0;
|
||||
oappend("hard-coded build info:\r\n\n");
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend("platform: esp32");
|
||||
#else
|
||||
oappend("platform: esp8266");
|
||||
#endif
|
||||
oappend("\r\nversion: ");
|
||||
oappend(versionString);
|
||||
oappend("\r\nbuild: ");
|
||||
oappendi(VERSION);
|
||||
oappend("\r\neepver: ");
|
||||
oappendi(EEPVER);
|
||||
oappend("\r\nesp-core: ");
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
oappend((char*)ESP.getSdkVersion());
|
||||
#else
|
||||
oappend((char*)ESP.getCoreVersion().c_str());
|
||||
#endif
|
||||
oappend("\r\nopt: ");
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
oappend("alexa ");
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
oappend("blynk ");
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_CRONIXIE
|
||||
oappend("cronixie ");
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_HUESYNC
|
||||
oappend("huesync ");
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_MOBILE_UI
|
||||
oappend("mobile-ui ");
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
oappend("ota");
|
||||
#endif
|
||||
#ifdef USEFS
|
||||
oappend("\r\nspiffs: true\r\n");
|
||||
#else
|
||||
oappend("\r\nspiffs: false\r\n");
|
||||
#endif
|
||||
#ifdef WLED_DEBUG
|
||||
oappend("debug: true\r\n");
|
||||
#else
|
||||
oappend("debug: false\r\n");
|
||||
#endif
|
||||
oappend("button-pin: gpio");
|
||||
oappendi(BTNPIN);
|
||||
oappend("\r\nstrip-pin: gpio");
|
||||
oappendi(LEDPIN);
|
||||
oappend("\r\nbrand: wled");
|
||||
oappend("\r\nbuild-type: src\r\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
* EEPROM bytes 2944 to 3071 are reserved for your custom use case.
|
||||
*/
|
||||
|
||||
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
|
||||
|
||||
void userBeginPreConnection()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void userBegin()
|
||||
@@ -18,4 +20,3 @@ void userLoop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,23 @@
|
||||
*/
|
||||
|
||||
#define WLEDPACKETSIZE 24
|
||||
#define UDP_IN_MAXSIZE 1472
|
||||
|
||||
|
||||
void notify(byte callMode, bool followUp=false)
|
||||
{
|
||||
if (!udpConnected) return;
|
||||
switch (callMode)
|
||||
{
|
||||
case 0: return;
|
||||
case 1: if (!notifyDirect) return; break;
|
||||
case 2: if (!notifyButton) return; break;
|
||||
case 4: if (!notifyDirect) return; break;
|
||||
case 6: if (!notifyDirect) return; break; //fx change
|
||||
case 7: if (!notifyHue) return; break;
|
||||
case 7: if (!notifyHue) return; break;
|
||||
case 8: if (!notifyDirect) return; break;
|
||||
case 9: if (!notifyDirect) return; break;
|
||||
case 10: if (!notifyAlexa) return; break;
|
||||
default: return;
|
||||
}
|
||||
byte udpOut[WLEDPACKETSIZE];
|
||||
@@ -27,18 +33,19 @@ void notify(byte callMode, bool followUp=false)
|
||||
udpOut[7] = nightlightDelayMins;
|
||||
udpOut[8] = effectCurrent;
|
||||
udpOut[9] = effectSpeed;
|
||||
udpOut[10] = white;
|
||||
udpOut[11] = 4; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet 4: supports transitionDelay
|
||||
udpOut[10] = col[3];
|
||||
udpOut[11] = 5; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
||||
udpOut[12] = colSec[0];
|
||||
udpOut[13] = colSec[1];
|
||||
udpOut[14] = colSec[2];
|
||||
udpOut[15] = whiteSec;
|
||||
udpOut[15] = colSec[3];
|
||||
udpOut[16] = effectIntensity;
|
||||
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
||||
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
||||
udpOut[19] = effectPalette;
|
||||
|
||||
IPAddress broadcastIp;
|
||||
broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP();
|
||||
broadcastIp = ~uint32_t(WiFi.subnetMask()) | uint32_t(WiFi.gatewayIP());
|
||||
|
||||
notifierUdp.beginPacket(broadcastIp, udpPort);
|
||||
notifierUdp.write(udpOut, WLEDPACKETSIZE);
|
||||
@@ -48,98 +55,213 @@ void notify(byte callMode, bool followUp=false)
|
||||
notificationTwoRequired = (followUp)? false:notifyTwice;
|
||||
}
|
||||
|
||||
|
||||
void arlsLock(uint32_t timeoutMs)
|
||||
{
|
||||
if (!realtimeActive){
|
||||
for (uint16_t i = 0; i < ledCount; i++)
|
||||
{
|
||||
strip.setPixelColor(i,0,0,0,0);
|
||||
}
|
||||
strip.unlockAll();
|
||||
}
|
||||
realtimeActive = true;
|
||||
realtimeTimeout = millis() + timeoutMs;
|
||||
if (arlsForceMaxBri) strip.setBrightness(255);
|
||||
}
|
||||
|
||||
|
||||
void initE131(){
|
||||
if (WiFi.status() == WL_CONNECTED && e131Enabled)
|
||||
{
|
||||
e131 = new E131();
|
||||
e131->begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe);
|
||||
} else {
|
||||
e131Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleE131(){
|
||||
//E1.31 protocol support
|
||||
if(e131Enabled) {
|
||||
uint16_t len = e131->parsePacket();
|
||||
if (!len || e131->universe < e131Universe || e131->universe > e131Universe +4) return;
|
||||
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;
|
||||
|
||||
arlsLock(realtimeTimeoutMs);
|
||||
if (len + multipacketOffset > ledCount) len = ledCount - multipacketOffset;
|
||||
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
int j = i * 3;
|
||||
setRealtimePixel(i + multipacketOffset, e131->data[j], e131->data[j+1], e131->data[j+2], 0);
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleNotifications()
|
||||
{
|
||||
//send second notification if enabled
|
||||
if(udpConnected && notificationTwoRequired && millis()-notificationSentTime > 250){
|
||||
notify(notificationSentCallMode,true);
|
||||
}
|
||||
|
||||
if(udpConnected && receiveNotifications){
|
||||
uint16_t packetSize = notifierUdp.parsePacket();
|
||||
if (packetSize > 1026) return;
|
||||
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves
|
||||
|
||||
handleE131();
|
||||
|
||||
//unlock strip when realtime UDP times out
|
||||
if (realtimeActive && millis() > realtimeTimeout)
|
||||
{
|
||||
//strip.unlockAll();
|
||||
strip.setBrightness(bri);
|
||||
realtimeActive = false;
|
||||
//strip.setMode(effectCurrent);
|
||||
realtimeIP[0] = 0;
|
||||
}
|
||||
|
||||
//receive UDP notifications
|
||||
if (!udpConnected || !(receiveNotifications || receiveDirect)) return;
|
||||
|
||||
uint16_t packetSize = notifierUdp.parsePacket();
|
||||
|
||||
//hyperion / raw RGB
|
||||
if (!packetSize && udpRgbConnected) {
|
||||
packetSize = rgbUdp.parsePacket();
|
||||
if (!receiveDirect) return;
|
||||
if (packetSize > UDP_IN_MAXSIZE || packetSize < 3) return;
|
||||
realtimeIP = rgbUdp.remoteIP();
|
||||
DEBUG_PRINTLN(rgbUdp.remoteIP());
|
||||
olen = 0;
|
||||
rgbUdp.read(obuf, packetSize);
|
||||
arlsLock(realtimeTimeoutMs);
|
||||
uint16_t id = 0;
|
||||
for (uint16_t i = 0; i < packetSize -2; i += 3)
|
||||
{
|
||||
byte udpIn[packetSize];
|
||||
notifierUdp.read(udpIn, packetSize);
|
||||
if (udpIn[0] == 0 && !arlsTimeout) //wled notifier, block if realtime packets active
|
||||
setRealtimePixel(id, obuf[i], obuf[i+1], obuf[i+2], 0);
|
||||
|
||||
id++; if (id >= ledCount) break;
|
||||
}
|
||||
strip.show();
|
||||
return;
|
||||
}
|
||||
|
||||
//notifier and UDP realtime
|
||||
if (packetSize > UDP_IN_MAXSIZE) return;
|
||||
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves
|
||||
{
|
||||
olen = 0;
|
||||
notifierUdp.read(obuf, packetSize);
|
||||
char* udpIn = obuf;
|
||||
|
||||
//wled notifier, block if realtime packets active
|
||||
if (udpIn[0] == 0 && !realtimeActive && receiveNotifications)
|
||||
{
|
||||
//apply colors from notification
|
||||
if (receiveNotificationColor)
|
||||
{
|
||||
if (receiveNotificationColor)
|
||||
{
|
||||
col[0] = udpIn[3];
|
||||
col[1] = udpIn[4];
|
||||
col[2] = udpIn[5];
|
||||
}
|
||||
if (udpIn[11] > 0 && receiveNotificationColor) //check if sending modules white val is inteded
|
||||
if (udpIn[11] > 0) //check if sending modules white val is inteded
|
||||
{
|
||||
white = udpIn[10];
|
||||
if (udpIn[11] > 1 )
|
||||
col[3] = udpIn[10];
|
||||
if (udpIn[11] > 1)
|
||||
{
|
||||
colSec[0] = udpIn[12];
|
||||
colSec[1] = udpIn[13];
|
||||
colSec[2] = udpIn[14];
|
||||
whiteSec = udpIn[15];
|
||||
colSec[3] = udpIn[15];
|
||||
}
|
||||
}
|
||||
if (udpIn[8] != effectCurrent && receiveNotificationEffects)
|
||||
{
|
||||
effectCurrent = udpIn[8];
|
||||
strip.setMode(effectCurrent);
|
||||
}
|
||||
if (udpIn[9] != effectSpeed && receiveNotificationEffects)
|
||||
{
|
||||
effectSpeed = udpIn[9];
|
||||
strip.setSpeed(effectSpeed);
|
||||
}
|
||||
if (udpIn[11] > 2 && udpIn[16] != effectIntensity && receiveNotificationEffects)
|
||||
{
|
||||
effectIntensity = udpIn[16];
|
||||
strip.setIntensity(effectIntensity);
|
||||
}
|
||||
if (udpIn[11] > 3)
|
||||
{
|
||||
transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00);
|
||||
}
|
||||
nightlightActive = udpIn[6];
|
||||
if (!nightlightActive)
|
||||
{
|
||||
if (receiveNotificationBrightness) bri = udpIn[2];
|
||||
colorUpdated(3);
|
||||
}
|
||||
} else if (udpIn[0] == 1) //warls
|
||||
{
|
||||
if (packetSize > 1) {
|
||||
if (udpIn[1] == 0)
|
||||
{
|
||||
arlsTimeout = false;
|
||||
} else {
|
||||
if (!arlsTimeout){
|
||||
strip.setRange(0, ledCount-1, 0);
|
||||
strip.setMode(0);
|
||||
}
|
||||
arlsTimeout = true;
|
||||
arlsTimeoutTime = millis() + 1000*udpIn[1];
|
||||
}
|
||||
for (int i = 2; i < packetSize -3; i += 4)
|
||||
{
|
||||
if (udpIn[i] + arlsOffset < ledCount && udpIn[i] + arlsOffset >= 0)
|
||||
if (useGammaCorrectionRGB)
|
||||
{
|
||||
strip.setPixelColor(udpIn[i] + arlsOffset, gamma8[udpIn[i+1]], gamma8[udpIn[i+2]], gamma8[udpIn[i+3]]);
|
||||
} else {
|
||||
strip.setPixelColor(udpIn[i] + arlsOffset, udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
||||
}
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arlsTimeout && millis() > arlsTimeoutTime)
|
||||
|
||||
//apply effects from notification
|
||||
if (receiveNotificationEffects)
|
||||
{
|
||||
effectCurrent = udpIn[8];
|
||||
effectSpeed = udpIn[9];
|
||||
if (udpIn[11] > 2) effectIntensity = udpIn[16];
|
||||
if (udpIn[11] > 4) effectPalette = udpIn[19];
|
||||
}
|
||||
|
||||
if (udpIn[11] > 3)
|
||||
{
|
||||
transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00);
|
||||
}
|
||||
|
||||
nightlightActive = udpIn[6];
|
||||
if (nightlightActive) nightlightDelayMins = udpIn[7];
|
||||
|
||||
if (receiveNotificationBrightness) bri = udpIn[2];
|
||||
colorUpdated(3);
|
||||
|
||||
} else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
|
||||
{
|
||||
strip.unlockAll();
|
||||
arlsTimeout = false;
|
||||
strip.setMode(effectCurrent);
|
||||
realtimeIP = notifierUdp.remoteIP();
|
||||
DEBUG_PRINTLN(notifierUdp.remoteIP());
|
||||
if (packetSize > 1) {
|
||||
if (udpIn[1] == 0)
|
||||
{
|
||||
realtimeActive = false;
|
||||
return;
|
||||
} else {
|
||||
arlsLock(udpIn[1]*1000);
|
||||
}
|
||||
if (udpIn[0] == 1) //warls
|
||||
{
|
||||
for (uint16_t i = 2; i < packetSize -3; i += 4)
|
||||
{
|
||||
setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0);
|
||||
}
|
||||
} else if (udpIn[0] == 2) //drgb
|
||||
{
|
||||
uint16_t id = 0;
|
||||
for (uint16_t i = 2; i < packetSize -2; i += 3)
|
||||
{
|
||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||
|
||||
id++; if (id >= ledCount) break;
|
||||
}
|
||||
} else if (udpIn[0] == 3) //drgbw
|
||||
{
|
||||
uint16_t id = 0;
|
||||
for (uint16_t i = 2; i < packetSize -3; i += 4)
|
||||
{
|
||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
||||
|
||||
id++; if (id >= ledCount) break;
|
||||
}
|
||||
} else if (udpIn[0] == 4) //dnrgb
|
||||
{
|
||||
uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
||||
for (uint16_t i = 4; i < packetSize -2; i += 3)
|
||||
{
|
||||
if (id >= ledCount) break;
|
||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
strip.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
uint16_t pix = i + arlsOffset;
|
||||
if (pix < ledCount)
|
||||
{
|
||||
if (!arlsDisableGammaCorrection && useGammaCorrectionRGB)
|
||||
{
|
||||
strip.setPixelColor(pix, gamma8[r], gamma8[g], gamma8[b], gamma8[w]);
|
||||
} else {
|
||||
strip.setPixelColor(pix, r, g, b, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,59 +2,95 @@
|
||||
* LED methods
|
||||
*/
|
||||
|
||||
void setAllLeds() {
|
||||
double d = briT*briMultiplier;
|
||||
int val = d/100;
|
||||
if (val > 255) val = 255;
|
||||
if (useGammaCorrectionBri)
|
||||
void toggleOnOff()
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
strip.setBrightness(gamma8[val]);
|
||||
} else {
|
||||
strip.setBrightness(val);
|
||||
}
|
||||
if (useGammaCorrectionRGB)
|
||||
bri = briLast;
|
||||
} else
|
||||
{
|
||||
strip.setColor(gamma8[colT[0]], gamma8[colT[1]], gamma8[colT[2]], gamma8[whiteT]);
|
||||
strip.setSecondaryColor(gamma8[colSec[0]], gamma8[colSec[1]], gamma8[colSec[2]], gamma8[whiteSec]);
|
||||
} else {
|
||||
strip.setColor(colT[0], colT[1], colT[2], whiteT);
|
||||
strip.setSecondaryColor(colSec[0], colSec[1], colSec[2], whiteSec);
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setAllLeds() {
|
||||
if (!realtimeActive || !arlsForceMaxBri)
|
||||
{
|
||||
double d = briT*briMultiplier;
|
||||
int val = d/100;
|
||||
if (val > 255) val = 255;
|
||||
if (useGammaCorrectionBri)
|
||||
{
|
||||
strip.setBrightness(gamma8[val]);
|
||||
} else {
|
||||
strip.setBrightness(val);
|
||||
}
|
||||
}
|
||||
if (!enableSecTransition)
|
||||
{
|
||||
for (byte i = 0; i<3; i++)
|
||||
{
|
||||
colSecT[i] = colSec[i];
|
||||
}
|
||||
colSecT[3] = colSec[3];
|
||||
}
|
||||
if (useRGBW && autoRGBtoRGBW)
|
||||
{
|
||||
colorRGBtoRGBW(colT);
|
||||
colorRGBtoRGBW(colSecT);
|
||||
}
|
||||
if (useGammaCorrectionRGB)
|
||||
{
|
||||
strip.setColor(gamma8[colT[0]], gamma8[colT[1]], gamma8[colT[2]], gamma8[colT[3]]);
|
||||
strip.setSecondaryColor(gamma8[colSecT[0]], gamma8[colSecT[1]], gamma8[colSecT[2]], gamma8[colSecT[3]]);
|
||||
} else {
|
||||
strip.setColor(colT[0], colT[1], colT[2], colT[3]);
|
||||
strip.setSecondaryColor(colSecT[0], colSecT[1], colSecT[2], colSecT[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setLedsStandard()
|
||||
{
|
||||
colOld[0] = col[0];
|
||||
colOld[1] = col[1];
|
||||
colOld[2] = col[2];
|
||||
whiteOld = white;
|
||||
for (byte i=0; i<4; i++)
|
||||
{
|
||||
colOld[i] = col[i];
|
||||
colT[i] = col[i];
|
||||
colSecOld[i] = colSec[i];
|
||||
colSecT[i] = colSec[i];
|
||||
}
|
||||
briOld = bri;
|
||||
colT[0] = col[0];
|
||||
colT[1] = col[1];
|
||||
colT[2] = col[2];
|
||||
whiteT = white;
|
||||
briT = bri;
|
||||
setAllLeds();
|
||||
}
|
||||
|
||||
|
||||
bool colorChanged()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (byte i=0; i<4; i++)
|
||||
{
|
||||
if (col[i] != colIT[i]) return true;
|
||||
if (colSec[i] != colSecIT[i]) return true;
|
||||
}
|
||||
if (white != whiteIT || whiteSec != whiteSecIT) return true;
|
||||
if (bri != briIT) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void colorUpdated(int callMode)
|
||||
{
|
||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (NN)6: fx changed 7: hue
|
||||
//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
|
||||
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
|
||||
if (!colorChanged())
|
||||
{
|
||||
if (callMode == 6) notify(6);
|
||||
if (nightlightActive && !nightlightActiveOld && callMode != 3 && callMode != 5)
|
||||
{
|
||||
notify(4); return;
|
||||
}
|
||||
else if (fxChanged) notify(6);
|
||||
return; //no change
|
||||
}
|
||||
if (callMode != 5 && nightlightActive && nightlightFade)
|
||||
@@ -63,87 +99,97 @@ void colorUpdated(int callMode)
|
||||
nightlightDelayMs -= (millis() - nightlightStartTime);
|
||||
nightlightStartTime = millis();
|
||||
}
|
||||
colIT[0] = col[0];
|
||||
colIT[1] = col[1];
|
||||
colIT[2] = col[2];
|
||||
colSecIT[0] = colSec[0];
|
||||
colSecIT[1] = colSec[1];
|
||||
colSecIT[2] = colSec[2];
|
||||
whiteIT = white;
|
||||
whiteSecIT = whiteSec;
|
||||
for (byte i=0; i<4; i++)
|
||||
{
|
||||
colIT[i] = col[i];
|
||||
colSecIT[i] = colSec[i];
|
||||
}
|
||||
briIT = bri;
|
||||
if (bri > 0) briLast = bri;
|
||||
|
||||
notify(callMode);
|
||||
if (fadeTransition || sweepTransition)
|
||||
|
||||
if (fadeTransition)
|
||||
{
|
||||
//set correct delay if not using notification delay
|
||||
if (callMode != 3) transitionDelayTemp = transitionDelay;
|
||||
if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;}
|
||||
|
||||
if (transitionActive)
|
||||
{
|
||||
colOld[0] = colT[0];
|
||||
colOld[1] = colT[1];
|
||||
colOld[2] = colT[2];
|
||||
whiteOld = whiteT;
|
||||
for (byte i=0; i<4; i++)
|
||||
{
|
||||
colOld[i] = colT[i];
|
||||
colSecOld[i] = colSecT[i];
|
||||
}
|
||||
briOld = briT;
|
||||
tperLast = 0;
|
||||
}
|
||||
strip.setTransitionMode(true);
|
||||
transitionActive = true;
|
||||
transitionStartTime = millis();
|
||||
strip.setFastUpdateMode(true);
|
||||
} else
|
||||
{
|
||||
setLedsStandard();
|
||||
strip.trigger();
|
||||
}
|
||||
|
||||
if (callMode == 8) return;
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
if (espalexaDevice != nullptr) espalexaDevice->setValue(bri);
|
||||
#endif
|
||||
//only update Blynk and mqtt every 2 seconds to reduce lag
|
||||
if (millis() - lastInterfaceUpdate <= 2000)
|
||||
{
|
||||
interfaceUpdateCallMode = callMode;
|
||||
return;
|
||||
}
|
||||
updateInterfaces(callMode);
|
||||
}
|
||||
|
||||
|
||||
void updateInterfaces(uint8_t callMode)
|
||||
{
|
||||
if (callMode != 9 && callMode != 5) updateBlynk();
|
||||
publishMQTT();
|
||||
lastInterfaceUpdate = millis();
|
||||
}
|
||||
|
||||
|
||||
void handleTransitions()
|
||||
{
|
||||
//handle still pending interface update
|
||||
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > 2000)
|
||||
{
|
||||
updateInterfaces(interfaceUpdateCallMode);
|
||||
interfaceUpdateCallMode = 0; //disable
|
||||
}
|
||||
|
||||
if (transitionActive && transitionDelayTemp > 0)
|
||||
{
|
||||
float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp;
|
||||
if (tper >= 1.0)
|
||||
{
|
||||
strip.setTransitionMode(false);
|
||||
transitionActive = false;
|
||||
tperLast = 0;
|
||||
if (sweepTransition) strip.unlockAll();
|
||||
setLedsStandard();
|
||||
strip.setFastUpdateMode(false);
|
||||
return;
|
||||
}
|
||||
if (tper - tperLast < transitionResolution)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (tper - tperLast < 0.004) return;
|
||||
tperLast = tper;
|
||||
if (fadeTransition)
|
||||
for (byte i=0; i<4; i++)
|
||||
{
|
||||
colT[0] = colOld[0]+((col[0] - colOld[0])*tper);
|
||||
colT[1] = colOld[1]+((col[1] - colOld[1])*tper);
|
||||
colT[2] = colOld[2]+((col[2] - colOld[2])*tper);
|
||||
whiteT = whiteOld +((white - whiteOld )*tper);
|
||||
briT = briOld +((bri - briOld )*tper);
|
||||
colT[i] = colOld[i]+((col[i] - colOld[i])*tper);
|
||||
colSecT[i] = colSecOld[i]+((colSec[i] - colSecOld[i])*tper);
|
||||
}
|
||||
if (sweepTransition)
|
||||
{
|
||||
strip.lockAll();
|
||||
if (sweepDirection)
|
||||
{
|
||||
strip.unlockRange(0, (int)(tper*(double)ledCount));
|
||||
} else
|
||||
{
|
||||
strip.unlockRange(ledCount - (int)(tper*(double)ledCount), ledCount);
|
||||
}
|
||||
if (!fadeTransition)
|
||||
{
|
||||
setLedsStandard();
|
||||
}
|
||||
}
|
||||
if (fadeTransition) setAllLeds();
|
||||
briT = briOld +((bri - briOld )*tper);
|
||||
|
||||
setAllLeds();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleNightlight()
|
||||
{
|
||||
if (nightlightActive)
|
||||
@@ -151,7 +197,6 @@ void handleNightlight()
|
||||
if (!nightlightActiveOld) //init
|
||||
{
|
||||
nightlightStartTime = millis();
|
||||
notify(4);
|
||||
nightlightDelayMs = (int)(nightlightDelayMins*60000);
|
||||
nightlightActiveOld = true;
|
||||
briNlT = bri;
|
||||
@@ -159,7 +204,7 @@ void handleNightlight()
|
||||
float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
|
||||
if (nightlightFade)
|
||||
{
|
||||
bri = briNlT+((nightlightTargetBri - briNlT)*nper);
|
||||
bri = briNlT + ((nightlightTargetBri - briNlT)*nper);
|
||||
colorUpdated(5);
|
||||
}
|
||||
if (nper >= 1)
|
||||
@@ -170,10 +215,21 @@ void handleNightlight()
|
||||
bri = nightlightTargetBri;
|
||||
colorUpdated(5);
|
||||
}
|
||||
updateBlynk();
|
||||
if (bri == 0) briLast = briNlT;
|
||||
}
|
||||
} else if (nightlightActiveOld) //early de-init
|
||||
{
|
||||
nightlightActiveOld = false;
|
||||
}
|
||||
|
||||
//also handle preset cycle here
|
||||
if (presetCyclingEnabled && (millis() - presetCycledTime > presetCycleTime))
|
||||
{
|
||||
applyPreset(presetCycCurr,presetApplyBri,presetApplyCol,presetApplyFx);
|
||||
presetCycCurr++; if (presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin;
|
||||
if (presetCycCurr > 25) presetCycCurr = 1;
|
||||
colorUpdated(8);
|
||||
presetCycledTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ void handleButton()
|
||||
{
|
||||
if (buttonEnabled)
|
||||
{
|
||||
if (digitalRead(buttonPin) == LOW && !buttonPressedBefore)
|
||||
if (digitalRead(BTNPIN) == LOW && !buttonPressedBefore)
|
||||
{
|
||||
buttonPressedTime = millis();
|
||||
buttonPressedBefore = true;
|
||||
}
|
||||
else if (digitalRead(buttonPin) == HIGH && buttonPressedBefore)
|
||||
else if (digitalRead(BTNPIN) == HIGH && buttonPressedBefore)
|
||||
{
|
||||
delay(15); //debounce
|
||||
if (digitalRead(buttonPin) == HIGH)
|
||||
if (digitalRead(BTNPIN) == HIGH)
|
||||
{
|
||||
if (millis() - buttonPressedTime > 7000) {initAP();}
|
||||
else if (millis() - buttonPressedTime > 700)
|
||||
@@ -25,14 +25,7 @@ void handleButton()
|
||||
else {
|
||||
if (macroButton == 0)
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
bri = briLast;
|
||||
} else
|
||||
{
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
}
|
||||
toggleOnOff();
|
||||
colorUpdated(2);
|
||||
} else {
|
||||
applyMacro(macroButton);
|
||||
@@ -51,9 +44,9 @@ void handleButton()
|
||||
auxActiveBefore = true;
|
||||
switch (auxTriggeredState)
|
||||
{
|
||||
case 0: pinMode(auxPin, INPUT); break;
|
||||
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break;
|
||||
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break;
|
||||
case 0: pinMode(AUXPIN, INPUT); break;
|
||||
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
|
||||
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
|
||||
}
|
||||
auxStartTime = millis();
|
||||
}
|
||||
@@ -63,9 +56,9 @@ void handleButton()
|
||||
auxActiveBefore = false;
|
||||
switch (auxDefaultState)
|
||||
{
|
||||
case 0: pinMode(auxPin, INPUT); break;
|
||||
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break;
|
||||
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break;
|
||||
case 0: pinMode(AUXPIN, INPUT); break;
|
||||
case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
|
||||
case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,24 +72,23 @@ void handleNetworkTime()
|
||||
|
||||
void sendNTPPacket()
|
||||
{
|
||||
const char* ntpsrv = ntpServerName.c_str();
|
||||
WiFi.hostByName(ntpsrv, ntpServerIP);
|
||||
WiFi.hostByName(ntpServerName, ntpServerIP);
|
||||
DEBUG_PRINTLN("send NTP packet");
|
||||
|
||||
memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE);
|
||||
memset(obuf, 0, NTP_PACKET_SIZE);
|
||||
|
||||
ntpPacketBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||
ntpPacketBuffer[1] = 0; // Stratum, or type of clock
|
||||
ntpPacketBuffer[2] = 6; // Polling Interval
|
||||
ntpPacketBuffer[3] = 0xEC; // Peer Clock Precision
|
||||
obuf[0] = 0b11100011; // LI, Version, Mode
|
||||
obuf[1] = 0; // Stratum, or type of clock
|
||||
obuf[2] = 6; // Polling Interval
|
||||
obuf[3] = 0xEC; // Peer Clock Precision
|
||||
// 8 bytes of zero for Root Delay & Root Dispersion
|
||||
ntpPacketBuffer[12] = 49;
|
||||
ntpPacketBuffer[13] = 0x4E;
|
||||
ntpPacketBuffer[14] = 49;
|
||||
ntpPacketBuffer[15] = 52;
|
||||
obuf[12] = 49;
|
||||
obuf[13] = 0x4E;
|
||||
obuf[14] = 49;
|
||||
obuf[15] = 52;
|
||||
|
||||
ntpUdp.beginPacket(ntpServerIP, 123); //NTP requests are to port 123
|
||||
ntpUdp.write(ntpPacketBuffer, NTP_PACKET_SIZE);
|
||||
ntpUdp.write((byte*)obuf, NTP_PACKET_SIZE);
|
||||
ntpUdp.endPacket();
|
||||
}
|
||||
|
||||
@@ -97,19 +96,19 @@ bool checkNTPResponse()
|
||||
{
|
||||
int cb = ntpUdp.parsePacket();
|
||||
if (cb) {
|
||||
DEBUG_PRINT("packet received, length=");
|
||||
DEBUG_PRINT("packet received, l=");
|
||||
DEBUG_PRINTLN(cb);
|
||||
|
||||
ntpUdp.read(ntpPacketBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
|
||||
ntpUdp.read(obuf, NTP_PACKET_SIZE); // read the packet into the buffer
|
||||
|
||||
unsigned long highWord = word(ntpPacketBuffer[40], ntpPacketBuffer[41]);
|
||||
unsigned long lowWord = word(ntpPacketBuffer[42], ntpPacketBuffer[43]);
|
||||
unsigned long highWord = word(obuf[40], obuf[41]);
|
||||
unsigned long lowWord = word(obuf[42], obuf[43]);
|
||||
if (highWord == 0 && lowWord == 0) return false;
|
||||
|
||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||
|
||||
DEBUG_PRINT("Unix time = ");
|
||||
unsigned long epoch = secsSince1900 - 2208988800UL; //subtract 70 years
|
||||
unsigned long epoch = secsSince1900 - 2208988799UL; //subtract 70 years -1sec (on avg. more precision)
|
||||
setTime(epoch);
|
||||
DEBUG_PRINTLN(epoch);
|
||||
if (countdownTime - now() > 0) countdownOverTriggered = false;
|
||||
@@ -167,3 +166,28 @@ bool checkCountdown()
|
||||
return false;
|
||||
}
|
||||
|
||||
byte weekdayMondayFirst()
|
||||
{
|
||||
byte wd = weekday(local) -1;
|
||||
if (wd == 0) wd = 7;
|
||||
return wd;
|
||||
}
|
||||
|
||||
void checkTimers()
|
||||
{
|
||||
if (lastTimerMinute != minute(local)) //only check once a new minute begins
|
||||
{
|
||||
lastTimerMinute = minute(local);
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (timerMacro[i] != 0
|
||||
&& (timerHours[i] == hour(local) || timerHours[i] == 24) //if hour is set to 24, activate every hour
|
||||
&& timerMinutes[i] == minute(local)
|
||||
&& (timerWeekday[i] & 0x01) //timer is enabled
|
||||
&& timerWeekday[i] >> weekdayMondayFirst() & 0x01) //timer should activate at current day of week
|
||||
{
|
||||
applyMacro(timerMacro[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,25 +3,26 @@
|
||||
*/
|
||||
void initCronixie()
|
||||
{
|
||||
if (overlayCurrent == 4 && !cronixieInit)
|
||||
if (overlayCurrent == 3 && !cronixieInit)
|
||||
{
|
||||
strip.driverModeCronixie(true);
|
||||
strip.setCronixieBacklight(cronixieBacklight);
|
||||
setCronixie();
|
||||
cronixieInit = true;
|
||||
} else if (cronixieInit && overlayCurrent != 4)
|
||||
} else if (cronixieInit && overlayCurrent != 3)
|
||||
{
|
||||
strip.driverModeCronixie(false);
|
||||
cronixieInit = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)white << 24)| ((uint32_t)colT[0] << 16) | ((uint32_t)colT[1] << 8) | colT[2]);
|
||||
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)
|
||||
@@ -116,33 +117,26 @@ void _nixieNumber(int number, int dur)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleOverlays()
|
||||
{
|
||||
if (millis() - overlayRefreshedTime > overlayRefreshMs)
|
||||
{
|
||||
initCronixie();
|
||||
updateLocalTime();
|
||||
checkTimers();
|
||||
switch (overlayCurrent)
|
||||
{
|
||||
case 0: break;//no overlay
|
||||
case 1: _overlaySolid(); break;//solid secondary color
|
||||
case 2: _overlayAnalogClock(); break;//2 analog clock
|
||||
case 3: _overlayNixieClock(); break;//nixie 1-digit
|
||||
case 4: _overlayCronixie();//Diamex cronixie clock kit
|
||||
case 1: _overlayAnalogClock(); break;//2 analog clock
|
||||
case 2: _overlayNixieClock(); break;//nixie 1-digit
|
||||
case 3: _overlayCronixie();//Diamex cronixie clock kit
|
||||
}
|
||||
if (!countdownMode || overlayCurrent < 2) checkCountdown(); //countdown macro activation must work
|
||||
overlayRefreshedTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void _overlaySolid()
|
||||
{
|
||||
strip.unlockAll();
|
||||
uint32_t cls = (useGammaCorrectionRGB)? gamma8[whiteSec*16777216] + gamma8[colSec[0]]*65536 + gamma8[colSec[1]]*256 + gamma8[colSec[2]]:whiteSec*16777216 + colSec[0]*65536 + colSec[1]*256 + colSec[2];
|
||||
strip.setRange(overlayMin,overlayMax,cls);
|
||||
overlayRefreshMs = 1902;
|
||||
}
|
||||
|
||||
void _overlayAnalogClock()
|
||||
{
|
||||
int overlaySize = overlayMax - overlayMin +1;
|
||||
@@ -151,7 +145,6 @@ void _overlayAnalogClock()
|
||||
{
|
||||
_overlayAnalogCountdown(); return;
|
||||
}
|
||||
_overlaySolid();
|
||||
double hourP = ((double)(hour(local)%12))/12;
|
||||
double minuteP = ((double)minute(local))/60;
|
||||
hourP = hourP + minuteP/12;
|
||||
@@ -178,9 +171,9 @@ void _overlayAnalogClock()
|
||||
int pix;
|
||||
for (int i = 0; i <= 12; i++)
|
||||
{
|
||||
pix = overlayMin + analogClock12pixel + (overlaySize/12)*i;
|
||||
if (pix > overlayMax) pix = pix - overlayMax;
|
||||
strip.setIndividual(pix,0x00FFAA);
|
||||
pix = analogClock12pixel + round((overlaySize / 12.0) *i);
|
||||
if (pix > overlayMax) pix -= overlaySize;
|
||||
strip.setIndividual(pix, 0x00FFAA);
|
||||
}
|
||||
}
|
||||
if (!analogClockSecondsTrail) strip.setIndividual(secondPixel, 0xFF0000);
|
||||
@@ -191,6 +184,10 @@ void _overlayAnalogClock()
|
||||
|
||||
void _overlayNixieClock()
|
||||
{
|
||||
#ifdef WLED_DISABLE_CRONIXIE
|
||||
if (countdownMode) checkCountdown();
|
||||
#else
|
||||
|
||||
if (countdownMode)
|
||||
{
|
||||
_overlayNixieCountdown(); return;
|
||||
@@ -275,6 +272,7 @@ void _overlayNixieClock()
|
||||
{
|
||||
_nixieDisplay(overlayArr, overlayDur, overlayPauseDur, 6);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void _overlayAnalogCountdown()
|
||||
@@ -312,16 +310,17 @@ void _overlayAnalogCountdown()
|
||||
byte pixelCnt = perc*overlaySize;
|
||||
if (analogClock12pixel + pixelCnt > overlayMax)
|
||||
{
|
||||
strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)whiteSec << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)whiteSec << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
} else
|
||||
{
|
||||
strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)whiteSec << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
}
|
||||
}
|
||||
overlayRefreshMs = 998;
|
||||
}
|
||||
|
||||
|
||||
void _overlayNixieCountdown()
|
||||
{
|
||||
if (now() >= countdownTime)
|
||||
|
||||
@@ -5,281 +5,76 @@
|
||||
* https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch
|
||||
* https://github.com/probonopd/ESP8266HueEmulator
|
||||
*/
|
||||
|
||||
void alexaInit()
|
||||
{
|
||||
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
prepareIds();
|
||||
|
||||
udpConnected = connectUDP();
|
||||
|
||||
if (udpConnected) alexaInitPages();
|
||||
}
|
||||
}
|
||||
|
||||
void handleAlexa()
|
||||
{
|
||||
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
if(udpConnected){
|
||||
// if there’s data available, read a packet
|
||||
int packetSize = UDP.parsePacket();
|
||||
if(packetSize>0) {
|
||||
IPAddress remote = UDP.remoteIP();
|
||||
int len = UDP.read(packetBuffer, 255);
|
||||
if (len > 0) {
|
||||
packetBuffer[len] = 0;
|
||||
}
|
||||
String request = packetBuffer;
|
||||
|
||||
if(request.indexOf("M-SEARCH") >= 0) {
|
||||
if(request.indexOf("upnp:rootdevice") > 0 || request.indexOf("device:basic:1") > 0) {
|
||||
DEBUG_PRINTLN("Responding search req...");
|
||||
respondToSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void alexaOn()
|
||||
{
|
||||
if (macroAlexaOn == 0)
|
||||
{
|
||||
handleSet((alexaNotify)?"win&T=1&IN":"win&T=1&NN&IN");
|
||||
} else
|
||||
{
|
||||
applyMacro(macroAlexaOn);
|
||||
}
|
||||
|
||||
String body = "[{\"success\":{\"/lights/1/state/on\":true}}]";
|
||||
|
||||
server.send(200, "text/xml", body.c_str());
|
||||
|
||||
DEBUG_PRINT("Sending :");
|
||||
DEBUG_PRINTLN(body);
|
||||
}
|
||||
|
||||
void alexaOff()
|
||||
{
|
||||
if (macroAlexaOff == 0)
|
||||
{
|
||||
handleSet((alexaNotify)?"win&T=0&IN":"win&T=0&NN&IN");
|
||||
} else
|
||||
{
|
||||
applyMacro(macroAlexaOff);
|
||||
}
|
||||
|
||||
String body = "[{\"success\":{\"/lights/1/state/on\":false}}]";
|
||||
|
||||
server.send(200, "application/json", body.c_str());
|
||||
|
||||
DEBUG_PRINT("Sending:");
|
||||
DEBUG_PRINTLN(body);
|
||||
}
|
||||
|
||||
void alexaDim(byte briL)
|
||||
{
|
||||
String body = "[{\"success\":{\"/lights/1/state/bri\":"+ String(briL) +"}}]";
|
||||
|
||||
server.send(200, "application/json", body.c_str());
|
||||
|
||||
String ct = (alexaNotify)?"win&IN&A=":"win&NN&IN&A=";
|
||||
if (briL < 255)
|
||||
{
|
||||
ct = ct + (briL+1);
|
||||
} else
|
||||
{
|
||||
ct = ct + (255);
|
||||
}
|
||||
handleSet(ct);
|
||||
}
|
||||
|
||||
void prepareIds() {
|
||||
escapedMac = WiFi.macAddress();
|
||||
escapedMac.replace(":", "");
|
||||
escapedMac.toLowerCase();
|
||||
}
|
||||
|
||||
void respondToSearch() {
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINT("Send resp to ");
|
||||
DEBUG_PRINTLN(UDP.remoteIP());
|
||||
DEBUG_PRINT("Port : ");
|
||||
DEBUG_PRINTLN(UDP.remotePort());
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
void onAlexaChange(byte b, uint32_t color);
|
||||
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String response =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"EXT:\r\n"
|
||||
"CACHE-CONTROL: max-age=100\r\n" // SSDP_INTERVAL
|
||||
"LOCATION: http://"+ String(s) +":80/description.xml\r\n"
|
||||
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber
|
||||
"hue-bridgeid: "+ escapedMac +"\r\n"
|
||||
"ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType
|
||||
"USN: uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"::upnp:rootdevice\r\n" // _uuid::_deviceType
|
||||
"\r\n";
|
||||
|
||||
UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
UDP.write((byte*)response.c_str(), response.length());
|
||||
#else
|
||||
UDP.write(response.c_str());
|
||||
#endif
|
||||
UDP.endPacket();
|
||||
|
||||
DEBUG_PRINTLN("Response sent!");
|
||||
}
|
||||
|
||||
void alexaInitPages() {
|
||||
|
||||
server.on("/description.xml", HTTP_GET, [](){
|
||||
DEBUG_PRINTLN(" # Responding to description.xml ... #\n");
|
||||
|
||||
IPAddress localIP = WiFi.localIP();
|
||||
char s[16];
|
||||
sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||
|
||||
String setup_xml = "<?xml version=\"1.0\" ?>"
|
||||
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
|
||||
"<specVersion><major>1</major><minor>0</minor></specVersion>"
|
||||
"<URLBase>http://"+ String(s) +":80/</URLBase>"
|
||||
"<device>"
|
||||
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
|
||||
"<friendlyName>Philips hue ("+ String(s) +")</friendlyName>"
|
||||
"<manufacturer>Royal Philips Electronics</manufacturer>"
|
||||
"<manufacturerURL>http://www.philips.com</manufacturerURL>"
|
||||
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
|
||||
"<modelName>Philips hue bridge 2012</modelName>"
|
||||
"<modelNumber>929000226503</modelNumber>"
|
||||
"<modelURL>http://www.meethue.com</modelURL>"
|
||||
"<serialNumber>"+ escapedMac +"</serialNumber>"
|
||||
"<UDN>uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"</UDN>"
|
||||
"<presentationURL>index.html</presentationURL>"
|
||||
"<iconList>"
|
||||
" <icon>"
|
||||
" <mimetype>image/png</mimetype>"
|
||||
" <height>48</height>"
|
||||
" <width>48</width>"
|
||||
" <depth>24</depth>"
|
||||
" <url>hue_logo_0.png</url>"
|
||||
" </icon>"
|
||||
" <icon>"
|
||||
" <mimetype>image/png</mimetype>"
|
||||
" <height>120</height>"
|
||||
" <width>120</width>"
|
||||
" <depth>24</depth>"
|
||||
" <url>hue_logo_3.png</url>"
|
||||
" </icon>"
|
||||
"</iconList>"
|
||||
"</device>"
|
||||
"</root>";
|
||||
|
||||
server.send(200, "text/xml", setup_xml.c_str());
|
||||
|
||||
DEBUG_PRINT("Sending :");
|
||||
DEBUG_PRINTLN(setup_xml);
|
||||
});
|
||||
|
||||
// openHAB support
|
||||
server.on("/on.html", HTTP_GET, [](){
|
||||
DEBUG_PRINTLN("on req");
|
||||
server.send(200, "text/plain", "turned on");
|
||||
alexaOn();
|
||||
});
|
||||
|
||||
server.on("/off.html", HTTP_GET, [](){
|
||||
DEBUG_PRINTLN("off req");
|
||||
server.send(200, "text/plain", "turned off");
|
||||
alexaOff();
|
||||
});
|
||||
|
||||
server.on("/status.html", HTTP_GET, [](){
|
||||
DEBUG_PRINTLN("Got status request");
|
||||
|
||||
String statrespone = "0";
|
||||
if (bri > 0) {
|
||||
statrespone = "1";
|
||||
}
|
||||
server.send(200, "text/plain", statrespone);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
String boolString(bool st)
|
||||
void alexaInit()
|
||||
{
|
||||
return (st)?"true":"false";
|
||||
if (alexaEnabled && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
if (espalexaDevice == nullptr) //only init once
|
||||
{
|
||||
espalexaDevice = new EspalexaDevice(alexaInvocationName, onAlexaChange);
|
||||
espalexa.addDevice(espalexaDevice);
|
||||
espalexa.begin(&server);
|
||||
} else {
|
||||
espalexaDevice->setName(alexaInvocationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String briForHue(int realBri)
|
||||
void handleAlexa()
|
||||
{
|
||||
realBri--;
|
||||
if (realBri < 0) realBri = 0;
|
||||
return String(realBri);
|
||||
if (!alexaEnabled || WiFi.status() != WL_CONNECTED) return;
|
||||
espalexa.loop();
|
||||
}
|
||||
|
||||
bool handleAlexaApiCall(String req, String body) //basic implementation of Philips hue api functions needed for basic Alexa control
|
||||
void onAlexaChange(byte b, uint32_t color)
|
||||
{
|
||||
DEBUG_PRINTLN("AlexaApiCall");
|
||||
if (req.indexOf("api") <0) return false;
|
||||
DEBUG_PRINTLN("ok");
|
||||
if (body.indexOf("devicetype") > 0) //client wants a hue api username, we dont care and give static
|
||||
{
|
||||
DEBUG_PRINTLN("devType");
|
||||
server.send(200, "application/json", "[{\"success\":{\"username\": \"2WLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBQr\"}}]");
|
||||
return true;
|
||||
}
|
||||
if (req.indexOf("state") > 0) //client wants to control light
|
||||
{
|
||||
DEBUG_PRINTLN("ls");
|
||||
if (body.indexOf("bri")>0) {alexaDim(body.substring(body.indexOf("bri") +5).toInt()); return true;}
|
||||
if (body.indexOf("false")>0) {alexaOff(); return true;}
|
||||
alexaOn();
|
||||
|
||||
return true;
|
||||
}
|
||||
if (req.indexOf("lights/1") > 0) //client wants light info
|
||||
{
|
||||
DEBUG_PRINTLN("l1");
|
||||
server.send(200, "application/json", "{\"manufacturername\":\"OpenSource\",\"modelid\":\"LST001\",\"name\":\""+ alexaInvocationName +"\",\"state\":{\"on\":"+ boolString(bri) +",\"hue\":0,\"bri\":"+ briForHue(bri) +",\"sat\":0,\"xy\":[0.00000,0.00000],\"ct\":500,\"alert\":\"none\",\"effect\":\"none\",\"colormode\":\"hs\",\"reachable\":true},\"swversion\":\"0.1\",\"type\":\"Extended color light\",\"uniqueid\":\"2\"}");
|
||||
|
||||
return true;
|
||||
}
|
||||
if (req.indexOf("lights") > 0) //client wants all lights
|
||||
{
|
||||
DEBUG_PRINTLN("lAll");
|
||||
server.send(200, "application/json", "{\"1\":{\"type\":\"Extended color light\",\"manufacturername\":\"OpenSource\",\"swversion\":\"0.1\",\"name\":\""+ alexaInvocationName +"\",\"uniqueid\":\""+ WiFi.macAddress() +"-2\",\"modelid\":\"LST001\",\"state\":{\"on\":"+ boolString(bri) +",\"bri\":"+ briForHue(bri) +",\"xy\":[0.00000,0.00000],\"colormode\":\"hs\",\"effect\":\"none\",\"ct\":500,\"hue\":0,\"sat\":0,\"alert\":\"none\",\"reachable\":true}}}");
|
||||
return true;
|
||||
}
|
||||
|
||||
//we dont care about other api commands at this time and send empty JSON
|
||||
server.send(200, "application/json", "{}");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool connectUDP(){
|
||||
bool state = false;
|
||||
byte m = espalexaDevice->getLastChangedProperty();
|
||||
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINTLN("Con UDP");
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if(UDP.beginMulticast(ipMulti, portMulti))
|
||||
#else
|
||||
if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti))
|
||||
#endif
|
||||
if (m == 1){ //ON
|
||||
if (!macroAlexaOn)
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
bri = briLast;
|
||||
colorUpdated(10);
|
||||
}
|
||||
} else applyMacro(macroAlexaOn);
|
||||
} else if (m == 2) //OFF
|
||||
{
|
||||
DEBUG_PRINTLN("Con success");
|
||||
state = true;
|
||||
if (!macroAlexaOff)
|
||||
{
|
||||
if (bri > 0)
|
||||
{
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
colorUpdated(10);
|
||||
}
|
||||
} else applyMacro(macroAlexaOff);
|
||||
} else if (m == 3) //brightness
|
||||
{
|
||||
bri = b;
|
||||
colorUpdated(10);
|
||||
} else //color
|
||||
{
|
||||
col[0] = ((color >> 16) & 0xFF);
|
||||
col[1] = ((color >> 8) & 0xFF);
|
||||
col[2] = (color & 0xFF);
|
||||
if (useRGBW) colorRGBtoRGBW(col);
|
||||
colorUpdated(10);
|
||||
}
|
||||
else{
|
||||
DEBUG_PRINTLN("Con failed");
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
void alexaInit(){}
|
||||
void handleAlexa(){}
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* Support for the Cronixie clock
|
||||
*/
|
||||
byte getSameCodeLength(char code, int index, char const digits[])
|
||||
byte getSameCodeLength(char code, int index, char const cronixieDisplay[])
|
||||
{
|
||||
byte counter = 0;
|
||||
|
||||
for (int i = index+1; i < 6; i++)
|
||||
{
|
||||
if (digits[i] == code)
|
||||
if (cronixieDisplay[i] == code)
|
||||
{
|
||||
counter++;
|
||||
} else {
|
||||
@@ -19,7 +19,7 @@ byte getSameCodeLength(char code, int index, char const digits[])
|
||||
|
||||
void setCronixie()
|
||||
{
|
||||
char digits[6]; for (int a=0;a<6;a++) digits[a]=cronixieDisplay.charAt(a);
|
||||
#ifndef WLED_DISABLE_CRONIXIE
|
||||
/*
|
||||
* digit purpose index
|
||||
* 0-9 | 0-9 (incl. random)
|
||||
@@ -84,14 +84,14 @@ void setCronixie()
|
||||
//D Day of Week | DD Day Of Month | DDD Day Of Year
|
||||
|
||||
DEBUG_PRINT("cset ");
|
||||
DEBUG_PRINTLN(digits);
|
||||
DEBUG_PRINTLN(cronixieDisplay);
|
||||
|
||||
overlayRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
dP[i] = 10;
|
||||
switch (digits[i])
|
||||
switch (cronixieDisplay[i])
|
||||
{
|
||||
case '_': dP[i] = 10; break;
|
||||
case '-': dP[i] = 11; break;
|
||||
@@ -99,24 +99,24 @@ void setCronixie()
|
||||
case 'R': dP[i] = random(0,10); break; //random btw. 0-9
|
||||
case 't': break; //Test upw.
|
||||
case 'T': break; //Test dnw.
|
||||
case 'b': dP[i] = 14 + getSameCodeLength('b',i,digits); i = i+dP[i]-14; break;
|
||||
case 'B': dP[i] = 14 + getSameCodeLength('B',i,digits); i = i+dP[i]-14; break;
|
||||
case 'h': dP[i] = 70 + getSameCodeLength('h',i,digits); i = i+dP[i]-70; break;
|
||||
case 'H': dP[i] = 20 + getSameCodeLength('H',i,digits); i = i+dP[i]-20; break;
|
||||
case 'b': dP[i] = 14 + getSameCodeLength('b',i,cronixieDisplay); i = i+dP[i]-14; break;
|
||||
case 'B': dP[i] = 14 + getSameCodeLength('B',i,cronixieDisplay); i = i+dP[i]-14; break;
|
||||
case 'h': dP[i] = 70 + getSameCodeLength('h',i,cronixieDisplay); i = i+dP[i]-70; break;
|
||||
case 'H': dP[i] = 20 + getSameCodeLength('H',i,cronixieDisplay); i = i+dP[i]-20; break;
|
||||
case 'A': dP[i] = 108; i++; break;
|
||||
case 'a': dP[i] = 58; i++; break;
|
||||
case 'm': dP[i] = 74 + getSameCodeLength('m',i,digits); i = i+dP[i]-74; break;
|
||||
case 'M': dP[i] = 24 + getSameCodeLength('M',i,digits); i = i+dP[i]-24; break;
|
||||
case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs
|
||||
case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; overlayRefreshMs = 497; break;
|
||||
case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,digits); i = i+dP[i]-36; break;
|
||||
case 'y': dP[i] = 86 + getSameCodeLength('y',i,digits); i = i+dP[i]-86; break;
|
||||
case 'I': dP[i] = 39 + getSameCodeLength('I',i,digits); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M.
|
||||
case 'i': dP[i] = 89 + getSameCodeLength('i',i,digits); i = i+dP[i]-89; break;
|
||||
case 'm': dP[i] = 74 + getSameCodeLength('m',i,cronixieDisplay); i = i+dP[i]-74; break;
|
||||
case 'M': dP[i] = 24 + getSameCodeLength('M',i,cronixieDisplay); i = i+dP[i]-24; break;
|
||||
case 's': dP[i] = 80 + getSameCodeLength('s',i,cronixieDisplay); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs
|
||||
case 'S': dP[i] = 30 + getSameCodeLength('S',i,cronixieDisplay); i = i+dP[i]-30; overlayRefreshMs = 497; break;
|
||||
case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,cronixieDisplay); i = i+dP[i]-36; break;
|
||||
case 'y': dP[i] = 86 + getSameCodeLength('y',i,cronixieDisplay); i = i+dP[i]-86; break;
|
||||
case 'I': dP[i] = 39 + getSameCodeLength('I',i,cronixieDisplay); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M.
|
||||
case 'i': dP[i] = 89 + getSameCodeLength('i',i,cronixieDisplay); i = i+dP[i]-89; break;
|
||||
case 'W': break;
|
||||
case 'w': break;
|
||||
case 'D': dP[i] = 43 + getSameCodeLength('D',i,digits); i = i+dP[i]-43; break;
|
||||
case 'd': dP[i] = 93 + getSameCodeLength('d',i,digits); i = i+dP[i]-93; break;
|
||||
case 'D': dP[i] = 43 + getSameCodeLength('D',i,cronixieDisplay); i = i+dP[i]-43; break;
|
||||
case 'd': dP[i] = 93 + getSameCodeLength('d',i,cronixieDisplay); i = i+dP[i]-93; break;
|
||||
case '0': dP[i] = 0; break;
|
||||
case '1': dP[i] = 1; break;
|
||||
case '2': dP[i] = 2; break;
|
||||
@@ -140,73 +140,77 @@ void setCronixie()
|
||||
DEBUG_PRINTLN((int)dP[5]);
|
||||
|
||||
_overlayCronixie(); //refresh
|
||||
#endif
|
||||
}
|
||||
|
||||
void _overlayCronixie()
|
||||
{
|
||||
if (countdownMode) checkCountdown();
|
||||
byte h = hour(local);
|
||||
byte h0 = h;
|
||||
byte m = minute(local);
|
||||
byte s = second(local);
|
||||
byte d = day(local);
|
||||
byte mi = month(local);
|
||||
int y = year(local);
|
||||
//this has to be changed in time for 22nd century
|
||||
y -= 2000; if (y<0) y += 30; //makes countdown work
|
||||
if (countdownMode) checkCountdown();
|
||||
#ifndef WLED_DISABLE_CRONIXIE
|
||||
|
||||
byte h = hour(local);
|
||||
byte h0 = h;
|
||||
byte m = minute(local);
|
||||
byte s = second(local);
|
||||
byte d = day(local);
|
||||
byte mi = month(local);
|
||||
int y = year(local);
|
||||
//this has to be changed in time for 22nd century
|
||||
y -= 2000; if (y<0) y += 30; //makes countdown work
|
||||
|
||||
if (useAMPM && !countdownMode)
|
||||
{
|
||||
if (h>12) h-=12;
|
||||
else if (h==0) h+=12;
|
||||
}
|
||||
byte _digitOut[]{10,10,10,10,10,10};
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (dP[i] < 12) _digitOut[i] = dP[i];
|
||||
else {
|
||||
if (dP[i] < 65)
|
||||
if (useAMPM && !countdownMode)
|
||||
{
|
||||
if (h>12) h-=12;
|
||||
else if (h==0) h+=12;
|
||||
}
|
||||
byte _digitOut[]{10,10,10,10,10,10};
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (dP[i] < 12) _digitOut[i] = dP[i];
|
||||
else {
|
||||
if (dP[i] < 65)
|
||||
{
|
||||
switch(dP[i])
|
||||
{
|
||||
switch(dP[i])
|
||||
{
|
||||
case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH
|
||||
case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM
|
||||
case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS
|
||||
case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH
|
||||
case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM
|
||||
case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS
|
||||
|
||||
case 20: _digitOut[i] = h- (h/10)*10; break; //H
|
||||
case 24: _digitOut[i] = m/10; break; //M
|
||||
case 30: _digitOut[i] = s/10; break; //S
|
||||
|
||||
case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D
|
||||
case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD
|
||||
case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II
|
||||
case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY
|
||||
case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY
|
||||
|
||||
case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI)
|
||||
case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB
|
||||
case 14: _digitOut[i] = (h0>11)?1:0; break; //B
|
||||
}
|
||||
} else
|
||||
case 20: _digitOut[i] = h- (h/10)*10; break; //H
|
||||
case 24: _digitOut[i] = m/10; break; //M
|
||||
case 30: _digitOut[i] = s/10; break; //S
|
||||
|
||||
case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D
|
||||
case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD
|
||||
case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II
|
||||
case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY
|
||||
case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY
|
||||
|
||||
case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI)
|
||||
case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB
|
||||
case 14: _digitOut[i] = (h0>11)?1:0; break; //B
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch(dP[i])
|
||||
{
|
||||
switch(dP[i])
|
||||
{
|
||||
case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh
|
||||
case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm
|
||||
case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss
|
||||
case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI)
|
||||
case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb
|
||||
case 64: _digitOut[i] = (h0>11)?1:10; break; //b
|
||||
case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh
|
||||
case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm
|
||||
case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss
|
||||
case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI)
|
||||
case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb
|
||||
case 64: _digitOut[i] = (h0>11)?1:10; break; //b
|
||||
|
||||
case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d
|
||||
case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd
|
||||
case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii
|
||||
case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy
|
||||
case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy
|
||||
}
|
||||
case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d
|
||||
case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd
|
||||
case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii
|
||||
case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy
|
||||
case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy
|
||||
}
|
||||
}
|
||||
}
|
||||
strip.setCronixieDigits(_digitOut);
|
||||
//strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time
|
||||
}
|
||||
strip.setCronixieDigits(_digitOut);
|
||||
//strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,34 +1,13 @@
|
||||
/*
|
||||
* Color conversion methods
|
||||
*/
|
||||
void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb
|
||||
|
||||
void colorFromUint32(uint32_t in)
|
||||
{
|
||||
//this is only an approximation using WS2812B with gamma correction enabled
|
||||
if (mired > 475)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
|
||||
} else if (mired > 425)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
|
||||
} else if (mired > 375)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
|
||||
} else if (mired > 325)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
|
||||
} else if (mired > 275)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
|
||||
} else if (mired > 225)
|
||||
{
|
||||
rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
|
||||
} else if (mired > 175)
|
||||
{
|
||||
rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
|
||||
} else
|
||||
{
|
||||
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
|
||||
}
|
||||
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
|
||||
@@ -50,6 +29,29 @@ void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WLED_DISABLE_HUESYNC
|
||||
void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb
|
||||
{
|
||||
//this is only an approximation using WS2812B with gamma correction enabled
|
||||
if (mired > 475) {
|
||||
rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
|
||||
} else if (mired > 425) {
|
||||
rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
|
||||
} else if (mired > 375) {
|
||||
rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
|
||||
} else if (mired > 325) {
|
||||
rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
|
||||
} else if (mired > 275) {
|
||||
rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
|
||||
} else if (mired > 225) {
|
||||
rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
|
||||
} else if (mired > 175) {
|
||||
rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
|
||||
} else {
|
||||
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
|
||||
}
|
||||
}
|
||||
|
||||
void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
||||
{
|
||||
float z = 1.0f - x - y;
|
||||
@@ -59,20 +61,20 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
|
||||
float g = (int)255*(-X * 0.707196f + 1.655397f + Z * 0.036152f);
|
||||
float b = (int)255*(X * 0.051713f - 0.121364f + Z * 1.011530f);
|
||||
if (r > b && r > g && r > 1.0f) {
|
||||
// red is too big
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0f;
|
||||
// red is too big
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0f;
|
||||
} else if (g > b && g > r && g > 1.0f) {
|
||||
// green is too big
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0f;
|
||||
// green is too big
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0f;
|
||||
} else if (b > r && b > g && b > 1.0f) {
|
||||
// blue is too big
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0f;
|
||||
// blue is too big
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0f;
|
||||
}
|
||||
// Apply gamma correction
|
||||
r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f;
|
||||
@@ -80,26 +82,26 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
|
||||
b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f;
|
||||
|
||||
if (r > b && r > g) {
|
||||
// red is biggest
|
||||
if (r > 1.0f) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0f;
|
||||
}
|
||||
// red is biggest
|
||||
if (r > 1.0f) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0f;
|
||||
}
|
||||
} else if (g > b && g > r) {
|
||||
// green is biggest
|
||||
if (g > 1.0f) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0f;
|
||||
}
|
||||
// green is biggest
|
||||
if (g > 1.0f) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0f;
|
||||
}
|
||||
} else if (b > r && b > g) {
|
||||
// blue is biggest
|
||||
if (b > 1.0f) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0f;
|
||||
}
|
||||
// blue is biggest
|
||||
if (b > 1.0f) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0f;
|
||||
}
|
||||
}
|
||||
rgb[0] = 255.0*r;
|
||||
rgb[1] = 255.0*g;
|
||||
@@ -114,8 +116,27 @@ void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.develo
|
||||
xy[0] = X / (X + Y + Z);
|
||||
xy[1] = Y / (X + Y + Z);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*//For some reason min and max are not declared here
|
||||
void colorFromDecOrHexString(byte* rgb, char* in)
|
||||
{
|
||||
if (in[0] == 0) return;
|
||||
char first = in[0];
|
||||
uint32_t c = 0;
|
||||
|
||||
if (first == '#' || first == 'h' || first == 'H') //is HEX encoded
|
||||
{
|
||||
c = strtoul(in +1, NULL, 16);
|
||||
} else
|
||||
{
|
||||
c = strtoul(in, NULL, 10);
|
||||
}
|
||||
|
||||
rgb[3] = (c >> 24) & 0xFF;
|
||||
rgb[0] = (c >> 16) & 0xFF;
|
||||
rgb[1] = (c >> 8) & 0xFF;
|
||||
rgb[2] = c & 0xFF;
|
||||
}
|
||||
|
||||
float minf (float v, float w)
|
||||
{
|
||||
@@ -129,11 +150,11 @@ float maxf (float v, float w)
|
||||
return v;
|
||||
}
|
||||
|
||||
void colorRGBtoRGBW(byte* rgb, byte* wht) //rgb to rgbw, untested and currently unused
|
||||
void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw)
|
||||
{
|
||||
*wht = (float)minf(rgb[0],minf(rgb[1],rgb[2]))*0.95;
|
||||
rgb[0]-=wht;
|
||||
rgb[1]-=wht;
|
||||
rgb[2]-=wht;
|
||||
}*/
|
||||
|
||||
float low = minf(rgb[0],minf(rgb[1],rgb[2]));
|
||||
float high = maxf(rgb[0],maxf(rgb[1],rgb[2]));
|
||||
if (high < 0.1f) return;
|
||||
float sat = 255.0f * ((high - low) / high);
|
||||
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Sync to Philips hue lights
|
||||
*/
|
||||
|
||||
#ifndef WLED_DISABLE_HUESYNC
|
||||
void handleHue()
|
||||
{
|
||||
if (huePollingEnabled && WiFi.status() == WL_CONNECTED)
|
||||
if (huePollingEnabled && WiFi.status() == WL_CONNECTED && hueClient != NULL)
|
||||
{
|
||||
if (millis() - hueLastRequestSent > huePollIntervalMsTemp)
|
||||
{
|
||||
@@ -17,18 +17,18 @@ bool setupHue()
|
||||
{
|
||||
if (WiFi.status() == WL_CONNECTED) //setup needed
|
||||
{
|
||||
if (hueApiKey.length()>20) //api key is probably ok
|
||||
if (strlen(hueApiKey)>20) //api key is probably ok
|
||||
{
|
||||
if (sendHuePoll(false))
|
||||
{
|
||||
huePollingEnabled = true;
|
||||
return true;
|
||||
}
|
||||
if (hueError.charAt(0) == 'R' || hueError.charAt(0) == 'I') return false; //can't connect
|
||||
if (hueError[0] == 'R' || hueError[0] == 'I') return false; //can't connect
|
||||
delay(20);
|
||||
}
|
||||
sendHuePoll(true); //new API key
|
||||
if (hueError.charAt(0) != 'C') return false; //still some error
|
||||
if (hueError[0] != 'C') return false; //still some error
|
||||
delay(20);
|
||||
if (sendHuePoll(false))
|
||||
{
|
||||
@@ -44,8 +44,8 @@ bool setupHue()
|
||||
bool sendHuePoll(bool sAuth)
|
||||
{
|
||||
bool st;
|
||||
hueClient.setReuse(true);
|
||||
hueClient.setTimeout(450);
|
||||
hueClient->setReuse(true);
|
||||
hueClient->setTimeout(450);
|
||||
String hueURL = "http://";
|
||||
hueURL += hueIP.toString();
|
||||
hueURL += "/api/";
|
||||
@@ -53,14 +53,14 @@ bool sendHuePoll(bool sAuth)
|
||||
hueURL += hueApiKey;
|
||||
hueURL += "/lights/" + String(huePollLightId);
|
||||
}
|
||||
hueClient.begin(hueURL);
|
||||
int httpCode = (sAuth)? hueClient.POST("{\"devicetype\":\"wled#esp\"}"):hueClient.GET();
|
||||
hueClient->begin(hueURL);
|
||||
int httpCode = (sAuth)? hueClient->POST("{\"devicetype\":\"wled#esp\"}"):hueClient->GET();
|
||||
//TODO this request may block operation for ages
|
||||
|
||||
if (httpCode>0){
|
||||
st = handleHueResponse(hueClient.getString(),sAuth);
|
||||
st = handleHueResponse(hueClient->getString(),sAuth);
|
||||
} else {
|
||||
hueError = "Request timed out";
|
||||
strcpy(hueError,"Request timed out");
|
||||
st = false;
|
||||
}
|
||||
if (!st){ //error
|
||||
@@ -81,10 +81,13 @@ bool handleHueResponse(String hueResp, bool isAuth)
|
||||
int hueErrorCode = getJsonValue(&hueResp,"type").toInt();
|
||||
switch (hueErrorCode)
|
||||
{
|
||||
case 1: hueError = "Unauthorized"; break;
|
||||
case 3: hueError = "Invalid light ID"; break;
|
||||
case 101: hueError = "Link button not pressed"; break;
|
||||
default: hueError = "Bridge Error " + String(hueErrorCode);
|
||||
case 1: strcpy(hueError,"Unauthorized"); break;
|
||||
case 3: strcpy(hueError,"Invalid light ID"); break;
|
||||
case 101: strcpy(hueError,"Link button not pressed"); break;
|
||||
default:
|
||||
char coerr[18];
|
||||
sprintf(coerr,"Bridge Error %i",hueErrorCode);
|
||||
strcpy(hueError,coerr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -94,10 +97,10 @@ bool handleHueResponse(String hueResp, bool isAuth)
|
||||
String tempApi = getJsonValue(&hueResp,"username");
|
||||
if (tempApi.length()>0)
|
||||
{
|
||||
hueApiKey = tempApi;
|
||||
strcpy(hueApiKey,tempApi.c_str());
|
||||
return true;
|
||||
}
|
||||
hueError = "Invalid response";
|
||||
strcpy(hueError,"Invalid response");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -157,7 +160,7 @@ bool handleHueResponse(String hueResp, bool isAuth)
|
||||
}
|
||||
hueFailCount = 0;
|
||||
huePollIntervalMsTemp = huePollIntervalMs;
|
||||
hueError = "Connected";
|
||||
strcpy(hueError,"Connected");
|
||||
//applying vals
|
||||
if (hueBri != hueBriLast)
|
||||
{
|
||||
@@ -203,4 +206,7 @@ String getJsonValue(String* req, String key)
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
#else
|
||||
void handleHue(){}
|
||||
bool setupHue(){return false;}
|
||||
#endif
|
||||
|
||||
93
wled00/wled16_blynk.ino
Normal file
93
wled00/wled16_blynk.ino
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Remote light control with the free Blynk app
|
||||
*/
|
||||
|
||||
uint16_t blHue = 0;
|
||||
byte blSat = 255;
|
||||
|
||||
void initBlynk(const char* auth)
|
||||
{
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
if (WiFi.status() != WL_CONNECTED) return;
|
||||
blynkEnabled = (auth[0] != 0);
|
||||
if (blynkEnabled) Blynk.config(auth);
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleBlynk()
|
||||
{
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
if (WiFi.status() == WL_CONNECTED && blynkEnabled)
|
||||
Blynk.run();
|
||||
#endif
|
||||
}
|
||||
|
||||
void updateBlynk()
|
||||
{
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
if (onlyAP) return;
|
||||
Blynk.virtualWrite(V0, bri);
|
||||
//we need a RGB -> HSB convert here
|
||||
Blynk.virtualWrite(V3, bri? 1:0);
|
||||
Blynk.virtualWrite(V4, effectCurrent);
|
||||
Blynk.virtualWrite(V5, effectSpeed);
|
||||
Blynk.virtualWrite(V6, effectIntensity);
|
||||
Blynk.virtualWrite(V7, nightlightActive);
|
||||
Blynk.virtualWrite(V8, notifyDirect);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef WLED_DISABLE_BLYNK
|
||||
BLYNK_WRITE(V0)
|
||||
{
|
||||
bri = param.asInt();//bri
|
||||
colorUpdated(9);
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V1)
|
||||
{
|
||||
blHue = param.asInt();//hue
|
||||
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
|
||||
colorUpdated(9);
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V2)
|
||||
{
|
||||
blSat = param.asInt();//sat
|
||||
colorHStoRGB(blHue*10,blSat,(false)? colSec:col);
|
||||
colorUpdated(9);
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V3)
|
||||
{
|
||||
handleSet((param.asInt()>0)?"win&T=1&IN":"win&T=0&IN");//power
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V4)
|
||||
{
|
||||
effectCurrent = param.asInt()-1;//fx
|
||||
colorUpdated(9);
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V5)
|
||||
{
|
||||
effectSpeed = param.asInt();//sx
|
||||
colorUpdated(9);
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V6)
|
||||
{
|
||||
effectIntensity = param.asInt();//ix
|
||||
colorUpdated(9);
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V7)
|
||||
{
|
||||
handleSet((param.asInt()>0)?"win&ND&IN":"win&NL=0&IN");//nl
|
||||
}
|
||||
|
||||
BLYNK_WRITE(V8)
|
||||
{
|
||||
notifyDirect = (param.asInt()>0); //send notifications
|
||||
}
|
||||
#endif
|
||||
145
wled00/wled17_mqtt.ino
Normal file
145
wled00/wled17_mqtt.ino
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* MQTT communication protocol for home automation
|
||||
*/
|
||||
|
||||
#define WLED_MQTT_PORT 1883
|
||||
|
||||
void parseMQTTBriPayload(char* payload)
|
||||
{
|
||||
if (strcmp(payload, "ON") == 0) {bri = briLast; colorUpdated(1);}
|
||||
else if (strcmp(payload, "T" ) == 0) {toggleOnOff(); colorUpdated(1);}
|
||||
else {
|
||||
uint8_t in = strtoul(payload, NULL, 10);
|
||||
if (in == 0 && bri > 0) briLast = bri;
|
||||
bri = in;
|
||||
colorUpdated(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void callbackMQTT(char* topic, byte* payload, unsigned int length) {
|
||||
|
||||
DEBUG_PRINT("MQTT callb rec: ");
|
||||
DEBUG_PRINTLN(topic);
|
||||
DEBUG_PRINTLN((char*)payload);
|
||||
|
||||
//no need to check the topic because we only get topics we are subscribed to
|
||||
|
||||
if (strstr(topic, "/col"))
|
||||
{
|
||||
colorFromDecOrHexString(col, (char*)payload);
|
||||
colorUpdated(1);
|
||||
} else if (strstr(topic, "/api"))
|
||||
{
|
||||
String apireq = "win&";
|
||||
apireq += (char*)payload;
|
||||
handleSet(apireq);
|
||||
} else
|
||||
{
|
||||
parseMQTTBriPayload((char*)payload);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void publishMQTT()
|
||||
{
|
||||
if (mqtt == NULL) return;
|
||||
if (!mqtt->connected()) return;
|
||||
DEBUG_PRINTLN("Publish MQTT");
|
||||
|
||||
char s[10];
|
||||
char subuf[38];
|
||||
|
||||
sprintf(s, "%ld", bri);
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/g");
|
||||
mqtt->publish(subuf, s);
|
||||
|
||||
sprintf(s, "#%X", col[3]*16777216 + col[0]*65536 + col[1]*256 + col[2]);
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/c");
|
||||
mqtt->publish(subuf, s);
|
||||
|
||||
//if you want to use this, increase the MQTT buffer in PubSubClient.h to 350+
|
||||
//it will publish the API response to MQTT
|
||||
/*XML_response(false, false);
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/v");
|
||||
mqtt->publish(subuf, obuf);*/
|
||||
}
|
||||
|
||||
|
||||
bool reconnectMQTT()
|
||||
{
|
||||
if (mqtt->connect(escapedMac.c_str()))
|
||||
{
|
||||
//re-subscribe to required topics
|
||||
char subuf[38];
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
|
||||
if (mqttDeviceTopic[0] != 0)
|
||||
{
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
mqtt->subscribe(subuf);
|
||||
strcat(subuf, "/col");
|
||||
mqtt->subscribe(subuf);
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/api");
|
||||
mqtt->subscribe(subuf);
|
||||
}
|
||||
|
||||
if (mqttGroupTopic[0] != 0)
|
||||
{
|
||||
strcpy(subuf, mqttGroupTopic);
|
||||
mqtt->subscribe(subuf);
|
||||
strcat(subuf, "/col");
|
||||
mqtt->subscribe(subuf);
|
||||
strcpy(subuf, mqttGroupTopic);
|
||||
strcat(subuf, "/api");
|
||||
mqtt->subscribe(subuf);
|
||||
}
|
||||
|
||||
publishMQTT();
|
||||
}
|
||||
return mqtt->connected();
|
||||
}
|
||||
|
||||
|
||||
bool initMQTT()
|
||||
{
|
||||
if (WiFi.status() != WL_CONNECTED) return false;
|
||||
if (mqttServer[0] == 0) return false;
|
||||
|
||||
IPAddress mqttIP;
|
||||
if (mqttIP.fromString(mqttServer)) //see if server is IP or domain
|
||||
{
|
||||
mqtt->setServer(mqttIP, WLED_MQTT_PORT);
|
||||
} else {
|
||||
mqtt->setServer(mqttServer, WLED_MQTT_PORT);
|
||||
}
|
||||
mqtt->setCallback(callbackMQTT);
|
||||
DEBUG_PRINTLN("MQTT ready.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void handleMQTT()
|
||||
{
|
||||
if (WiFi.status() != WL_CONNECTED || !mqttInit) return;
|
||||
|
||||
//every time connection is unsuccessful, the attempt interval is increased, since attempt will block program for 7 sec each time
|
||||
if (!mqtt->connected() && millis() - lastMQTTReconnectAttempt > 5000 + (5000 * mqttFailedConAttempts * mqttFailedConAttempts))
|
||||
{
|
||||
DEBUG_PRINTLN("Attempting to connect MQTT...");
|
||||
lastMQTTReconnectAttempt = millis();
|
||||
if (!reconnectMQTT())
|
||||
{
|
||||
//still attempt reconnect about once daily
|
||||
if (mqttFailedConAttempts < 120) mqttFailedConAttempts++;
|
||||
return;
|
||||
}
|
||||
DEBUG_PRINTLN("MQTT con!");
|
||||
mqttFailedConAttempts = 0;
|
||||
}
|
||||
mqtt->loop();
|
||||
}
|
||||
390
wled00/wled18_server.ino
Normal file
390
wled00/wled18_server.ino
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Server page definitions
|
||||
*/
|
||||
|
||||
void initServer()
|
||||
{
|
||||
//settings page
|
||||
server.on("/settings", HTTP_GET, [](){
|
||||
serveSettings(0);
|
||||
});
|
||||
server.on("/settings/wifi", HTTP_GET, [](){
|
||||
if (!(wifiLock && otaLock))
|
||||
{
|
||||
serveSettings(1);
|
||||
}else{
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
}
|
||||
});
|
||||
server.on("/settings/leds", HTTP_GET, [](){
|
||||
serveSettings(2);
|
||||
});
|
||||
server.on("/settings/ui", HTTP_GET, [](){
|
||||
serveSettings(3);
|
||||
});
|
||||
server.on("/settings/sync", HTTP_GET, [](){
|
||||
serveSettings(4);
|
||||
});
|
||||
server.on("/settings/time", HTTP_GET, [](){
|
||||
serveSettings(5);
|
||||
});
|
||||
server.on("/settings/sec", HTTP_GET, [](){
|
||||
serveSettings(6);
|
||||
});
|
||||
|
||||
server.on("/favicon.ico", HTTP_GET, [](){
|
||||
if(!handleFileRead("/favicon.ico"))
|
||||
{
|
||||
server.send_P(200, "image/x-icon", favicon, 156);
|
||||
}
|
||||
});
|
||||
|
||||
server.on("/sliders", HTTP_GET, serveIndex);
|
||||
|
||||
server.on("/welcome", HTTP_GET, [](){
|
||||
serveSettings(255);
|
||||
});
|
||||
|
||||
server.on("/reset", HTTP_GET, [](){
|
||||
serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",79);
|
||||
reset();
|
||||
});
|
||||
|
||||
server.on("/settings/wifi", HTTP_POST, [](){
|
||||
if (!(wifiLock && otaLock)) handleSettingsSet(1);
|
||||
serveMessage(200,"WiFi settings saved.","Rebooting now...",255);
|
||||
reset();
|
||||
});
|
||||
|
||||
server.on("/settings/leds", HTTP_POST, [](){
|
||||
handleSettingsSet(2);
|
||||
serveMessage(200,"LED settings saved.","Redirecting...",1);
|
||||
});
|
||||
|
||||
server.on("/settings/ui", HTTP_POST, [](){
|
||||
handleSettingsSet(3);
|
||||
serveMessage(200,"UI settings saved.","Reloading to apply theme...",122);
|
||||
});
|
||||
|
||||
server.on("/settings/sync", HTTP_POST, [](){
|
||||
handleSettingsSet(4);
|
||||
if (hueAttempt)
|
||||
{
|
||||
serveMessage(200,"Hue setup result",hueError,253);
|
||||
} else {
|
||||
serveMessage(200,"Sync settings saved.","Redirecting...",1);
|
||||
}
|
||||
hueAttempt = false;
|
||||
});
|
||||
|
||||
server.on("/settings/time", HTTP_POST, [](){
|
||||
handleSettingsSet(5);
|
||||
serveMessage(200,"Time settings saved.","Redirecting...",1);
|
||||
});
|
||||
|
||||
server.on("/settings/sec", HTTP_POST, [](){
|
||||
handleSettingsSet(6);
|
||||
serveMessage(200,"Security settings saved.","Rebooting now... (takes ~20 seconds, wait for auto-redirect)",139);
|
||||
reset();
|
||||
});
|
||||
|
||||
server.on("/json", HTTP_ANY, [](){
|
||||
server.send(500, "application/json", "{\"error\":\"Not implemented\"}");
|
||||
});
|
||||
|
||||
server.on("/json/effects", HTTP_GET, [](){
|
||||
server.setContentLength(strlen_P(JSON_mode_names));
|
||||
server.send(200, "application/json", "");
|
||||
server.sendContent_P(JSON_mode_names);
|
||||
});
|
||||
|
||||
server.on("/json/palettes", HTTP_GET, [](){
|
||||
server.setContentLength(strlen_P(JSON_palette_names));
|
||||
server.send(200, "application/json", "");
|
||||
server.sendContent_P(JSON_palette_names);
|
||||
});
|
||||
|
||||
server.on("/version", HTTP_GET, [](){
|
||||
server.send(200, "text/plain", (String)VERSION);
|
||||
});
|
||||
|
||||
server.on("/uptime", HTTP_GET, [](){
|
||||
server.send(200, "text/plain", (String)millis());
|
||||
});
|
||||
|
||||
server.on("/freeheap", HTTP_GET, [](){
|
||||
server.send(200, "text/plain", (String)ESP.getFreeHeap());
|
||||
});
|
||||
|
||||
server.on("/power", HTTP_GET, [](){
|
||||
String val = "";
|
||||
if (strip.currentMilliamps == 0)
|
||||
{
|
||||
val = "Power calculation disabled";
|
||||
} else
|
||||
{
|
||||
val += (String)strip.currentMilliamps;
|
||||
val += "mA currently";
|
||||
}
|
||||
serveMessage(200, val, "This is just an estimate (does not account for factors like wire resistance). It is NOT a measurement!", 254);
|
||||
});
|
||||
|
||||
server.on("/u", HTTP_GET, [](){
|
||||
server.setContentLength(strlen_P(PAGE_usermod));
|
||||
server.send(200, "text/html", "");
|
||||
server.sendContent_P(PAGE_usermod);
|
||||
});
|
||||
|
||||
server.on("/teapot", HTTP_GET, [](){
|
||||
serveMessage(418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254);
|
||||
});
|
||||
|
||||
server.on("/build", HTTP_GET, [](){
|
||||
getBuildInfo();
|
||||
server.send(200, "text/plain", obuf);
|
||||
});
|
||||
//if OTA is allowed
|
||||
if (!otaLock){
|
||||
server.on("/edit", HTTP_GET, [](){
|
||||
server.send(200, "text/html", PAGE_edit);
|
||||
});
|
||||
#ifdef USEFS
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
#endif
|
||||
//init ota page
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
httpUpdater.setup(&server);
|
||||
#else
|
||||
server.on("/update", HTTP_GET, [](){
|
||||
serveMessage(500, "Not implemented", "OTA updates are unsupported in this build.", 254);
|
||||
});
|
||||
#endif
|
||||
} else
|
||||
{
|
||||
server.on("/edit", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
server.on("/update", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
server.on("/list", HTTP_GET, [](){
|
||||
serveMessage(500, "Access Denied", txd, 254);
|
||||
});
|
||||
}
|
||||
|
||||
//this ceased working somehow
|
||||
/*server.on("/", HTTP_GET, [](){
|
||||
serveIndexOrWelcome();
|
||||
});*/
|
||||
|
||||
//called when the url is not defined here, ajax-in; get-settings
|
||||
server.onNotFound([](){
|
||||
DEBUG_PRINTLN("Not-Found HTTP call:");
|
||||
DEBUG_PRINTLN("URI: " + server.uri());
|
||||
DEBUG_PRINTLN("Body: " + server.arg(0));
|
||||
|
||||
//make API CORS compatible
|
||||
if (server.method() == HTTP_OPTIONS)
|
||||
{
|
||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||
server.sendHeader("Access-Control-Max-Age", "10000");
|
||||
server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS");
|
||||
server.sendHeader("Access-Control-Allow-Headers", "*");
|
||||
server.send(200);
|
||||
return;
|
||||
}
|
||||
|
||||
//workaround for subpage issue
|
||||
if (server.uri().length() == 1)
|
||||
{
|
||||
serveIndexOrWelcome();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!handleSet(server.uri())){
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
if(!espalexa.handleAlexaApiCall(server.uri(),server.arg(0)))
|
||||
#endif
|
||||
server.send(404, "text/plain", "Not Found");
|
||||
}
|
||||
});
|
||||
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
const char * headerkeys[] = {"User-Agent"};
|
||||
server.collectHeaders(headerkeys,sizeof(headerkeys)/sizeof(char*));
|
||||
#else
|
||||
String ua = "User-Agent";
|
||||
server.collectHeaders(ua);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void serveIndexOrWelcome()
|
||||
{
|
||||
if (!showWelcomePage){
|
||||
serveIndex();
|
||||
}else{
|
||||
serveSettings(255);
|
||||
}
|
||||
}
|
||||
|
||||
void serveRealtimeError(bool settings)
|
||||
{
|
||||
String mesg = "The ";
|
||||
mesg += (settings)?"settings":"WLED";
|
||||
mesg += " UI is not available while receiving real-time data (";
|
||||
if (realtimeIP[0] == 0)
|
||||
{
|
||||
mesg += "E1.31";
|
||||
} else {
|
||||
mesg += "UDP from ";
|
||||
mesg += realtimeIP[0];
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
mesg += ".";
|
||||
mesg += realtimeIP[i];
|
||||
}
|
||||
}
|
||||
mesg += ").";
|
||||
server.send(200, "text/plain", mesg);
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
bool serveMobile = false;
|
||||
if (uiConfiguration == 0) serveMobile = checkClientIsMobile(server.header("User-Agent"));
|
||||
else if (uiConfiguration == 2) serveMobile = true;
|
||||
|
||||
if (realtimeActive && !enableRealtimeUI) //do not serve while receiving realtime
|
||||
{
|
||||
serveRealtimeError(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//error message is not gzipped
|
||||
#ifdef WLED_DISABLE_MOBILE_UI
|
||||
if (!serveMobile) server.sendHeader("Content-Encoding","gzip");
|
||||
#else
|
||||
server.sendHeader("Content-Encoding","gzip");
|
||||
#endif
|
||||
|
||||
server.send_P(200, "text/html",
|
||||
(serveMobile) ? PAGE_indexM : PAGE_index0,
|
||||
(serveMobile) ? PAGE_indexM_L : PAGE_index0_L);
|
||||
}
|
||||
|
||||
|
||||
void serveMessage(int code, String headl, String subl="", int optionType)
|
||||
{
|
||||
olen = 0;
|
||||
getCSSColors();
|
||||
|
||||
String messageBody = "<h2>";
|
||||
messageBody += headl;
|
||||
messageBody += "</h2>";
|
||||
messageBody += subl;
|
||||
switch(optionType)
|
||||
{
|
||||
case 255: break; //simple message
|
||||
case 254: messageBody += "<br><br><button type=\"button\" onclick=\"B()\">Back</button>"; break; //back button
|
||||
case 253: messageBody += "<br><br><form action=/settings><button type=submit>Back</button></form>"; //button to settings
|
||||
}
|
||||
if (optionType < 60) //redirect to settings after optionType seconds
|
||||
{
|
||||
messageBody += "<script>setTimeout(RS," + String(optionType*1000) + ")</script>";
|
||||
} else if (optionType < 120) //redirect back after optionType-60 seconds
|
||||
{
|
||||
messageBody += "<script>setTimeout(B," + String((optionType-60)*1000) + ")</script>";
|
||||
} else if (optionType < 180) //reload parent after optionType-120 seconds
|
||||
{
|
||||
messageBody += "<script>setTimeout(RP," + String((optionType-120)*1000) + ")</script>";
|
||||
}
|
||||
messageBody += "</body></html>";
|
||||
server.setContentLength(strlen_P(PAGE_msg0) + olen + strlen_P(PAGE_msg1) + messageBody.length());
|
||||
server.send(code, "text/html", "");
|
||||
server.sendContent_P(PAGE_msg0);
|
||||
server.sendContent(obuf);
|
||||
server.sendContent_P(PAGE_msg1);
|
||||
server.sendContent(messageBody);
|
||||
}
|
||||
|
||||
|
||||
void serveSettings(byte subPage)
|
||||
{
|
||||
if (realtimeActive && !enableRealtimeUI) //do not serve while receiving realtime
|
||||
{
|
||||
serveRealtimeError(true);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage
|
||||
if (subPage == 255) {serveIndex(); return;}
|
||||
#endif
|
||||
|
||||
int pl0, pl1;
|
||||
switch (subPage) //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
|
||||
{
|
||||
case 1: pl0 = strlen_P(PAGE_settings_wifi0); pl1 = strlen_P(PAGE_settings_wifi1); break;
|
||||
case 2: pl0 = strlen_P(PAGE_settings_leds0); pl1 = strlen_P(PAGE_settings_leds1); break;
|
||||
case 3: pl0 = strlen_P(PAGE_settings_ui0); pl1 = strlen_P(PAGE_settings_ui1); break;
|
||||
case 4: pl0 = strlen_P(PAGE_settings_sync0); pl1 = strlen_P(PAGE_settings_sync1); break;
|
||||
case 5: pl0 = strlen_P(PAGE_settings_time0); pl1 = strlen_P(PAGE_settings_time1); break;
|
||||
case 6: pl0 = strlen_P(PAGE_settings_sec0); pl1 = strlen_P(PAGE_settings_sec1); break;
|
||||
case 255: pl0 = strlen_P(PAGE_welcome0); pl1 = strlen_P(PAGE_welcome1); break;
|
||||
default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1);
|
||||
}
|
||||
|
||||
uint16_t sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0;
|
||||
|
||||
getSettingsJS(subPage);
|
||||
|
||||
getCSSColors();
|
||||
|
||||
server.setContentLength(pl0 + olen + sCssLength + pl1);
|
||||
server.send(200, "text/html", "");
|
||||
|
||||
switch (subPage)
|
||||
{
|
||||
case 1: server.sendContent_P(PAGE_settings_wifi0); break;
|
||||
case 2: server.sendContent_P(PAGE_settings_leds0); break;
|
||||
case 3: server.sendContent_P(PAGE_settings_ui0 ); break;
|
||||
case 4: server.sendContent_P(PAGE_settings_sync0); break;
|
||||
case 5: server.sendContent_P(PAGE_settings_time0); break;
|
||||
case 6: server.sendContent_P(PAGE_settings_sec0 ); break;
|
||||
case 255: server.sendContent_P(PAGE_welcome0 ); break;
|
||||
default: server.sendContent_P(PAGE_settings0 );
|
||||
}
|
||||
server.sendContent(obuf);
|
||||
|
||||
if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss);
|
||||
switch (subPage)
|
||||
{
|
||||
case 1: server.sendContent_P(PAGE_settings_wifi1); break;
|
||||
case 2: server.sendContent_P(PAGE_settings_leds1); break;
|
||||
case 3: server.sendContent_P(PAGE_settings_ui1 ); break;
|
||||
case 4: server.sendContent_P(PAGE_settings_sync1); break;
|
||||
case 5: server.sendContent_P(PAGE_settings_time1); break;
|
||||
case 6: server.sendContent_P(PAGE_settings_sec1 ); break;
|
||||
case 255: server.sendContent_P(PAGE_welcome1 ); break;
|
||||
default: server.sendContent_P(PAGE_settings1 );
|
||||
}
|
||||
}
|
||||
155
wled00/wled19_ir.ino
Normal file
155
wled00/wled19_ir.ino
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Infrared sensor support for generic 24 key RGB remote
|
||||
*/
|
||||
|
||||
#if defined(WLED_DISABLE_INFRARED) || defined(ARDUINO_ARCH_ESP32)
|
||||
void handleIR(){}
|
||||
#else
|
||||
|
||||
IRrecv* irrecv;
|
||||
//change pin in NpbWrapper.h
|
||||
|
||||
decode_results results;
|
||||
|
||||
unsigned long irCheckedTime = 0;
|
||||
uint32_t lastValidCode = 0;
|
||||
uint16_t irTimesRepeated = 0;
|
||||
|
||||
|
||||
//Add what your custom IR codes should trigger here. Guide: https://github.com/Aircoookie/WLED/wiki/Infrared-Control
|
||||
//IR codes themselves can be defined directly after "case" or in "ir_codes.h"
|
||||
bool decodeIRCustom(uint32_t code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
//just examples, feel free to modify or remove
|
||||
case IRCUSTOM_ONOFF : toggleOnOff(); break;
|
||||
case IRCUSTOM_MACRO1 : applyMacro(1); break;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
if (code != IRCUSTOM_MACRO1) colorUpdated(2); //don't update color again if we apply macro, it already does it
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//relatively change brightness, minumum A=5
|
||||
void relativeChange(byte* property, int8_t amount, byte lowerBoundary =0)
|
||||
{
|
||||
int16_t new_val = (int16_t) *property + amount;
|
||||
if (new_val > 0xFF) new_val = 0xFF;
|
||||
else if (new_val < lowerBoundary) new_val = lowerBoundary;
|
||||
*property = new_val;
|
||||
}
|
||||
|
||||
|
||||
void decodeIR(uint32_t code)
|
||||
{
|
||||
if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down
|
||||
{
|
||||
irTimesRepeated++;
|
||||
if (lastValidCode == IR24_BRIGHTER)
|
||||
{
|
||||
relativeChange(&bri, 10); colorUpdated(2);
|
||||
}
|
||||
else if (lastValidCode == IR24_DARKER)
|
||||
{
|
||||
relativeChange(&bri, -10, 5); colorUpdated(2);
|
||||
}
|
||||
else if (lastValidCode == IR24_ON && irTimesRepeated > 7)
|
||||
{
|
||||
nightlightActive = true;
|
||||
nightlightStartTime = millis();
|
||||
colorUpdated(2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
lastValidCode = 0; irTimesRepeated = 0;
|
||||
|
||||
if (decodeIRCustom(code)) return;
|
||||
if (code > 0xFFFFFF) return; //invalid code
|
||||
else if (code > 0xFF0000) decodeIR44(code); //is in 44-key remote range
|
||||
else if (code > 0xF70000 && code < 0xF80000) decodeIR24(code); //is in 24-key remote range
|
||||
//code <= 0xF70000 also invalid
|
||||
}
|
||||
|
||||
|
||||
void decodeIR24(uint32_t code)
|
||||
{
|
||||
switch (code) {
|
||||
case IR24_BRIGHTER : relativeChange(&bri, 10); break;
|
||||
case IR24_DARKER : relativeChange(&bri, -10, 5); break;
|
||||
case IR24_OFF : briLast = bri; bri = 0; break;
|
||||
case IR24_ON : bri = briLast; break;
|
||||
case IR24_RED : colorFromUint32(COLOR_RED); break;
|
||||
case IR24_REDDISH : colorFromUint32(COLOR_REDDISH); break;
|
||||
case IR24_ORANGE : colorFromUint32(COLOR_ORANGE); break;
|
||||
case IR24_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break;
|
||||
case IR24_YELLOW : colorFromUint32(COLOR_YELLOW); break;
|
||||
case IR24_GREEN : colorFromUint32(COLOR_GREEN); break;
|
||||
case IR24_GREENISH : colorFromUint32(COLOR_GREENISH); break;
|
||||
case IR24_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break;
|
||||
case IR24_CYAN : colorFromUint32(COLOR_CYAN); break;
|
||||
case IR24_AQUA : colorFromUint32(COLOR_AQUA); break;
|
||||
case IR24_BLUE : colorFromUint32(COLOR_BLUE); break;
|
||||
case IR24_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break;
|
||||
case IR24_PURPLE : colorFromUint32(COLOR_PURPLE); break;
|
||||
case IR24_MAGENTA : colorFromUint32(COLOR_MAGENTA); break;
|
||||
case IR24_PINK : colorFromUint32(COLOR_PINK); break;
|
||||
case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break;
|
||||
case IR24_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break;
|
||||
case IR24_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break;
|
||||
case IR24_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break;
|
||||
case IR24_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break;
|
||||
default: return;
|
||||
}
|
||||
lastValidCode = code;
|
||||
colorUpdated(2); //for notifier, IR is considered a button input
|
||||
}
|
||||
|
||||
|
||||
void decodeIR44(uint32_t code)
|
||||
{
|
||||
//not implemented for now
|
||||
}
|
||||
|
||||
|
||||
void initIR()
|
||||
{
|
||||
if (irEnabled)
|
||||
{
|
||||
irrecv = new IRrecv(IR_PIN);
|
||||
irrecv->enableIRIn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleIR()
|
||||
{
|
||||
if (irEnabled && millis() - irCheckedTime > 120)
|
||||
{
|
||||
irCheckedTime = millis();
|
||||
if (irEnabled)
|
||||
{
|
||||
if (irrecv == NULL)
|
||||
{
|
||||
initIR(); return;
|
||||
}
|
||||
|
||||
if (irrecv->decode(&results))
|
||||
{
|
||||
Serial.print("IR recv\r\n0x");
|
||||
Serial.println((uint32_t)results.value, HEX);
|
||||
Serial.println();
|
||||
decodeIR(results.value);
|
||||
irrecv->resume();
|
||||
}
|
||||
} else if (irrecv != NULL)
|
||||
{
|
||||
irrecv->disableIRIn();
|
||||
delete irrecv; irrecv = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
BIN
wled_logo.png
Normal file
BIN
wled_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Reference in New Issue
Block a user