Compare commits
293 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c9bcb2445 | ||
|
|
c98c54bd6b | ||
|
|
f1810a9784 | ||
|
|
9526051766 | ||
|
|
bd435b175b | ||
|
|
42ab734256 | ||
|
|
77d89e7df3 | ||
|
|
6122a8371a | ||
|
|
4ffeb05120 | ||
|
|
310f55abb6 | ||
|
|
d6c0642a02 | ||
|
|
541556874f | ||
|
|
477d7080b8 | ||
|
|
173c752d62 | ||
|
|
3b70488828 | ||
|
|
334783f89a | ||
|
|
89a54e31f1 | ||
|
|
354d18f78e | ||
|
|
0e8806eb2b | ||
|
|
731550acb3 | ||
|
|
be4019b4d3 | ||
|
|
70ffcd9adf | ||
|
|
bbe511dd15 | ||
|
|
82d5ac91d7 | ||
|
|
54de0eab6a | ||
|
|
4d5bb274d1 | ||
|
|
131fae57e5 | ||
|
|
37da53c20e | ||
|
|
6ad57a15cf | ||
|
|
4729bce16c | ||
|
|
0b5ac7a139 | ||
|
|
677e23ad14 | ||
|
|
6d838e3043 | ||
|
|
f322abceb8 | ||
|
|
e754d21598 | ||
|
|
0fdd861ef1 | ||
|
|
2e5f6a3507 | ||
|
|
4e57cab0fa | ||
|
|
9930c8f94d | ||
|
|
f8e262b87e | ||
|
|
896bdaf124 | ||
|
|
2e4f2639a3 | ||
|
|
ce89a92d0d | ||
|
|
1d9d1f6bbd | ||
|
|
767b57fc01 | ||
|
|
9e00177d76 | ||
|
|
095429a7df | ||
|
|
983efd61fb | ||
|
|
e028316308 | ||
|
|
e1354accb8 | ||
|
|
ea726f928d | ||
|
|
6b419dbfc0 | ||
|
|
006a9eaf44 | ||
|
|
76117854c6 | ||
|
|
6eae6db46b | ||
|
|
3aacb7150d | ||
|
|
81298a1034 | ||
|
|
b3d728df91 | ||
|
|
6989b1730e | ||
|
|
1595542d59 | ||
|
|
fba9992a10 | ||
|
|
867dce2294 | ||
|
|
692554a899 | ||
|
|
f3cc616e07 | ||
|
|
e7a0874a57 | ||
|
|
1beb9c4bb8 | ||
|
|
6eef3a9037 | ||
|
|
ddaaae46a6 | ||
|
|
4e4773a370 | ||
|
|
f4a2ffc5d2 | ||
|
|
ba1117e10e | ||
|
|
0cd46f932a | ||
|
|
937f404583 | ||
|
|
d13d60d752 | ||
|
|
31e4e7c709 | ||
|
|
0d3a8ce31b | ||
|
|
be185b46a7 | ||
|
|
90fa5b3b93 | ||
|
|
733996772b | ||
|
|
d4c921ea2e | ||
|
|
2852061699 | ||
|
|
d8859b9f0a | ||
|
|
ae1bc96006 | ||
|
|
f30ffb4413 | ||
|
|
273c6467c8 | ||
|
|
846a1d007c | ||
|
|
1dccc8dc78 | ||
|
|
e0d67bd057 | ||
|
|
4b4b93ac04 | ||
|
|
4390aee1e0 | ||
|
|
4cddb16788 | ||
|
|
e1179fd8c8 | ||
|
|
cb77285277 | ||
|
|
6c9d161950 | ||
|
|
40aaac5868 | ||
|
|
e16b69594e | ||
|
|
4837bf007a | ||
|
|
705fd4dafd | ||
|
|
a3e28d3c66 | ||
|
|
4a6755c28a | ||
|
|
188fe5dc52 | ||
|
|
44a8ae457d | ||
|
|
92eafcfe1a | ||
|
|
b12b031fdd | ||
|
|
492ec489a1 | ||
|
|
c57124e876 | ||
|
|
95b33c9c34 | ||
|
|
c6d8b63e54 | ||
|
|
f0f02c4ea6 | ||
|
|
eb2cb6810a | ||
|
|
b3c090e9ed | ||
|
|
13366fc9f8 | ||
|
|
929af7830a | ||
|
|
13062cf0e4 | ||
|
|
b897a8a35f | ||
|
|
117dc5288d | ||
|
|
4b5a3bd3d5 | ||
|
|
b224a67ea7 | ||
|
|
793f919d59 | ||
|
|
315987b2f6 | ||
|
|
9b7db548a2 | ||
|
|
126b70f781 | ||
|
|
0bbff627e2 | ||
|
|
961d23e2a1 | ||
|
|
b03ff9a48a | ||
|
|
3ffb40fafa | ||
|
|
1a3b4ac2ac | ||
|
|
794e17442f | ||
|
|
238d7119e0 | ||
|
|
8a929a8348 | ||
|
|
cf77153647 | ||
|
|
a2da0b0641 | ||
|
|
73faa13811 | ||
|
|
1a71872c7b | ||
|
|
62fe7135bd | ||
|
|
078940d29f | ||
|
|
2fafe42c18 | ||
|
|
c8a7537157 | ||
|
|
d4bf1cb23d | ||
|
|
46e4350013 | ||
|
|
202eb0d854 | ||
|
|
898702346e | ||
|
|
b72e6f16ca | ||
|
|
b9c27ed324 | ||
|
|
0166dfe16e | ||
|
|
7274541722 | ||
|
|
709ff7a701 | ||
|
|
66c224c954 | ||
|
|
3f9b37aa7f | ||
|
|
0377958d8f | ||
|
|
cc1cfd70b8 | ||
|
|
bc125ad76c | ||
|
|
62a2246448 | ||
|
|
587cf751d8 | ||
|
|
600181ed07 | ||
|
|
f0e525d2e2 | ||
|
|
f86cdd8cde | ||
|
|
4a4c537a0d | ||
|
|
1caaf04dfa | ||
|
|
b422a80249 | ||
|
|
ba19e20833 | ||
|
|
c34ddb2bc3 | ||
|
|
aa315f8472 | ||
|
|
2af6af2bf0 | ||
|
|
5694ff7c97 | ||
|
|
76f1c689c1 | ||
|
|
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 |
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.pio
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.vscode
|
||||
!.vscode/extensions.json
|
||||
/wled00/Release
|
||||
/wled00/extLibs
|
||||
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
|
||||
BIN
.vs/wled00/v15/.suo
Normal file
BIN
.vs/wled00/v15/.suo
Normal file
Binary file not shown.
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,7 +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?
|
||||
|
||||
You should always try to use the binaries from the release page. This directory is for legacy purposes only!
|
||||
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
|
||||
167
platformio.ini
Normal file
167
platformio.ini
Normal file
@@ -0,0 +1,167 @@
|
||||
; 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
|
||||
; Please uncomment one of the 5 lines below to select your board
|
||||
; env_default = nodemcuv2
|
||||
; env_default = esp01
|
||||
; env_default = esp01_1m
|
||||
; env_default = d1_mini
|
||||
; env_default = esp32dev
|
||||
|
||||
|
||||
[common]
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
board_build.flash_mode = dout
|
||||
upload_speed = 115200
|
||||
upload_speed_fast = 921600
|
||||
build_flags =
|
||||
-w ; supresses all C/C++ warnings
|
||||
; -D VERSION=0.8.5
|
||||
; -D DEBUG
|
||||
# TODO replace libs in /lib with managed libs in here if possible.
|
||||
# If they are not changed it's just a matter of setting the correct version and change the import statement
|
||||
lib_deps_external =
|
||||
#Blynk@0.5.4(changed)
|
||||
#E131@1.0.0(changed)
|
||||
FastLED@3.3.2
|
||||
NeoPixelBus@2.5.1
|
||||
ESPAsyncTCP@1.2.0
|
||||
ESPAsyncUDP@697c75a025
|
||||
AsyncTCP@1.0.3
|
||||
Esp Async WebServer@1.2.0
|
||||
#ArduinoJson@5.13.5
|
||||
IRremoteESP8266@2.5.5
|
||||
#Time@1.5
|
||||
#Timezone@1.2.1
|
||||
|
||||
[common:esp8266]
|
||||
# ------------------------------------------------------------------------------
|
||||
# PLATFORM:
|
||||
# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266
|
||||
# We use Arduino Core 2.5.0 (platformIO 2.0.4) as default
|
||||
#
|
||||
# arduino core 2.3.0 = platformIO 1.5.0
|
||||
# arduino core 2.4.0 = platformIO 1.6.0
|
||||
# arduino core 2.4.1 = platformIO 1.7.3
|
||||
# arduino core 2.4.2 = platformIO 1.8.0
|
||||
# arduino core 2.5.0 = platformIO 2.0.4
|
||||
# arduino core stage = platformIO feature#stage
|
||||
# ------------------------------------------------------------------------------
|
||||
arduino_core_2_3_0 = espressif8266@1.5.0
|
||||
arduino_core_2_4_0 = espressif8266@1.6.0
|
||||
arduino_core_2_4_1 = espressif8266@1.7.3
|
||||
arduino_core_2_4_2 = espressif8266@1.8.0
|
||||
arduino_core_2_5_0 = espressif8266@2.0.4
|
||||
arduino_core_2_5_2 = espressif8266@2.2.3
|
||||
arduino_core_2_6_1 = espressif8266@2.3.0
|
||||
arduino_core_2_6_2 = espressif8266@2.3.1
|
||||
arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#feature/stage
|
||||
platform = ${common:esp8266.arduino_core_2_6_2}
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
-Wl,-Teagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs
|
||||
|
||||
[common:esp8266_1M]
|
||||
platform = espressif8266@1.8.0
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
|
||||
-Wl,-Teagle.flash.1m0.ld ;;;; Compile with no SPIFFS to leave space for OTA
|
||||
; -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:esp8266_512k]
|
||||
platform = espressif8266@1.8.0
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
|
||||
-Wl,-Teagle.flash.512k0.ld ;;;; Compile with no SPIFFS
|
||||
; -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.11.1
|
||||
build_flags =
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||
-D ARDUINO_ARCH_ESP32
|
||||
-D WLED_DISABLE_INFRARED
|
||||
|
||||
# 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}
|
||||
|
||||
[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}
|
||||
|
||||
[env:esp01_1m]
|
||||
board = esp01_1m
|
||||
platform = ${common:esp8266_1M.platform}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp8266_1M.build_flags}
|
||||
# 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_fast}
|
||||
framework = ${common.framework}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common:esp32.build_flags}
|
||||
lib_deps =
|
||||
${common.lib_deps_external}
|
||||
lib_ignore =
|
||||
IRremoteESP8266
|
||||
ESPAsyncUDP
|
||||
89
readme.md
89
readme.md
@@ -1,50 +1,67 @@
|
||||

|
||||
|
||||
[](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/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
|
||||
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs!
|
||||
|
||||
### Features: (V0.6.3)
|
||||
- RGB, HSB, and brightness sliders
|
||||
- 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! Now supports cycling through them.
|
||||
- HTTP request API for simple integration
|
||||
- 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
|
||||
- Support for the Adalight serial ambilight protocol!
|
||||
- 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, DRGB, DRGBW) possible
|
||||
- Client HTML UI controlled, customizable themes
|
||||
### Features:
|
||||
- WS2812FX library integrated for almost 90 special effects
|
||||
- FastLED noise effects and palettes
|
||||
- Modern UI with color, effect and segment controls
|
||||
- Segments to set different effects and colors to parts of the LEDs
|
||||
- Settings page - configuration over network
|
||||
- Access Point and station mode - automatic failsafe AP
|
||||
- Support for RGBW strips
|
||||
- 16 user presets to save and load colors/effects easily, supports cycling through them.
|
||||
- Macro functions to automatically execute API calls
|
||||
- Nightlight function (gradually dims down)
|
||||
- Full OTA software updatability (HTTP + ArduinoOTA), password protectable
|
||||
- Configurable analog clock + support for the Cronixie kit by Diamex
|
||||
- Configurable Auto Brightness limit for safer operation
|
||||
|
||||
### Supported light control interfaces:
|
||||
- WLED app for Android and iOS
|
||||
- JSON and HTTP request APIs
|
||||
- MQTT
|
||||
- Blynk IoT
|
||||
- E1.31
|
||||
- Hyperion
|
||||
- UDP realtime
|
||||
- Alexa voice control (including dimming and color)
|
||||
- Sync to Philips hue lights
|
||||
- Adalight (PC ambilight via serial)
|
||||
- Sync color of multiple WLED devices (UDP notifier)
|
||||
- Infrared remotes (24-key RGB, receiver required)
|
||||
- Simple timers/schedules (time from NTP, timezones/DST supported)
|
||||
|
||||
### Quick start guide and documentation:
|
||||
|
||||
See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
|
||||
|
||||
DrZzs has made some excellent video guides:
|
||||
[Introduction, hardware and installation](https://www.youtube.com/watch?v=tXvtxwK3jRk)
|
||||
[Settings, tips and tricks](https://www.youtube.com/watch?v=6eCE2BpLaUQ)
|
||||
|
||||
If you'd rather read, here is a very [detailed step-by-step beginner tutorial](https://tynick.com/blog/11-03-2019/getting-started-with-wled-on-esp8266/) by tynick!
|
||||
|
||||
### Other
|
||||
|
||||
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)
|
||||
|
||||
*Disclaimer:*
|
||||
If you are sensitive to photoeleptic seizures it is not recommended that you use this software.
|
||||
In case you still want to try, don't use strobe, lighting or noise modes or high effect speed settings.
|
||||
As per the MIT license, i assume no liability for any damage to you or any other person or equipment.
|
||||
|
||||
|
||||
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
|
||||
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt
Normal file
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
These files allow WLED 0.8.6 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up.
|
||||
|
||||
This code uses Aircookie's WLED software. It has a premade file for user modifications. I use it to publish the temperature from the dallas temperature sensor on the Quinled board. The entries for the top of the WLED00 file, initializes the required libraries, and variables for the sensor. The .ino file waits for 60 seconds, and checks to see if the MQTT server is connected (thanks Aircoookie). It then poles the sensor, and published it using the MQTT service already running, using the main topic programmed in the WLED UI.
|
||||
|
||||
To install:
|
||||
|
||||
Add the enties in the WLED00 file to the top of the same file from Aircoookies WLED.
|
||||
Replace the WLED06_usermod.ino file in Aircoookies WLED folder.
|
||||
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt
Normal file
8
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
//Intiating code for QuinLED Dig-Uno temp sensor
|
||||
//Uncomment Celsius if that is your prefered temperature scale
|
||||
#include <DallasTemperature.h>
|
||||
OneWire oneWire(14);
|
||||
DallasTemperature sensors(&oneWire);
|
||||
long temptimer = millis();
|
||||
long lastMeasure = 0;
|
||||
//#define Celsius
|
||||
41
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino
Normal file
41
usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino
Normal file
@@ -0,0 +1,41 @@
|
||||
//starts Dallas Temp service on boot
|
||||
void userSetup()
|
||||
{
|
||||
// Start the DS18B20 sensor
|
||||
sensors.begin();
|
||||
}
|
||||
|
||||
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
|
||||
void userConnected()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void userLoop()
|
||||
{
|
||||
temptimer = millis();
|
||||
|
||||
// Timer to publishe new temperature every 60 seconds
|
||||
if (temptimer - lastMeasure > 60000) {
|
||||
lastMeasure = temptimer;
|
||||
|
||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||
if (mqtt != nullptr){
|
||||
sensors.requestTemperatures();
|
||||
|
||||
//Gets prefered temperature scale based on selection in definitions section
|
||||
#ifdef Celsius
|
||||
float board_temperature = sensors.getTempCByIndex(0);
|
||||
#else
|
||||
float board_temperature = sensors.getTempFByIndex(0);
|
||||
#endif
|
||||
|
||||
//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server.
|
||||
char subuf[38];
|
||||
strcpy(subuf, mqttDeviceTopic);
|
||||
strcat(subuf, "/temperature");
|
||||
mqtt->publish(subuf, 0, true, String(board_temperature).c_str());
|
||||
return;}
|
||||
return;}
|
||||
return;
|
||||
}
|
||||
18
usermods/readme.md
Normal file
18
usermods/readme.md
Normal file
@@ -0,0 +1,18 @@
|
||||
### Usermods
|
||||
|
||||
This folder serves as a repository for usermods (custom `wled06_usermod.ino` files)!
|
||||
|
||||
If you have created an usermod that you believe is useful (for example to support a particular sensor, display, feature...), feel free to contribute by opening a pull request!
|
||||
|
||||
In order for other people to be able to have fun with your usermod, please keep these points in mind:
|
||||
|
||||
- Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`)
|
||||
- Include your custom `wled06_usermod.ino` file
|
||||
- If your usermod requieres changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod
|
||||
- Create a pull request!
|
||||
- If your feature is useful for the majority of WLED users, I will consider adding it to the base code!
|
||||
|
||||
While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break.
|
||||
I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod.
|
||||
|
||||
Thank you for your help :)
|
||||
45
usermods/rotary_encoder_change_effect/wled06_usermod.ino
Normal file
45
usermods/rotary_encoder_change_effect/wled06_usermod.ino
Normal file
@@ -0,0 +1,45 @@
|
||||
//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)
|
||||
|
||||
long lastTime = 0;
|
||||
int delayMs = 10;
|
||||
const int pinA = D6; //data
|
||||
const int pinB = D7; //clk
|
||||
int oldA = LOW;
|
||||
|
||||
//gets called once at boot. Do all initialization that doesn't depend on network here
|
||||
void userSetup() {
|
||||
pinMode(pinA, INPUT_PULLUP);
|
||||
pinMode(pinB, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
|
||||
void userConnected() {
|
||||
}
|
||||
|
||||
//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
|
||||
void userLoop() {
|
||||
if (millis()-lastTime > delayMs) {
|
||||
int A = digitalRead(pinA);
|
||||
int B = digitalRead(pinB);
|
||||
|
||||
if (oldA == LOW && A == HIGH) {
|
||||
if (oldB == HIGH) {
|
||||
// bri += 10;
|
||||
// if (bri > 250) bri = 10;
|
||||
effectCurrent += 1;
|
||||
if (effectCurrent >= MODE_COUNT) effectCurrent = 0;
|
||||
}
|
||||
else {
|
||||
// bri -= 10;
|
||||
// if (bri < 10) bri = 250;
|
||||
effectCurrent -= 1;
|
||||
if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1);
|
||||
}
|
||||
oldA = A;
|
||||
|
||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
|
||||
// 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa
|
||||
colorUpdated(6);
|
||||
lastTime = millis();
|
||||
}
|
||||
}
|
||||
35
usermods/ssd1306_i2c_oled_u8g2/README.md
Normal file
35
usermods/ssd1306_i2c_oled_u8g2/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# SSD1306 128x32 OLED via I2C with u8g2
|
||||
This usermod allows to connect 128x32 Oled display to WLED controlled and show
|
||||
the next information:
|
||||
- Current SSID
|
||||
- IP address if obtained
|
||||
* in AP mode and turned off lightning AP password is shown
|
||||
- Current effect
|
||||
- Current palette
|
||||
- On/Off icon (sun/moon)
|
||||
|
||||
## Hardware
|
||||

|
||||
|
||||
## Requirements
|
||||
Functionality checked with:
|
||||
- commit 095429a7df4f9e2b34dd464f7bbfd068df6558eb
|
||||
- Wemos d1 mini
|
||||
- PlatformIO
|
||||
- Generic SSD1306 128x32 I2C OLED display from aliexpress
|
||||
|
||||
### Platformio
|
||||
Add `U8g2@~2.27.2` dependency to `lib_deps_external` under `[common]` section in `platformio.ini`:
|
||||
```ini
|
||||
# platformio.ini
|
||||
...
|
||||
[common]
|
||||
...
|
||||
lib_deps_external =
|
||||
...
|
||||
U8g2@~2.27.2
|
||||
...
|
||||
```
|
||||
|
||||
### Arduino IDE
|
||||
Install library `U8g2 by oliver` in `Tools | Include Library | Manage libraries` menu.
|
||||
BIN
usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png
Normal file
BIN
usermods/ssd1306_i2c_oled_u8g2/assets/hw_connection.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
149
usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino
Normal file
149
usermods/ssd1306_i2c_oled_u8g2/wled06_usermod.ino
Normal file
@@ -0,0 +1,149 @@
|
||||
#include <U8x8lib.h> // from https://github.com/olikraus/u8g2/
|
||||
|
||||
// If display does not work or looks corrupted check the
|
||||
// constructor reference:
|
||||
// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
|
||||
// or check the gallery:
|
||||
// https://github.com/olikraus/u8g2/wiki/gallery
|
||||
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, 5,
|
||||
4); // Pins are Reset, SCL, SDA
|
||||
|
||||
// gets called once at boot. Do all initialization that doesn't depend on
|
||||
// network here
|
||||
void userSetup() {
|
||||
u8x8.begin();
|
||||
u8x8.setPowerSave(0);
|
||||
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||
u8x8.drawString(0, 0, "Loading...");
|
||||
}
|
||||
|
||||
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||
// interfaces here
|
||||
void userConnected() {}
|
||||
|
||||
// needRedraw marks if redraw is required to prevent often redrawing.
|
||||
bool needRedraw = true;
|
||||
|
||||
// Next variables hold the previous known values to determine if redraw is
|
||||
// required.
|
||||
String knownSsid = "";
|
||||
IPAddress knownIp;
|
||||
uint8_t knownBrightness = 0;
|
||||
uint8_t knownMode = 0;
|
||||
uint8_t knownPalette = 0;
|
||||
|
||||
long lastUpdate = 0;
|
||||
// How often we are redrawing screen
|
||||
#define USER_LOOP_REFRESH_RATE_MS 5000
|
||||
|
||||
void userLoop() {
|
||||
|
||||
// Check if we time interval for redrawing passes.
|
||||
if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) {
|
||||
return;
|
||||
}
|
||||
lastUpdate = millis();
|
||||
|
||||
// Check if values which are shown on display changed from the last tiem.
|
||||
if ((apActive == true ? String(apSSID) : WiFi.SSID()) != knownSsid) {
|
||||
needRedraw = true;
|
||||
} else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) {
|
||||
needRedraw = true;
|
||||
} else if (knownBrightness != bri) {
|
||||
needRedraw = true;
|
||||
} else if (knownMode != strip.getMode()) {
|
||||
needRedraw = true;
|
||||
} else if (knownPalette != strip.getSegment(0).palette) {
|
||||
needRedraw = true;
|
||||
}
|
||||
|
||||
if (!needRedraw) {
|
||||
return;
|
||||
}
|
||||
needRedraw = false;
|
||||
|
||||
// Update last known values.
|
||||
knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID();
|
||||
knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP();
|
||||
knownBrightness = bri;
|
||||
knownMode = strip.getMode();
|
||||
knownPalette = strip.getSegment(0).palette;
|
||||
|
||||
u8x8.clear();
|
||||
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||
|
||||
// First row with Wifi name
|
||||
u8x8.setCursor(1, 0);
|
||||
u8x8.print(ssid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0));
|
||||
// Print `~` char to indicate that SSID is longer, than owr dicplay
|
||||
if (ssid.length() > u8x8.getCols())
|
||||
u8x8.print("~");
|
||||
|
||||
// Second row with IP or Psssword
|
||||
u8x8.setCursor(1, 1);
|
||||
// Print password in AP mode and if led is OFF.
|
||||
if (apActive && bri == 0)
|
||||
u8x8.print(apPass);
|
||||
else
|
||||
u8x8.print(ip);
|
||||
|
||||
// Third row with mode name
|
||||
u8x8.setCursor(2, 2);
|
||||
uint8_t qComma = 0;
|
||||
bool insideQuotes = false;
|
||||
uint8_t printedChars = 0;
|
||||
char singleJsonSymbol;
|
||||
// Find the mode name in JSON
|
||||
for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) {
|
||||
singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i);
|
||||
switch (singleJsonSymbol) {
|
||||
case '"':
|
||||
insideQuotes = !insideQuotes;
|
||||
break;
|
||||
case '[':
|
||||
case ']':
|
||||
break;
|
||||
case ',':
|
||||
qComma++;
|
||||
default:
|
||||
if (!insideQuotes || (qComma != knownMode))
|
||||
break;
|
||||
u8x8.print(singleJsonSymbol);
|
||||
printedChars++;
|
||||
}
|
||||
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
|
||||
break;
|
||||
}
|
||||
// Fourth row with palette name
|
||||
u8x8.setCursor(2, 3);
|
||||
qComma = 0;
|
||||
insideQuotes = false;
|
||||
printedChars = 0;
|
||||
// Looking for palette name in JSON.
|
||||
for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) {
|
||||
singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i);
|
||||
switch (singleJsonSymbol) {
|
||||
case '"':
|
||||
insideQuotes = !insideQuotes;
|
||||
break;
|
||||
case '[':
|
||||
case ']':
|
||||
break;
|
||||
case ',':
|
||||
qComma++;
|
||||
default:
|
||||
if (!insideQuotes || (qComma != knownPalette))
|
||||
break;
|
||||
u8x8.print(singleJsonSymbol);
|
||||
printedChars++;
|
||||
}
|
||||
if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2))
|
||||
break;
|
||||
}
|
||||
|
||||
u8x8.setFont(u8x8_font_open_iconic_embedded_1x1);
|
||||
u8x8.drawGlyph(0, 0, 80); // wifi icon
|
||||
u8x8.drawGlyph(0, 1, 68); // home icon
|
||||
u8x8.setFont(u8x8_font_open_iconic_weather_2x2);
|
||||
u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon
|
||||
}
|
||||
25
wled00.sln
Normal file
25
wled00.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28010.2046
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wled00", "wled00\wled00.vcxproj", "{C5F80730-F44F-4478-BDAE-6634EFC2CA88}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C5F80730-F44F-4478-BDAE-6634EFC2CA88}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9A679C2B-61D3-400B-B96F-06E604E9CED2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
BIN
wled00/.vs/wled00/v15/.suo
Normal file
BIN
wled00/.vs/wled00/v15/.suo
Normal file
Binary file not shown.
2351
wled00/FX.cpp
Normal file
2351
wled00/FX.cpp
Normal file
File diff suppressed because it is too large
Load Diff
593
wled00/FX.h
Normal file
593
wled00/FX.h
Normal file
@@ -0,0 +1,593 @@
|
||||
/*
|
||||
WS2812FX.h - Library for WS2812 LED effects.
|
||||
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 for WLED
|
||||
*/
|
||||
|
||||
#ifndef WS2812FX_h
|
||||
#define WS2812FX_h
|
||||
|
||||
#include "NpbWrapper.h"
|
||||
|
||||
#define FASTLED_INTERNAL //remove annoying pragma messages
|
||||
#include "FastLED.h"
|
||||
|
||||
#define DEFAULT_BRIGHTNESS (uint8_t)127
|
||||
#define DEFAULT_MODE (uint8_t)0
|
||||
#define DEFAULT_SPEED (uint8_t)128
|
||||
#define DEFAULT_COLOR (uint32_t)0xFFAA00
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
/* Not used in all effects yet */
|
||||
#define WLED_FPS 42
|
||||
#define FRAMETIME (1000/WLED_FPS)
|
||||
|
||||
/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#define MAX_NUM_SEGMENTS 10
|
||||
|
||||
#define NUM_COLORS 3 /* number of colors per segment */
|
||||
#define SEGMENT _segments[_segment_index]
|
||||
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
|
||||
#define SEGENV _segment_runtimes[_segment_index]
|
||||
#define SEGLEN SEGMENT.length()
|
||||
#define SEGACT SEGMENT.stop
|
||||
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
|
||||
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
||||
|
||||
// some common colors
|
||||
#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 7: segment is in transition mode
|
||||
// bits 2-6: TBD
|
||||
// bit 1: reverse segment
|
||||
// bit 0: segment is selected
|
||||
#define NO_OPTIONS (uint8_t)0x00
|
||||
#define TRANSITIONAL (uint8_t)0x80
|
||||
#define REVERSE (uint8_t)0x02
|
||||
#define SELECTED (uint8_t)0x01
|
||||
#define IS_TRANSITIONAL ((SEGMENT.options & TRANSITIONAL) == TRANSITIONAL)
|
||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||
#define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED )
|
||||
|
||||
#define MODE_COUNT 89
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
#define FX_MODE_BREATH 2
|
||||
#define FX_MODE_COLOR_WIPE 3
|
||||
#define FX_MODE_COLOR_WIPE_RANDOM 4
|
||||
#define FX_MODE_RANDOM_COLOR 5
|
||||
#define FX_MODE_COLOR_SWEEP 6
|
||||
#define FX_MODE_DYNAMIC 7
|
||||
#define FX_MODE_RAINBOW 8
|
||||
#define FX_MODE_RAINBOW_CYCLE 9
|
||||
#define FX_MODE_SCAN 10
|
||||
#define FX_MODE_DUAL_SCAN 11
|
||||
#define FX_MODE_FADE 12
|
||||
#define FX_MODE_THEATER_CHASE 13
|
||||
#define FX_MODE_THEATER_CHASE_RAINBOW 14
|
||||
#define FX_MODE_RUNNING_LIGHTS 15
|
||||
#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
|
||||
#define FX_MODE_STROBE 23
|
||||
#define FX_MODE_STROBE_RAINBOW 24
|
||||
#define FX_MODE_MULTI_STROBE 25
|
||||
#define FX_MODE_BLINK_RAINBOW 26
|
||||
#define FX_MODE_ANDROID 27
|
||||
#define FX_MODE_CHASE_COLOR 28
|
||||
#define FX_MODE_CHASE_RANDOM 29
|
||||
#define FX_MODE_CHASE_RAINBOW 30
|
||||
#define FX_MODE_CHASE_FLASH 31
|
||||
#define FX_MODE_CHASE_FLASH_RANDOM 32
|
||||
#define FX_MODE_CHASE_RAINBOW_WHITE 33
|
||||
#define FX_MODE_COLORFUL 34
|
||||
#define FX_MODE_TRAFFIC_LIGHT 35
|
||||
#define FX_MODE_COLOR_SWEEP_RANDOM 36
|
||||
#define FX_MODE_RUNNING_COLOR 37
|
||||
#define FX_MODE_RUNNING_RED_BLUE 38
|
||||
#define FX_MODE_RUNNING_RANDOM 39
|
||||
#define FX_MODE_LARSON_SCANNER 40
|
||||
#define FX_MODE_COMET 41
|
||||
#define FX_MODE_FIREWORKS 42
|
||||
#define FX_MODE_RAIN 43
|
||||
#define FX_MODE_MERRY_CHRISTMAS 44
|
||||
#define FX_MODE_FIRE_FLICKER 45
|
||||
#define FX_MODE_GRADIENT 46
|
||||
#define FX_MODE_LOADING 47
|
||||
#define FX_MODE_POLICE 48
|
||||
#define FX_MODE_POLICE_ALL 49
|
||||
#define FX_MODE_TWO_DOTS 50
|
||||
#define FX_MODE_TWO_AREAS 51
|
||||
#define FX_MODE_CIRCUS_COMBUSTUS 52
|
||||
#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
|
||||
#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
|
||||
#define FX_MODE_TWINKLEFOX 80
|
||||
#define FX_MODE_TWINKLECAT 81
|
||||
#define FX_MODE_HALLOWEEN_EYES 82
|
||||
#define FX_MODE_STATIC_PATTERN 83
|
||||
#define FX_MODE_TRI_STATIC_PATTERN 84
|
||||
#define FX_MODE_SPOTS 85
|
||||
#define FX_MODE_SPOTS_FADE 86
|
||||
#define FX_MODE_GLITTER 87
|
||||
#define FX_MODE_CANDLE 88
|
||||
|
||||
|
||||
class WS2812FX {
|
||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||
|
||||
// segment parameters
|
||||
public:
|
||||
typedef struct Segment { // 24 bytes
|
||||
uint16_t start;
|
||||
uint16_t stop; //segment invalid if stop == 0
|
||||
uint8_t speed;
|
||||
uint8_t intensity;
|
||||
uint8_t palette;
|
||||
uint8_t mode;
|
||||
uint8_t options; //bit pattern: msb first: transitional tbd tbd tbd tbd paused reverse selected
|
||||
uint8_t group, spacing;
|
||||
uint8_t opacity;
|
||||
uint32_t colors[NUM_COLORS];
|
||||
void setOption(uint8_t n, bool val)
|
||||
{
|
||||
if (val) {
|
||||
options |= 0x01 << n;
|
||||
} else
|
||||
{
|
||||
options &= ~(0x01 << n);
|
||||
}
|
||||
}
|
||||
bool getOption(uint8_t n)
|
||||
{
|
||||
return ((options >> n) & 0x01);
|
||||
}
|
||||
bool isSelected()
|
||||
{
|
||||
return getOption(0);
|
||||
}
|
||||
bool isActive()
|
||||
{
|
||||
return stop > start;
|
||||
}
|
||||
uint16_t length()
|
||||
{
|
||||
return stop - start;
|
||||
}
|
||||
} segment;
|
||||
|
||||
// segment runtime parameters
|
||||
typedef struct Segment_runtime { // 16 bytes
|
||||
unsigned long next_time;
|
||||
uint32_t step;
|
||||
uint32_t call;
|
||||
uint16_t aux0;
|
||||
uint16_t aux1;
|
||||
void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;};
|
||||
} segment_runtime;
|
||||
|
||||
WS2812FX() {
|
||||
//assign each member of the _mode[] array to its respective function reference
|
||||
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
|
||||
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
|
||||
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
|
||||
_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_POLICE] = &WS2812FX::mode_police;
|
||||
_mode[FX_MODE_POLICE_ALL] = &WS2812FX::mode_police_all;
|
||||
_mode[FX_MODE_TWO_DOTS] = &WS2812FX::mode_two_dots;
|
||||
_mode[FX_MODE_TWO_AREAS] = &WS2812FX::mode_two_areas;
|
||||
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
||||
_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[FX_MODE_TWINKLEFOX] = &WS2812FX::mode_twinklefox;
|
||||
_mode[FX_MODE_TWINKLECAT] = &WS2812FX::mode_twinklecat;
|
||||
_mode[FX_MODE_HALLOWEEN_EYES] = &WS2812FX::mode_halloween_eyes;
|
||||
_mode[FX_MODE_STATIC_PATTERN] = &WS2812FX::mode_static_pattern;
|
||||
_mode[FX_MODE_TRI_STATIC_PATTERN] = &WS2812FX::mode_tri_static_pattern;
|
||||
_mode[FX_MODE_SPOTS] = &WS2812FX::mode_spots;
|
||||
_mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade;
|
||||
_mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter;
|
||||
_mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle;
|
||||
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
targetPalette = CloudColors_p;
|
||||
ablMilliampsMax = 850;
|
||||
currentMilliamps = 0;
|
||||
timebase = 0;
|
||||
_locked = nullptr;
|
||||
_modeUsesLock = false;
|
||||
bus = new NeoPixelWrapper();
|
||||
resetSegments();
|
||||
}
|
||||
|
||||
void
|
||||
init(bool supportWhite, uint16_t countPixels, bool skipFirs, uint8_t disableNLeds),
|
||||
service(void),
|
||||
blur(uint8_t),
|
||||
fade_out(uint8_t r),
|
||||
setMode(uint8_t segid, uint8_t m),
|
||||
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||
setColor(uint8_t slot, uint32_t c),
|
||||
setBrightness(uint8_t b),
|
||||
driverModeCronixie(bool b),
|
||||
setCronixieDigits(byte* d),
|
||||
setCronixieBacklight(bool b),
|
||||
setIndividual(uint16_t i, uint32_t col),
|
||||
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
||||
lock(uint16_t i),
|
||||
lockRange(uint16_t i, uint16_t i2),
|
||||
unlock(uint16_t i),
|
||||
unlockRange(uint16_t i, uint16_t i2),
|
||||
unlockAll(void),
|
||||
setTransitionMode(bool t),
|
||||
trigger(void),
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop),
|
||||
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
|
||||
reverseMode = false,
|
||||
gammaCorrectBri = false,
|
||||
gammaCorrectCol = true,
|
||||
applyToAllSelected = true,
|
||||
segmentsAreIdentical(Segment* a, Segment* b),
|
||||
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
|
||||
|
||||
uint8_t
|
||||
mainSegment = 0,
|
||||
paletteFade = 0,
|
||||
paletteBlend = 0,
|
||||
colorOrder = 0,
|
||||
milliampsPerLed = 55,
|
||||
_disableNLeds = 0,
|
||||
getBrightness(void),
|
||||
getMode(void),
|
||||
getSpeed(void),
|
||||
getModeCount(void),
|
||||
getPaletteCount(void),
|
||||
getMaxSegments(void),
|
||||
//getFirstSelectedSegment(void),
|
||||
getMainSegmentId(void),
|
||||
gamma8(uint8_t),
|
||||
get_random_wheel_index(uint8_t);
|
||||
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps,
|
||||
triwave16(uint16_t),
|
||||
getUsableCount();
|
||||
|
||||
uint32_t
|
||||
timebase,
|
||||
color_wheel(uint8_t),
|
||||
color_from_palette(uint16_t, bool, bool, uint8_t, uint8_t pbri = 255),
|
||||
color_blend(uint32_t,uint32_t,uint8_t),
|
||||
gamma32(uint32_t),
|
||||
getLastShow(void),
|
||||
getPixelColor(uint16_t),
|
||||
getColor(void);
|
||||
|
||||
WS2812FX::Segment&
|
||||
getSegment(uint8_t n);
|
||||
|
||||
WS2812FX::Segment_runtime
|
||||
getSegmentRuntime(void);
|
||||
|
||||
WS2812FX::Segment*
|
||||
getSegments(void);
|
||||
|
||||
// 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_dynamic(void),
|
||||
mode_breath(void),
|
||||
mode_fade(void),
|
||||
mode_scan(void),
|
||||
mode_dual_scan(void),
|
||||
mode_theater_chase(void),
|
||||
mode_theater_chase_rainbow(void),
|
||||
mode_rainbow(void),
|
||||
mode_rainbow_cycle(void),
|
||||
mode_running_lights(void),
|
||||
mode_saw(void),
|
||||
mode_twinkle(void),
|
||||
mode_dissolve(void),
|
||||
mode_dissolve_random(void),
|
||||
mode_sparkle(void),
|
||||
mode_flash_sparkle(void),
|
||||
mode_hyper_sparkle(void),
|
||||
mode_multi_strobe(void),
|
||||
mode_android(void),
|
||||
mode_chase_color(void),
|
||||
mode_chase_random(void),
|
||||
mode_chase_rainbow(void),
|
||||
mode_chase_flash(void),
|
||||
mode_chase_flash_random(void),
|
||||
mode_chase_rainbow_white(void),
|
||||
mode_colorful(void),
|
||||
mode_traffic_light(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_rain(void),
|
||||
mode_merry_christmas(void),
|
||||
mode_halloween(void),
|
||||
mode_fire_flicker(void),
|
||||
mode_gradient(void),
|
||||
mode_loading(void),
|
||||
mode_police(void),
|
||||
mode_police_all(void),
|
||||
mode_two_dots(void),
|
||||
mode_two_areas(void),
|
||||
mode_circus_combustus(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),
|
||||
mode_twinklefox(void),
|
||||
mode_twinklecat(void),
|
||||
mode_halloween_eyes(void),
|
||||
mode_static_pattern(void),
|
||||
mode_tri_static_pattern(void),
|
||||
mode_spots(void),
|
||||
mode_spots_fade(void),
|
||||
mode_glitter(void),
|
||||
mode_candle(void);
|
||||
|
||||
|
||||
private:
|
||||
NeoPixelWrapper *bus;
|
||||
|
||||
uint32_t crgb_to_col(CRGB fastled);
|
||||
CRGB col_to_crgb(uint32_t);
|
||||
CRGBPalette16 currentPalette;
|
||||
CRGBPalette16 targetPalette;
|
||||
|
||||
uint32_t now;
|
||||
uint16_t _length, _lengthRaw, _usableCount;
|
||||
uint16_t _rand16seed;
|
||||
uint8_t _brightness;
|
||||
|
||||
void handle_palette(void);
|
||||
void fill(uint32_t);
|
||||
bool modeUsesLock(uint8_t);
|
||||
|
||||
bool
|
||||
_modeUsesLock,
|
||||
_rgbwMode,
|
||||
_cronixieMode,
|
||||
_cronixieBacklightEnabled,
|
||||
_skipFirstMode,
|
||||
_triggered;
|
||||
|
||||
byte* _locked;
|
||||
byte _cronixieDigits[6];
|
||||
|
||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
||||
|
||||
// mode helper functions
|
||||
uint16_t
|
||||
blink(uint32_t, uint32_t, bool strobe, bool),
|
||||
color_wipe(bool, bool),
|
||||
scan(bool),
|
||||
theater_chase(uint32_t, uint32_t, bool),
|
||||
running_base(bool),
|
||||
dissolve(uint32_t),
|
||||
chase(uint32_t, uint32_t, uint32_t, bool),
|
||||
gradient_base(bool),
|
||||
police_base(uint32_t, uint32_t),
|
||||
running(uint32_t, uint32_t),
|
||||
tricolor_chase(uint32_t, uint32_t),
|
||||
twinklefox_base(bool),
|
||||
spots_base(uint16_t);
|
||||
|
||||
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
|
||||
|
||||
uint32_t _lastPaletteChange = 0;
|
||||
uint32_t _lastShow = 0;
|
||||
|
||||
uint8_t _segment_index = 0;
|
||||
uint8_t _segment_index_palette_last = 99;
|
||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
|
||||
// start, stop, speed, intensity, palette, mode, options, 3 unused bytes (group, spacing, opacity), color[]
|
||||
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
|
||||
};
|
||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
|
||||
};
|
||||
|
||||
|
||||
//10 names per line
|
||||
const char JSON_mode_names[] PROGMEM = R"=====([
|
||||
"Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow",
|
||||
"Scan","Dual Scan","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd",
|
||||
"Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random",
|
||||
"Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream",
|
||||
"Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All",
|
||||
"Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet",
|
||||
"Scanner Dual ","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
|
||||
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
|
||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle"
|
||||
])=====";
|
||||
|
||||
|
||||
const char JSON_palette_names[] PROGMEM = R"=====([
|
||||
"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","Orangery","C9","Sakura",
|
||||
"Aurora"
|
||||
])=====";
|
||||
|
||||
#endif
|
||||
864
wled00/FX_fcn.cpp
Normal file
864
wled00/FX_fcn.cpp
Normal file
@@ -0,0 +1,864 @@
|
||||
/*
|
||||
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 "FX.h"
|
||||
#include "palettes.h"
|
||||
|
||||
#define LED_SKIP_AMOUNT 1
|
||||
#define MIN_SHOW_DELAY 15
|
||||
|
||||
void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uint8_t disableNLeds)
|
||||
{
|
||||
if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && disableNLeds == _disableNLeds) return;
|
||||
RESET_RUNTIME;
|
||||
_rgbwMode = supportWhite;
|
||||
_skipFirstMode = skipFirst;
|
||||
_length = countPixels;
|
||||
|
||||
if (disableNLeds > 0) {
|
||||
uint16_t groupCount = disableNLeds +1;
|
||||
//since 1st led is lit, even partial group has a led lit, whereas int division truncates decimal.
|
||||
bool hasExtraLight = _length % groupCount != 0;
|
||||
_usableCount = _length/groupCount;
|
||||
_usableCount += hasExtraLight ? 1 : 0;
|
||||
} else {
|
||||
_usableCount = _length;
|
||||
}
|
||||
|
||||
_disableNLeds = disableNLeds;
|
||||
|
||||
uint8_t ty = 1;
|
||||
if (supportWhite) ty =2;
|
||||
_lengthRaw = _length;
|
||||
if (_skipFirstMode) {
|
||||
_lengthRaw += LED_SKIP_AMOUNT;
|
||||
}
|
||||
|
||||
bus->Begin((NeoPixelType)ty, _lengthRaw);
|
||||
|
||||
delete[] _locked;
|
||||
_locked = new byte[_length];
|
||||
|
||||
_segments[0].start = 0;
|
||||
_segments[0].stop = _usableCount;
|
||||
|
||||
unlockAll();
|
||||
setBrightness(_brightness);
|
||||
}
|
||||
|
||||
void WS2812FX::service() {
|
||||
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
||||
now = nowUp + timebase;
|
||||
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
||||
bool doShow = false;
|
||||
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
_segment_index = i;
|
||||
if (SEGMENT.isActive())
|
||||
{
|
||||
if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
|
||||
{
|
||||
doShow = true;
|
||||
handle_palette();
|
||||
uint16_t delay = (this->*_mode[SEGMENT.mode])();
|
||||
SEGENV.next_time = nowUp + delay;
|
||||
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(doShow) {
|
||||
yield();
|
||||
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 || m == FX_MODE_DYNAMIC ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
|
||||
uint8_t w = (c >> 24);
|
||||
uint8_t r = (c >> 16);
|
||||
uint8_t g = (c >> 8);
|
||||
uint8_t b = c ;
|
||||
setPixelColor(n, r, g, b, w);
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
i = i * (_disableNLeds+1);
|
||||
if (_locked[i] && !_modeUsesLock) return;
|
||||
if (IS_REVERSE) i = SEGMENT.stop -1 -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 (reverseMode) i = _length -1 -i;
|
||||
if (_skipFirstMode)
|
||||
{
|
||||
if (i < LED_SKIP_AMOUNT) bus->SetPixelColor(i, RgbwColor(0,0,0,0));
|
||||
i += LED_SKIP_AMOUNT;
|
||||
}
|
||||
if (i < _lengthRaw) bus->SetPixelColor(i, RgbwColor(r,g,b,w));
|
||||
if (_disableNLeds > 0) {
|
||||
for(uint16_t offCount=0; offCount < _disableNLeds; offCount++) {
|
||||
if (i < _lengthRaw) bus->SetPixelColor((i + offCount + 1), RgbwColor(0,0,0,0));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(i>6)return;
|
||||
byte o = 10*i;
|
||||
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
|
||||
{
|
||||
byte r2 = _segments[0].colors[1] >>16;
|
||||
byte g2 = _segments[0].colors[1] >> 8;
|
||||
byte b2 = _segments[0].colors[1];
|
||||
byte w2 = _segments[0].colors[1] >>24;
|
||||
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::driverModeCronixie(bool b)
|
||||
{
|
||||
_cronixieMode = b;
|
||||
_segments[0].stop = (b) ? 6 : _length;
|
||||
}
|
||||
|
||||
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 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 && milliampsPerLed > 0) //0 mA per LED and too low numbers turn off calculation
|
||||
{
|
||||
uint32_t puPerMilliamp = 195075 / milliampsPerLed;
|
||||
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
|
||||
if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget
|
||||
{
|
||||
powerBudget -= puPerMilliamp * _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 = 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) / puPerMilliamp;
|
||||
} else
|
||||
{
|
||||
currentMilliamps = powerSum / puPerMilliamp;
|
||||
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->SetBrightness(_brightness);
|
||||
}
|
||||
|
||||
bus->Show();
|
||||
_lastShow = millis();
|
||||
}
|
||||
|
||||
void WS2812FX::trigger() {
|
||||
_triggered = true;
|
||||
}
|
||||
|
||||
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
||||
if (segid >= MAX_NUM_SEGMENTS) return;
|
||||
|
||||
bool anyUsedLock = _modeUsesLock, anyUseLock = false;
|
||||
if (m >= MODE_COUNT) m = MODE_COUNT - 1;
|
||||
|
||||
if (_segments[segid].mode != m)
|
||||
{
|
||||
_segment_runtimes[segid].reset();
|
||||
_segments[segid].mode = m;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (modeUsesLock(_segments[i].mode)) anyUseLock = true;
|
||||
}
|
||||
if (anyUsedLock && !anyUseLock) unlockAll();
|
||||
_modeUsesLock = anyUseLock;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getModeCount()
|
||||
{
|
||||
return MODE_COUNT;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getPaletteCount()
|
||||
{
|
||||
return 13 + gGradientPaletteCount;
|
||||
}
|
||||
|
||||
//TODO transitions
|
||||
|
||||
|
||||
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
|
||||
uint8_t mainSeg = getMainSegmentId();
|
||||
Segment& seg = _segments[getMainSegmentId()];
|
||||
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;
|
||||
|
||||
if (applyToAllSelected) {
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected())
|
||||
{
|
||||
_segments[i].speed = s;
|
||||
_segments[i].intensity = in;
|
||||
_segments[i].palette = p;
|
||||
setMode(i, m);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
seg.speed = s;
|
||||
seg.intensity = in;
|
||||
seg.palette = p;
|
||||
setMode(mainSegment, m);
|
||||
}
|
||||
|
||||
if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
setColor(slot, ((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
|
||||
if (slot >= NUM_COLORS) return;
|
||||
if (applyToAllSelected) {
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
|
||||
}
|
||||
} else {
|
||||
_segments[getMainSegmentId()].colors[slot] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setBrightness(uint8_t b) {
|
||||
if (_brightness == b) return;
|
||||
_brightness = (gammaCorrectBri) ? gamma8(b) : b;
|
||||
_segment_index = 0;
|
||||
if (SEGENV.next_time > millis() + 22) show();//apply brightness change immediately if no refresh soon
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getMode(void) {
|
||||
return _segments[getMainSegmentId()].mode;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getSpeed(void) {
|
||||
return _segments[getMainSegmentId()].speed;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getBrightness(void) {
|
||||
return _brightness;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getMaxSegments(void) {
|
||||
return MAX_NUM_SEGMENTS;
|
||||
}
|
||||
|
||||
/*uint8_t WS2812FX::getFirstSelectedSegment(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
if (_segments[i].isActive() && _segments[i].isSelected()) return i;
|
||||
}
|
||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //if none selected, get first active
|
||||
{
|
||||
if (_segments[i].isActive()) return i;
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
uint8_t WS2812FX::getMainSegmentId(void) {
|
||||
if (mainSegment >= MAX_NUM_SEGMENTS) return 0;
|
||||
return mainSegment;
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getColor(void) {
|
||||
return _segments[getMainSegmentId()].colors[0];
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||
{
|
||||
i = i * (_disableNLeds+1);
|
||||
if (reverseMode) i = _length- 1 -i;
|
||||
if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment
|
||||
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
||||
if (_cronixieMode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (i >= _lengthRaw) 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(uint8_t id) {
|
||||
if (id >= MAX_NUM_SEGMENTS) return _segments[0];
|
||||
return _segments[id];
|
||||
}
|
||||
|
||||
WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) {
|
||||
return SEGENV;
|
||||
}
|
||||
|
||||
WS2812FX::Segment* WS2812FX::getSegments(void) {
|
||||
return _segments;
|
||||
}
|
||||
|
||||
uint16_t WS2812FX::getUsableCount(void) {
|
||||
return _usableCount;
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::getLastShow(void) {
|
||||
return _lastShow;
|
||||
}
|
||||
|
||||
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
|
||||
if (n >= MAX_NUM_SEGMENTS) return;
|
||||
Segment& seg = _segments[n];
|
||||
if (seg.start == i1 && seg.stop == i2) return;
|
||||
if (seg.isActive() && modeUsesLock(seg.mode))
|
||||
{
|
||||
_modeUsesLock = false;
|
||||
unlockRange(seg.start, seg.stop);
|
||||
_modeUsesLock = true;
|
||||
}
|
||||
_segment_index = n; fill(0); //turn old segment range off
|
||||
if (i2 <= i1) //disable segment
|
||||
{
|
||||
seg.stop = 0; return;
|
||||
}
|
||||
if (i1 < _length) seg.start = i1;
|
||||
seg.stop = i2;
|
||||
if (i2 > _length) seg.stop = _length;
|
||||
_segment_runtimes[n].reset();
|
||||
}
|
||||
|
||||
void WS2812FX::resetSegments() {
|
||||
memset(_segments, 0, sizeof(_segments));
|
||||
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
|
||||
_segment_index = 0;
|
||||
_segments[0].mode = DEFAULT_MODE;
|
||||
_segments[0].colors[0] = DEFAULT_COLOR;
|
||||
_segments[0].start = 0;
|
||||
_segments[0].speed = DEFAULT_SPEED;
|
||||
_segments[0].stop = _length;
|
||||
_segments[0].setOption(0, 1); //select
|
||||
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
||||
{
|
||||
_segments[i].colors[0] = color_wheel(i*51);
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setIndividual(uint16_t i, uint32_t col)
|
||||
{
|
||||
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) return;
|
||||
if (i < _length) _locked[i] = true;
|
||||
}
|
||||
|
||||
void WS2812FX::lockRange(uint16_t i, uint16_t i2)
|
||||
{
|
||||
if (_modeUsesLock) return;
|
||||
for (uint16_t x = i; x < i2; x++)
|
||||
{
|
||||
if (x < _length) _locked[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::unlock(uint16_t i)
|
||||
{
|
||||
if (_modeUsesLock) return;
|
||||
if (i < _length) _locked[i] = false;
|
||||
}
|
||||
|
||||
void WS2812FX::unlockRange(uint16_t i, uint16_t i2)
|
||||
{
|
||||
if (_modeUsesLock) return;
|
||||
for (uint16_t x = i; x < i2; x++)
|
||||
{
|
||||
if (x < _length) _locked[x] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::unlockAll()
|
||||
{
|
||||
for (int i=0; i < _length; i++) _locked[i] = false;
|
||||
}
|
||||
|
||||
void WS2812FX::setTransitionMode(bool t)
|
||||
{
|
||||
_segment_index = getMainSegmentId();
|
||||
SEGMENT.setOption(7,t);
|
||||
if (!t) return;
|
||||
unsigned long waitMax = millis() + 20; //refresh after 20 ms if transition enabled
|
||||
if (SEGMENT.mode == FX_MODE_STATIC && SEGENV.next_time > waitMax) SEGENV.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;
|
||||
|
||||
uint32_t w1 = (color1 >> 24) & 0xff;
|
||||
uint32_t r1 = (color1 >> 16) & 0xff;
|
||||
uint32_t g1 = (color1 >> 8) & 0xff;
|
||||
uint32_t b1 = color1 & 0xff;
|
||||
|
||||
uint32_t w2 = (color2 >> 24) & 0xff;
|
||||
uint32_t r2 = (color2 >> 16) & 0xff;
|
||||
uint32_t g2 = (color2 >> 8) & 0xff;
|
||||
uint32_t b2 = color2 & 0xff;
|
||||
|
||||
uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8;
|
||||
uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8;
|
||||
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 = SEGCOLOR(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 = col_to_crgb(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;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t WS2812FX::triwave16(uint16_t in)
|
||||
{
|
||||
if (in < 0x8000) return in *2;
|
||||
return 0xFFFF - (in - 0x8000)*2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a value 0 to 255 in to get a color value.
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
uint32_t WS2812FX::crgb_to_col(CRGB fastled)
|
||||
{
|
||||
return (((uint32_t)fastled.red << 16) | ((uint32_t)fastled.green << 8) | fastled.blue);
|
||||
}
|
||||
|
||||
|
||||
CRGB WS2812FX::col_to_crgb(uint32_t color)
|
||||
{
|
||||
CRGB fastled_col;
|
||||
fastled_col.red = (color >> 16 & 0xFF);
|
||||
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_GLITTER && paletteIndex == 0) paletteIndex = 11;
|
||||
if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 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
|
||||
//case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break;
|
||||
|
||||
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 = col_to_crgb(SEGCOLOR(0));
|
||||
targetPalette = CRGBPalette16(prim); break;}
|
||||
case 3: {//based on primary
|
||||
//considering performance implications
|
||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||
CHSV prim_hsv = rgb2hsv_approximate(prim);
|
||||
targetPalette = CRGBPalette16(
|
||||
CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself
|
||||
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 = col_to_crgb(SEGCOLOR(0));
|
||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||
targetPalette = CRGBPalette16(sec,prim); break;}
|
||||
case 5: {//based on primary + secondary
|
||||
CRGB prim = col_to_crgb(SEGCOLOR(0));
|
||||
CRGB sec = col_to_crgb(SEGCOLOR(1));
|
||||
CRGB ter = col_to_crgb(SEGCOLOR(2));
|
||||
targetPalette = CRGBPalette16(ter,sec,prim); 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 SEGCOLOR(mcol); //WS2812FX default
|
||||
uint8_t paletteIndex = i;
|
||||
if (mapping) paletteIndex = map(i,SEGMENT.start,SEGMENT.stop-1,0,255);
|
||||
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||
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;
|
||||
}
|
||||
|
||||
bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b)
|
||||
{
|
||||
//if (a->start != b->start) return false;
|
||||
//if (a->stop != b->stop) return false;
|
||||
for (uint8_t i = 0; i < NUM_COLORS; i++)
|
||||
{
|
||||
if (a->colors[i] != b->colors[i]) return false;
|
||||
}
|
||||
if (a->mode != b->mode) return false;
|
||||
if (a->speed != b->speed) return false;
|
||||
if (a->intensity != b->intensity) return false;
|
||||
if (a->palette != b->palette) return false;
|
||||
//if (a->getOption(1) != b->getOption(1)) return false; //reverse
|
||||
return true;
|
||||
}
|
||||
|
||||
//gamma 2.4 lookup table used for color correction
|
||||
const byte gammaT[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
|
||||
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
|
||||
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
|
||||
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
|
||||
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
|
||||
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
|
||||
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
|
||||
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
|
||||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
|
||||
|
||||
uint8_t WS2812FX::gamma8(uint8_t b)
|
||||
{
|
||||
return gammaT[b];
|
||||
}
|
||||
|
||||
uint32_t WS2812FX::gamma32(uint32_t color)
|
||||
{
|
||||
if (!gammaCorrectCol) return color;
|
||||
uint8_t w = (color >> 24);
|
||||
uint8_t r = (color >> 16);
|
||||
uint8_t g = (color >> 8);
|
||||
uint8_t b = color;
|
||||
w = gammaT[w];
|
||||
r = gammaT[r];
|
||||
g = gammaT[g];
|
||||
b = gammaT[b];
|
||||
return ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||
}
|
||||
202
wled00/NpbWrapper.h
Normal file
202
wled00/NpbWrapper.h
Normal file
@@ -0,0 +1,202 @@
|
||||
//this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103
|
||||
#ifndef NpbWrapper_h
|
||||
#define NpbWrapper_h
|
||||
|
||||
//PIN CONFIGURATION
|
||||
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
|
||||
//#define USE_APA102 // Uncomment for using APA102 LEDs.
|
||||
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
|
||||
#define IR_PIN 4 //infrared pin (-1 to disable)
|
||||
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
|
||||
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)
|
||||
|
||||
#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on
|
||||
|
||||
#ifdef USE_APA102
|
||||
#define CLKPIN 0
|
||||
#define DATAPIN 2
|
||||
#if BTNPIN == CLKPIN || BTNPIN == DATAPIN
|
||||
#undef BTNPIN // Deactivate button pin if it conflicts with one of the APA102 pins.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//automatically uses the right driver method for each platform
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef USE_APA102
|
||||
#define PIXELMETHOD DotStarMethod
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod
|
||||
#endif
|
||||
#else //esp8266
|
||||
//autoselect the right method depending on strip pin
|
||||
#ifdef USE_APA102
|
||||
#define PIXELMETHOD DotStarMethod
|
||||
#elif LEDPIN == 2
|
||||
#define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus
|
||||
#elif LEDPIN == 3
|
||||
#define PIXELMETHOD NeoEsp8266Dma800KbpsMethod
|
||||
#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
|
||||
#ifdef USE_APA102
|
||||
#define PIXELFEATURE3 DotStarBgrFeature
|
||||
#define PIXELFEATURE4 DotStarLbgrFeature
|
||||
#else
|
||||
#define PIXELFEATURE3 NeoGrbFeature
|
||||
#define PIXELFEATURE4 NeoGrbwFeature
|
||||
#endif
|
||||
|
||||
|
||||
#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:
|
||||
#ifdef USE_APA102
|
||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
|
||||
#else
|
||||
_pGrb = new NeoPixelBrightnessBus<PIXELFEATURE3,PIXELMETHOD>(countPixels, LEDPIN);
|
||||
#endif
|
||||
_pGrb->Begin();
|
||||
break;
|
||||
|
||||
case NeoPixelType_Grbw:
|
||||
#ifdef USE_APA102
|
||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, CLKPIN, DATAPIN);
|
||||
#else
|
||||
_pGrbw = new NeoPixelBrightnessBus<PIXELFEATURE4,PIXELMETHOD>(countPixels, LEDPIN);
|
||||
#endif
|
||||
_pGrbw->Begin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Show()
|
||||
{
|
||||
switch (_type)
|
||||
{
|
||||
case NeoPixelType_Grb: _pGrb->Show(); break;
|
||||
case NeoPixelType_Grbw: _pGrbw->Show(); break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanShow() const
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: _pGrb->CanShow(); break;
|
||||
case NeoPixelType_Grbw: _pGrbw->CanShow(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetPixelColor(uint16_t indexPixel, RgbColor color)
|
||||
{
|
||||
switch (_type) {
|
||||
case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break;
|
||||
case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
2174
wled00/WS2812FX.cpp
2174
wled00/WS2812FX.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,422 +0,0 @@
|
||||
//#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
|
||||
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 to work with WLED - differs from Github WS2812FX
|
||||
*/
|
||||
|
||||
#ifndef WS2812FX_h
|
||||
#define WS2812FX_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <NeoPixelBrightnessBus.h>
|
||||
|
||||
#define DEFAULT_BRIGHTNESS 50
|
||||
#define DEFAULT_MODE 0
|
||||
#define DEFAULT_SPEED 150
|
||||
#define DEFAULT_COLOR 0xFFAA00
|
||||
|
||||
#define SPEED_MIN 0
|
||||
#define SPEED_MAX 255
|
||||
|
||||
#define BRIGHTNESS_MIN 0
|
||||
#define BRIGHTNESS_MAX 255
|
||||
|
||||
#define MODE_COUNT 58
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
#define FX_MODE_BREATH 2
|
||||
#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_DYNAMIC 7
|
||||
#define FX_MODE_RAINBOW 8
|
||||
#define FX_MODE_RAINBOW_CYCLE 9
|
||||
#define FX_MODE_SCAN 10
|
||||
#define FX_MODE_DUAL_SCAN 11
|
||||
#define FX_MODE_FADE 12
|
||||
#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_SPARKLE 20
|
||||
#define FX_MODE_FLASH_SPARKLE 21
|
||||
#define FX_MODE_HYPER_SPARKLE 22
|
||||
#define FX_MODE_STROBE 23
|
||||
#define FX_MODE_STROBE_RAINBOW 24
|
||||
#define FX_MODE_MULTI_STROBE 25
|
||||
#define FX_MODE_BLINK_RAINBOW 26
|
||||
#define FX_MODE_ANDROID 27
|
||||
#define FX_MODE_CHASE_COLOR 28
|
||||
#define FX_MODE_CHASE_RANDOM 29
|
||||
#define FX_MODE_CHASE_RAINBOW 30
|
||||
#define FX_MODE_CHASE_FLASH 31
|
||||
#define FX_MODE_CHASE_FLASH_RANDOM 32
|
||||
#define FX_MODE_CHASE_RAINBOW_WHITE 33
|
||||
#define FX_MODE_COLORFUL 34
|
||||
#define FX_MODE_TRAFFIC_LIGHT 35
|
||||
#define FX_MODE_COLOR_SWEEP_RANDOM 36
|
||||
#define FX_MODE_RUNNING_COLOR 37
|
||||
#define FX_MODE_RUNNING_RED_BLUE 38
|
||||
#define FX_MODE_RUNNING_RANDOM 39
|
||||
#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_MERRY_CHRISTMAS 44
|
||||
#define FX_MODE_FIRE_FLICKER 45
|
||||
#define FX_MODE_GRADIENT 46
|
||||
#define FX_MODE_LOADING 47
|
||||
#define FX_MODE_DUAL_COLOR_WIPE_IN_OUT 48
|
||||
#define FX_MODE_DUAL_COLOR_WIPE_IN_IN 49
|
||||
#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
|
||||
|
||||
|
||||
class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
typedef void (WS2812FX::*mode_ptr)(void);
|
||||
public:
|
||||
WS2812FX(uint16_t n) : NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD>(n,PIN) {
|
||||
|
||||
_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;
|
||||
_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_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;
|
||||
_reverseMode = false;
|
||||
_locked = new bool[n];
|
||||
_cronixieDigits = new byte[6];
|
||||
}
|
||||
|
||||
void
|
||||
show(void),
|
||||
setPixelColor(uint16_t i, byte r, byte g, byte b),
|
||||
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
|
||||
init(void),
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
unlockAll(void),
|
||||
setFastUpdateMode(bool b),
|
||||
trigger(void),
|
||||
setLedCount(uint16_t i),
|
||||
setFade(int sp);
|
||||
|
||||
bool
|
||||
isRunning(void),
|
||||
isLocked(int i);
|
||||
|
||||
byte
|
||||
get_random_wheel_index(byte),
|
||||
getMode(void),
|
||||
getSpeed(void),
|
||||
getIntensity(void),
|
||||
getBrightness(void),
|
||||
getModeCount(void);
|
||||
|
||||
uint32_t
|
||||
color_wheel(byte),
|
||||
getColor(void);
|
||||
|
||||
double
|
||||
getPowerEstimate(byte leds, uint32_t c, byte b),
|
||||
getSafePowerMultiplier(double safeMilliAmps, byte leds, uint32_t c, byte b);
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
begin(void),
|
||||
clear(void),
|
||||
setPixelColor(uint16_t i, uint32_t c),
|
||||
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
|
||||
dofade(void),
|
||||
strip_off(void),
|
||||
strip_off_respectLock(void),
|
||||
mode_static(void),
|
||||
mode_blink(void),
|
||||
mode_color_wipe(void),
|
||||
mode_color_wipe_random(void),
|
||||
mode_random_color(void),
|
||||
mode_easter(void),
|
||||
mode_dynamic(void),
|
||||
mode_breath(void),
|
||||
mode_fade(void),
|
||||
mode_scan(void),
|
||||
mode_dual_scan(void),
|
||||
mode_theater_chase(void),
|
||||
mode_theater_chase_rainbow(void),
|
||||
mode_rainbow(void),
|
||||
mode_rainbow_cycle(void),
|
||||
mode_running_lights(void),
|
||||
mode_twinkle(void),
|
||||
mode_twinkle_random(void),
|
||||
mode_twinkle_fade(void),
|
||||
mode_twinkle_fade_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),
|
||||
mode_chase_rainbow(void),
|
||||
mode_chase_flash(void),
|
||||
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_merry_christmas(void),
|
||||
mode_fire_flicker(void),
|
||||
mode_gradient(void),
|
||||
mode_loading(void),
|
||||
mode_dual_color_wipe_in_out(void),
|
||||
mode_dual_color_wipe_in_in(void),
|
||||
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);
|
||||
|
||||
bool
|
||||
_triggered,
|
||||
_fastStandard,
|
||||
_reverseMode,
|
||||
_cronixieMode,
|
||||
_cronixieBacklightEnabled,
|
||||
_cc_fs,
|
||||
_cc_fe,
|
||||
_running;
|
||||
|
||||
bool*
|
||||
_locked;
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
#endif
|
||||
129
wled00/__vm/.wled00.vsarduino.h
Normal file
129
wled00/__vm/.wled00.vsarduino.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Editor: https://www.visualmicro.com/
|
||||
This file is for intellisense purpose only.
|
||||
Visual micro (and the arduino ide) ignore this code during compilation. This code is automatically maintained by visualmicro, manual changes to this file will be overwritten
|
||||
The contents of the _vm sub folder can be deleted prior to publishing a project
|
||||
All non-arduino files created by visual micro and all visual studio project or solution files can be freely deleted and are not required to compile a sketch (do not delete your own code!).
|
||||
Note: debugger breakpoints are stored in '.sln' or '.asln' files, knowledge of last uploaded breakpoints is stored in the upload.vmps.xml file. Both files are required to continue a previous debug session without needing to compile and upload again
|
||||
|
||||
Hardware: ESP32 Dev Module, Platform=esp32, Package=esp32
|
||||
*/
|
||||
|
||||
#if defined(_VMICRO_INTELLISENSE)
|
||||
|
||||
#ifndef _VSARDUINO_H_
|
||||
#define _VSARDUINO_H_
|
||||
#define __ESP32_esp32__
|
||||
#define __ESP32_ESP32__
|
||||
#define ESP_PLATFORM
|
||||
#define HAVE_CONFIG_H
|
||||
#define F_CPU 240000000L
|
||||
#define ARDUINO 10809
|
||||
#define ARDUINO_ESP32_DEV
|
||||
#define ARDUINO_ARCH_ESP32
|
||||
#define ESP32
|
||||
#define CORE_DEBUG_LEVEL 0
|
||||
#define __cplusplus 201103L
|
||||
|
||||
#define _Pragma(x)
|
||||
#undef __cplusplus
|
||||
#define __cplusplus 201103L
|
||||
|
||||
#define __STDC__
|
||||
#define __ARM__
|
||||
#define __arm__
|
||||
#define __inline__
|
||||
#define __asm__(...)
|
||||
#define __extension__
|
||||
#define __ATTR_PURE__
|
||||
#define __ATTR_CONST__
|
||||
#define __volatile__
|
||||
|
||||
#define __ASM
|
||||
#define __INLINE
|
||||
#define __attribute__(noinline)
|
||||
|
||||
//#define _STD_BEGIN
|
||||
//#define EMIT
|
||||
#define WARNING
|
||||
#define _Lockit
|
||||
#define __CLR_OR_THIS_CALL
|
||||
#define C4005
|
||||
#define _NEW
|
||||
|
||||
typedef bool _Bool;
|
||||
typedef int _read;
|
||||
typedef int _seek;
|
||||
typedef int _write;
|
||||
typedef int _close;
|
||||
typedef int __cleanup;
|
||||
|
||||
//#define inline
|
||||
|
||||
#define __builtin_clz
|
||||
#define __builtin_clzl
|
||||
#define __builtin_clzll
|
||||
#define __builtin_labs
|
||||
#define __builtin_va_list
|
||||
typedef int __gnuc_va_list;
|
||||
|
||||
#define __ATOMIC_ACQ_REL
|
||||
|
||||
#define __CHAR_BIT__
|
||||
#define _EXFUN()
|
||||
|
||||
typedef unsigned char byte;
|
||||
extern "C" void __cxa_pure_virtual() {;}
|
||||
|
||||
typedef long __INTPTR_TYPE__ ;
|
||||
typedef long __UINTPTR_TYPE__ ;
|
||||
typedef long __SIZE_TYPE__ ;
|
||||
typedef long __PTRDIFF_TYPE__;
|
||||
|
||||
typedef long pthread_t;
|
||||
typedef long pthread_key_t;
|
||||
typedef long pthread_once_t;
|
||||
typedef long pthread_mutex_t;
|
||||
typedef long pthread_mutex_t;
|
||||
typedef long pthread_cond_t;
|
||||
|
||||
|
||||
|
||||
#include "arduino.h"
|
||||
#include <pins_arduino.h>
|
||||
|
||||
//#include "..\generic\Common.h"
|
||||
//#include "..\generic\pins_arduino.h"
|
||||
|
||||
//#undef F
|
||||
//#define F(string_literal) ((const PROGMEM char *)(string_literal))
|
||||
//#undef PSTR
|
||||
//#define PSTR(string_literal) ((const PROGMEM char *)(string_literal))
|
||||
//current vc++ does not understand this syntax so use older arduino example for intellisense
|
||||
//todo:move to the new clang/gcc project types.
|
||||
#define interrupts() sei()
|
||||
#define noInterrupts() cli()
|
||||
|
||||
#include "wled00.ino"
|
||||
#include "wled01_eeprom.ino"
|
||||
#include "wled02_xml.ino"
|
||||
#include "wled03_set.ino"
|
||||
#include "wled04_file.ino"
|
||||
#include "wled05_init.ino"
|
||||
#include "wled06_usermod.ino"
|
||||
#include "wled07_notify.ino"
|
||||
#include "wled08_led.ino"
|
||||
#include "wled09_button.ino"
|
||||
#include "wled10_ntp.ino"
|
||||
#include "wled11_ol.ino"
|
||||
#include "wled12_alexa.ino"
|
||||
#include "wled13_cronixie.ino"
|
||||
#include "wled14_colors.ino"
|
||||
#include "wled15_hue.ino"
|
||||
#include "wled16_blynk.ino"
|
||||
#include "wled17_mqtt.ino"
|
||||
#include "wled18_server.ino"
|
||||
#include "wled19_json.ino"
|
||||
#include "wled20_ir.ino"
|
||||
#endif
|
||||
#endif
|
||||
12
wled00/__vm/Compile.vmps.xml
Normal file
12
wled00/__vm/Compile.vmps.xml
Normal file
File diff suppressed because one or more lines are too long
9
wled00/__vm/Configuration.Release.vmps.xml
Normal file
9
wled00/__vm/Configuration.Release.vmps.xml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
100
wled00/data/jsontest.htm
Normal file
100
wled00/data/jsontest.htm
Normal file
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>JSON client</title>
|
||||
<style>
|
||||
:root {
|
||||
--bCol:#333;--cCol:#222;--dCol:#666;--tCol:#fff;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana, sans-serif;
|
||||
text-align: center;
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
margin: 20px;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
button {
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
border: 0.3ch solid var(--cCol);
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
input {
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
border: 0.5ch solid var(--cCol);
|
||||
width: 100%;
|
||||
}
|
||||
h1{
|
||||
margin: 0px;
|
||||
font-size: 20px;
|
||||
}
|
||||
h2{
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
form{
|
||||
background: var(--bCol);
|
||||
width: 500px;
|
||||
padding: 20px;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
textarea{
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
padding-top: 10px;
|
||||
width: 100%;
|
||||
font-family: monaco,monospace;
|
||||
font-size: 12px;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form name="cf">
|
||||
<h1>JSON API test tool</h1>
|
||||
<h2>URL:</h2>
|
||||
<input name="cu" type="text" size="60" value="http://192.168.4.1/json">
|
||||
<div id="buttons">
|
||||
<button type="button" onclick="rq('GET')">GET</button>
|
||||
<button type="button" onclick="rq('POST')">POST</button>
|
||||
</div>
|
||||
<h2>Body:</h2>
|
||||
<textarea name="bd" rows="8" cols="100"></textarea>
|
||||
<h2>Response:</h2>
|
||||
<textarea name="rsp" rows="25" cols="100"></textarea>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
function rq(cm)
|
||||
{
|
||||
var h = new XMLHttpRequest();
|
||||
h.open(cm, document.cf.cu.value, true);
|
||||
h.onreadystatechange = function()
|
||||
{
|
||||
if(h.readyState == 4)
|
||||
{
|
||||
if(h.status==200)
|
||||
{
|
||||
document.cf.rsp.value="Bad JSON: "+h.responseText
|
||||
document.cf.rsp.value=JSON.stringify(JSON.parse(h.responseText), null, '\t');
|
||||
}
|
||||
else
|
||||
{
|
||||
document.cf.rsp.value="Error "+h.status+"\r\n\n"+h.responseText;
|
||||
}
|
||||
}
|
||||
}
|
||||
h.send(document.cf.bd.value);
|
||||
}
|
||||
</script>
|
||||
64
wled00/data/liveview.htm
Normal file
64
wled00/data/liveview.htm
Normal file
@@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<meta name="theme-color" content="#222222">
|
||||
<title>WLED Live Preview</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#canv {
|
||||
background: black;
|
||||
filter: brightness(175%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="canv" />
|
||||
<script>
|
||||
update();
|
||||
|
||||
var tmout = null;
|
||||
function update()
|
||||
{
|
||||
if (document.hidden) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 250);
|
||||
return;
|
||||
}
|
||||
fetch('/json/live')
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 2500);
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then(json => {
|
||||
var str = "linear-gradient(90deg,";
|
||||
var len = json.leds.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
var leddata = json.leds[i];
|
||||
if (leddata.length > 6) leddata = leddata.substring(2);
|
||||
str += "#" + leddata;
|
||||
if (i < len -1) str += ","
|
||||
}
|
||||
str += ")";
|
||||
document.getElementById("canv").style.background = str;
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 40);
|
||||
})
|
||||
.catch(function (error) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 2500);
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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>
|
||||
@@ -22,7 +23,7 @@
|
||||
--tCol: #328CC1;
|
||||
--cFn: Verdana;
|
||||
}
|
||||
button {
|
||||
.bt {
|
||||
background: var(--bCol);
|
||||
color: var(--tCol);
|
||||
border: 0.3ch solid var(--bCol);
|
||||
@@ -33,6 +34,9 @@
|
||||
margin: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
input[type=file] {
|
||||
font-size: 16px;
|
||||
}
|
||||
body {
|
||||
font-family: var(--cFn), sans-serif;
|
||||
text-align: center;
|
||||
@@ -46,6 +50,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<h2>Sample message.</h2>
|
||||
Sample detail.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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.
4
wled00/data/update.htm
Normal file
4
wled00/data/update.htm
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta content='width=device-width' name='viewport'><title>WLED Message</title><script>function B(){window.history.back()}</script>
|
||||
<style>:root{--aCol:#D9B310;--bCol:#0B3C5D;--cCol:#1D2731;--dCol:#328CC1;--sCol:#000;--tCol:#328CC1;--cFn:Verdana;}.bt{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%}</style></head>
|
||||
<body><h2>WLED Software Update</h2>Installed version: 0.8.5-dev<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>
|
||||
@@ -1,28 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content='width=device-width' name='viewport'>
|
||||
<meta name="theme-color" content="#333333">
|
||||
<title>WLED Setup</title>
|
||||
<style>
|
||||
:root {
|
||||
--aCol: #D9B310;
|
||||
--bCol: #0B3C5D;
|
||||
--cCol: #1D2731;
|
||||
--dCol: #328CC1;
|
||||
--sCol: #000;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana, Helvetica, sans-serif;
|
||||
text-align: center;
|
||||
background: linear-gradient(var(--bCol),black);
|
||||
height: 100%;
|
||||
background-color: #333;
|
||||
margin: 0;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
color: var(--dCol);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
button {
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
margin: 10px;
|
||||
width: 230px;
|
||||
text-transform: uppercase;
|
||||
font-family: helvetica;
|
||||
font-size: 19px;
|
||||
background-color: #222;
|
||||
color: white;
|
||||
border: 0px solid white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: var(--dCol);
|
||||
fill: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -35,10 +43,12 @@
|
||||
<svg><use xlink:href="#lnr-smile"></use></svg>
|
||||
<h1>Welcome to WLED!</h1>
|
||||
<h3>Thank you for installing my application!</h3>
|
||||
Take a quick look at the <a href="https://github.com/Aircoookie/WLED/wiki" target="_blank">wiki</a>!<br>
|
||||
If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br>
|
||||
<b>Next steps:</b><br><br>
|
||||
Connect the module to your local WiFi <a href="/settings/wifi">here</a>!<br><br>
|
||||
<i>Just trying this out in AP mode?</i> <a href="/sliders">Here are the controls.</a><br>
|
||||
Connect the module to your local WiFi here!<br>
|
||||
<button onclick="window.location.href='/settings/wifi'">WiFi settings</button><br>
|
||||
<i>Just trying this out in AP mode?</i><br>
|
||||
<button onclick="window.location.href='/sliders'">To the controls!</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
103
wled00/html_other.h
Normal file
103
wled00/html_other.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Various pages
|
||||
*/
|
||||
|
||||
//USER HTML HERE (/u subpage)
|
||||
const char PAGE_usermod[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><body>No usermod custom web page set.</body></html>)=====";
|
||||
|
||||
|
||||
//server message
|
||||
const char PAGE_msg[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta content='width=device-width' name='viewport'>
|
||||
<title>WLED Message</title>
|
||||
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
|
||||
<style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}</style></head>
|
||||
<body><h2>%MSG%</body></html>)=====";
|
||||
|
||||
|
||||
//firmware update page
|
||||
const char PAGE_update[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta content='width=device-width' name='viewport'><title>WLED Update</title><script>function B(){window.history.back()}</script>
|
||||
<style>.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}</style></head>
|
||||
<body><h2>WLED Software Update</h2>Installed version: 0.9.0-b1<br>Download the latest binary: <a href="https://github.com/Aircoookie/WLED/releases"><img src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"></a><br><form method='POST' action='/update' enctype='multipart/form-data'><input type='file' class="bt" name='update' required><br><input type='submit' class="bt" value='Update!'></form><button type="button" class="bt" onclick="B()">Back</button></body></html>)=====";
|
||||
|
||||
|
||||
//new user welcome page
|
||||
const char PAGE_welcome[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset=utf-8><meta content='width=device-width' name=viewport><meta name=theme-color content=#333333><title>WLED Setup</title> <style>body{font-family:Verdana,Helvetica,sans-serif;text-align:center;background-color:#333;margin:0;color:#fff}button{outline:0;cursor:pointer}.btn{padding:8px;margin:10px;width:230px;text-transform:uppercase;font-family:helvetica;font-size:19px;background-color:#222;color:white;border:0 solid white;border-radius:5px}svg{fill:#fff}</style></head>
|
||||
<body> <svg style=position:absolute;width:0;height:0;overflow:hidden version=1.1 xmlns=http://www.w3.org/2000/svg> <defs> <symbol id=lnr-smile viewBox="0 0 1024 1024"><path d="M486.4 1024c-129.922 0-252.067-50.594-343.936-142.464s-142.464-214.014-142.464-343.936c0-129.923 50.595-252.067 142.464-343.936s214.013-142.464 343.936-142.464c129.922 0 252.067 50.595 343.936 142.464s142.464 214.014 142.464 343.936-50.594 252.067-142.464 343.936c-91.869 91.87-214.014 142.464-343.936 142.464zM486.4 102.4c-239.97 0-435.2 195.23-435.2 435.2s195.23 435.2 435.2 435.2 435.2-195.23 435.2-435.2-195.23-435.2-435.2-435.2z"></path><path d="M332.8 409.6c-42.347 0-76.8-34.453-76.8-76.8s34.453-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.453 76.8-76.8 76.8zM332.8 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M640 409.6c-42.349 0-76.8-34.453-76.8-76.8s34.451-76.8 76.8-76.8 76.8 34.453 76.8 76.8-34.451 76.8-76.8 76.8zM640 307.2c-14.115 0-25.6 11.485-25.6 25.6s11.485 25.6 25.6 25.6 25.6-11.485 25.6-25.6-11.485-25.6-25.6-25.6z"></path><path d="M486.4 870.4c-183.506 0-332.8-149.294-332.8-332.8 0-14.139 11.462-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 155.275 126.325 281.6 281.6 281.6s281.6-126.325 281.6-281.6c0-14.139 11.461-25.6 25.6-25.6s25.6 11.461 25.6 25.6c0 183.506-149.294 332.8-332.8 332.8z"></path></symbol> </defs></svg> <br><br>
|
||||
<svg><use xlink:href=#lnr-smile></use></svg><h1>Welcome to WLED!</h1><h3>Thank you for installing my application!</h3> If you encounter a bug or have a question/feature suggestion, feel free to open a GitHub issue!<br><br> <b>Next steps:</b><br><br> Connect the module to your local WiFi here!<br> <button class=btn onclick="window.location.href='/settings/wifi'">WiFi settings</button><br> <i>Just trying this out in AP mode?</i><br> <button class=btn onclick="window.location.href='/sliders'">To the controls!</button></body></html>)=====";
|
||||
|
||||
|
||||
//liveview
|
||||
const char PAGE_liveview[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta name=viewport content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||
<meta charset=utf-8>
|
||||
<meta name=theme-color content=#222222>
|
||||
<title>WLED Live Preview</title>
|
||||
<style>
|
||||
body {margin: 0;}
|
||||
#canv {background: black;filter: brightness(175%);width: 100%;height: 100%;position: absolute;}
|
||||
</style></head>
|
||||
<body>
|
||||
<div id="canv" />
|
||||
<script>
|
||||
update();
|
||||
var tmout = null;
|
||||
function update()
|
||||
{
|
||||
if (document.hidden) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 250);
|
||||
return;
|
||||
}
|
||||
fetch('/json/live')
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 2500);
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then(json => {
|
||||
var str = "linear-gradient(90deg,";
|
||||
var len = json.leds.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
var leddata = json.leds[i];
|
||||
if (leddata.length > 6) leddata = leddata.substring(2);
|
||||
str += "#" + leddata;
|
||||
if (i < len -1) str += ","
|
||||
}
|
||||
str += ")";
|
||||
document.getElementById("canv").style.background = str;
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 40);
|
||||
})
|
||||
.catch(function (error) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 2500);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body></html>)=====";
|
||||
|
||||
|
||||
/*
|
||||
* favicon
|
||||
*/
|
||||
const uint8_t favicon[] PROGMEM = {
|
||||
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x00,
|
||||
0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x89, 0x50,
|
||||
0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48,
|
||||
0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06,
|
||||
0x00, 0x00, 0x00, 0x1F, 0xF3, 0xFF, 0x61, 0x00, 0x00, 0x00, 0x4D, 0x49,
|
||||
0x44, 0x41, 0x54, 0x38, 0x8D, 0x63, 0xFC, 0xFF, 0xFF, 0x3F, 0x03, 0xB1,
|
||||
0x80, 0xD1, 0x9E, 0x01, 0x43, 0x31, 0x13, 0xD1, 0xBA, 0x71, 0x00, 0x8A,
|
||||
0x0D, 0x60, 0x21, 0xA4, 0x00, 0xD9, 0xD9, 0xFF, 0x0F, 0x32, 0x30, 0x52,
|
||||
0xDD, 0x05, 0xB4, 0xF1, 0x02, 0xB6, 0xD0, 0xA6, 0x99, 0x0B, 0x68, 0x1F,
|
||||
0x0B, 0xD8, 0x42, 0x9E, 0xAA, 0x2E, 0xA0, 0xD8, 0x00, 0x46, 0x06, 0x3B,
|
||||
0xCC, 0xCC, 0x40, 0xC8, 0xD9, 0x54, 0x75, 0x01, 0xE5, 0x5E, 0x20, 0x25,
|
||||
0x3B, 0x63, 0x03, 0x00, 0x3E, 0xB7, 0x11, 0x5A, 0x8D, 0x1C, 0x07, 0xB4,
|
||||
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
|
||||
};
|
||||
379
wled00/html_settings.h
Normal file
379
wled00/html_settings.h
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Settings html
|
||||
*/
|
||||
|
||||
//common CSS of settings pages
|
||||
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:0.5ch solid #333}td{padding:2px;}</style>)=====";
|
||||
|
||||
|
||||
//settings menu
|
||||
const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><title>WLED Settings</title><style>body{text-align:center;background:#222;height:100%;margin:0}html{--h:11.55vh}button{background:#333;color:#fff;font-family:Verdana,Helvetica,sans-serif;border:.3ch solid #333;display:inline-block;font-size:8vmin;height:var(--h);width:95%;margin-top:2.4vh}</style>
|
||||
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script></head>
|
||||
<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>
|
||||
<form action=/settings/sync><button type=submit>Sync Interfaces</button></form>
|
||||
<form action=/settings/time><button type=submit>Time & Macros</button></form>
|
||||
<form action=/settings/sec><button type=submit>Security & Updates</button></form>
|
||||
</body></html>)=====";
|
||||
|
||||
|
||||
//wifi settings
|
||||
const char PAGE_settings_wifi[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8">
|
||||
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d=document;
|
||||
%CSS%%SCSS%</head><body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button><hr>
|
||||
<h2>WiFi setup</h2>
|
||||
<h3>Connect to existing network</h3>
|
||||
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
|
||||
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
|
||||
Static IP (leave at 0.0.0.0 for DHCP):<br>
|
||||
<input name="I0" type="number" min="0" max="255" required> .
|
||||
<input name="I1" type="number" min="0" max="255" required> .
|
||||
<input name="I2" type="number" min="0" max="255" required> .
|
||||
<input name="I3" type="number" min="0" max="255" required><br>
|
||||
Static gateway:<br>
|
||||
<input name="G0" type="number" min="0" max="255" required> .
|
||||
<input name="G1" type="number" min="0" max="255" required> .
|
||||
<input name="G2" type="number" min="0" max="255" required> .
|
||||
<input name="G3" type="number" min="0" max="255" required><br>
|
||||
Static subnet mask:<br>
|
||||
<input name="S0" type="number" min="0" max="255" required> .
|
||||
<input name="S1" type="number" min="0" max="255" required> .
|
||||
<input name="S2" type="number" min="0" max="255" required> .
|
||||
<input name="S3" type="number" min="0" max="255" required><br>
|
||||
mDNS address (leave empty for no mDNS):<br/>
|
||||
http:// <input name="CM" maxlength="32"> .local<br>
|
||||
Client IP: <span class="sip"> Not connected </span><br>
|
||||
<h3>Configure Access Point</h3>
|
||||
AP name (SSID):<br><input name="AS" maxlength="32"><br>
|
||||
Hide AP name: <input type="checkbox" name="AH"><br>
|
||||
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63"><br>
|
||||
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
|
||||
AP opens:
|
||||
<select name="AB">
|
||||
<option value="0">No connection after boot</option>
|
||||
<option value="1">Disconnected</option>
|
||||
<option value="2">Always</option>
|
||||
<option value="3">Never (not recommended)</option></select><br>
|
||||
AP IP: <span class="sip"> Not active </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Connect</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>)=====";
|
||||
|
||||
|
||||
//LED settings
|
||||
const char PAGE_settings_leds[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta charset=utf-8>
|
||||
<meta name=viewport content="width=500">
|
||||
<title>LED Settings</title>
|
||||
<script>var d=document,laprev=55;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings")}function B(){window.open("/settings","_self")}function S(){GetV();setABL()}function enABL(){var a=d.getElementById("able").checked;d.Sf.LA.value=(a)?laprev:0;d.getElementById("abl").style.display=(a)?"inline":"none";d.getElementById("psu2").style.display=(a)?"inline":"none";if(d.Sf.LA.value>0){setABL()}}function enLA(){var a=d.Sf.LAsel.value;d.Sf.LA.value=a;d.getElementById("LAdis").style.display=(a==50)?"inline":"none";UI()}function setABL(){d.getElementById("able").checked=true;d.Sf.LAsel.value=50;switch(parseInt(d.Sf.LA.value)){case 0:d.getElementById("able").checked=false;enABL();break;case 30:d.Sf.LAsel.value=30;break;case 35:d.Sf.LAsel.value=35;break;case 55:d.Sf.LAsel.value=55;break;default:d.getElementById("LAdis").style.display="inline"}UI()}function UI(){var b=d.querySelectorAll(".wc"),a=b.length;for(i=0;i<a;i++){b[i].style.display=(d.getElementById("rgbw").checked)?"inline":"none"}d.getElementById("ledwarning").style.display=(d.Sf.LC.value>1000)?"inline":"none";d.getElementById("ampwarning").style.display=(d.Sf.MA.value>7200)?"inline":"none";if(d.Sf.LA.value>0){laprev=d.Sf.LA.value}var j=Math.ceil((100+d.Sf.LC.value*laprev)/500)/2;j=(j>5)?Math.ceil(j):j;var g="";var e=(d.Sf.LAsel.value==30);if(j<1.02&&!e){g="ESP 5V pin with 1A USB supply"}else{g+=e?"12V ":"5V ";g+=j;g+="A supply connected to LEDs"}var h=Math.ceil((100+d.Sf.LC.value*laprev)/1500)/2;h=(h>5)?Math.ceil(h):h;var c="(for most effects, ~";c+=h;c+="A is enough)<br>";d.getElementById("psu").innerHTML=g;d.getElementById("psu2").innerHTML=c}function GetV(){var d=document;
|
||||
%CSS%%SCSS%</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: <input name=LC type=number min=1 max=1500 oninput=UI() required><br>
|
||||
<div id=ledwarning style=color:orange;display:none>
|
||||
⚠ You might run into stability or lag issues.<br>
|
||||
Use less than 1000 LEDs per ESP for the best experience!<br>
|
||||
</div>
|
||||
<i>Recommended power supply for brightest white:</i><br>
|
||||
<b><span id=psu>?</span></b><br>
|
||||
<span id=psu2><br></span>
|
||||
<br>
|
||||
Enable automatic brightness limiter: <input type=checkbox name=ABen onchange=enABL() id=able><br>
|
||||
<div id=abl>
|
||||
Maximum Current: <input name=MA type=number min=250 max=65000 oninput=UI() required> mA<br>
|
||||
<div id=ampwarning style=color:orange;display:none>
|
||||
⚠ Your power supply provides high current.<br>
|
||||
To improve the safety of your setup,<br>
|
||||
please use thick cables,<br>
|
||||
multiple power injection points and a fuse!<br>
|
||||
</div>
|
||||
<i>Automatically limits brightness to stay close to the limit.<br>
|
||||
Keep at <1A if powering LEDs directly from the ESP 5V pin!<br>
|
||||
If you are using an external power supply, enter its rating.<br>
|
||||
(Current estimated usage: <span class=pow>unknown</span>)</i><br><br>
|
||||
LED voltage (Max. current for a single LED):<br>
|
||||
<select name=LAsel onchange=enLA()>
|
||||
<option value=55 selected>5V default (55mA)</option>
|
||||
<option value=35>5V efficient (35mA)</option>
|
||||
<option value=30>12V (30mA)</option>
|
||||
<option value=50>Custom</option>
|
||||
</select><br>
|
||||
<span id=LAdis style=display:none>Custom max. current per LED: <input name=LA type=number min=0 max=255 id=la oninput=UI() required> mA<br></span>
|
||||
<i>Keep at default if you are unsure about your type of LEDs.</i><br>
|
||||
</div>
|
||||
<br>
|
||||
LEDs are 4-channel type (RGBW): <input type=checkbox name=EW onchange=UI() id=rgbw><br>
|
||||
<span class=wc>
|
||||
Auto-calculate white channel from RGB: <input type=checkbox name=AW><br></span>
|
||||
Color order:
|
||||
<select name=CO>
|
||||
<option value=0>GRB</option>
|
||||
<option value=1>RGB</option>
|
||||
<option value=2>BRG</option>
|
||||
<option value=3>RBG</option>
|
||||
</select>
|
||||
<h3>Defaults</h3>
|
||||
Turn LEDs on after power up/reset: <input type=checkbox name=BO><br>
|
||||
Default brightness: <input name=CA type=number min=0 max=255 required> (0-255)<br><br>
|
||||
Apply preset <input name=BP type=number min=0 max=16 required> at boot (0 uses defaults)
|
||||
<br>- <i>or</i> -<br>
|
||||
Set current preset cycle setting as boot default: <input type=checkbox name=PC><br><br>
|
||||
Use Gamma correction for color: <input type=checkbox name=GC> (strongly recommended)<br>
|
||||
Use Gamma correction for brightness: <input type=checkbox name=GB> (not recommended)<br><br>
|
||||
Brightness factor: <input name=BF type=number min=1 max=255 required> %
|
||||
<h3>Transitions</h3>
|
||||
Crossfade: <input type=checkbox name=TF><br>
|
||||
Transition Time: <input name=TD maxlength=5 size=2> ms<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>
|
||||
Skip first LED: <input type=checkbox name=SL><br>
|
||||
Disable repeating N LEDs: <input type=number min=0 max=255 name=DL><br>
|
||||
(Turns off N LEDs between each lit one, spacing out effects)<hr>
|
||||
<button type=button onclick=B()>Back</button><button type=submit>Save</button>
|
||||
</form></body></html>)=====";
|
||||
|
||||
|
||||
//User Interface settings
|
||||
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><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;
|
||||
%CSS%%SCSS%</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>
|
||||
Sync button toggles both send and receive: <input type="checkbox" name="ST"><br><br>
|
||||
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>)=====";
|
||||
|
||||
|
||||
//sync settings
|
||||
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Sync Settings</title>
|
||||
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d=document;
|
||||
%CSS%%SCSS%</head>
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>Sync setup</h2>
|
||||
<h3>Button setup</h3>
|
||||
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" type="number" min="1" max="65535" required><br>
|
||||
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
||||
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 Macro notifications: <input type="checkbox" name="SM"><br>
|
||||
Send notifications twice: <input type="checkbox" name="S2">
|
||||
<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>
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><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 may impact 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>
|
||||
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||
Broker: <input name="MS" maxlength="32">
|
||||
Port: <input name="MQPORT" type="number" min="1" max="65535" required><br>
|
||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||
Never use the MQTT password for another service!</b><br>
|
||||
Username: <input name="MQUSER" maxlength="40"><br>
|
||||
Password: <input type="password" input name="MQPASS" maxlength="40"><br>
|
||||
Client ID: <input name="MQCID" maxlength="40"><br>
|
||||
Device Topic: <input name="MD" maxlength="32"><br>
|
||||
Group Topic: <input name="MG" maxlength="32"><br>
|
||||
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
||||
<h3>Philips Hue</h3>
|
||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
|
||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||
Hue Bridge IP:<br>
|
||||
<input name="H0" type="number" min="0" max="255" required> .
|
||||
<input name="H1" type="number" min="0" max="255" required> .
|
||||
<input name="H2" type="number" min="0" max="255" required> .
|
||||
<input name="H3" type="number" min="0" max="255" required><br>
|
||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||
(when first connecting)<br>
|
||||
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>)=====";
|
||||
|
||||
|
||||
//time and macro settings
|
||||
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8"><title>Time Settings</title>
|
||||
<script>var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){BTa();GetV();Cs();FC();}function gId(s){return d.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}
|
||||
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(){
|
||||
%CSS%%SCSS%</head>
|
||||
<body onload="S()">
|
||||
<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>
|
||||
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
||||
<input name="NS" maxlength="32"><br>
|
||||
Use 24h format: <input type="checkbox" name="CF"><br>
|
||||
Time zone:
|
||||
<select name="TZ">
|
||||
<option value="0" selected>GMT(UTC)</option>
|
||||
<option value="1">GMT/BST</option>
|
||||
<option value="2">CET/CEST</option>
|
||||
<option value="3">EET/EEST</option>
|
||||
<option value="4">US-EST/EDT</option>
|
||||
<option value="5">US-CST/CDT</option>
|
||||
<option value="6">US-MST/MDT</option>
|
||||
<option value="7">US-AZ</option>
|
||||
<option value="8">US-PST/PDT</option>
|
||||
<option value="9">CST(AWST)</option>
|
||||
<option value="10">JST(KST)</option>
|
||||
<option value="11">AEST/AEDT</option>
|
||||
<option value="12">NZST/NZDT</option>
|
||||
<option value="13">North Korea</option>
|
||||
<option value="14">IST (India)</option>
|
||||
</select><br>
|
||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||
Current local time is <span class="times">unknown</span>.
|
||||
<h3>Clock</h3>
|
||||
Clock Overlay:
|
||||
<select name="OL" onchange="Cs()">
|
||||
<option value="0" id="cn" selected>None</option>
|
||||
<option value="1" id="ca">Analog Clock</option>
|
||||
<option value="2" disabled>-</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>
|
||||
<div id="cac">
|
||||
12h LED: <input name="OM" type="number" min="0" max="255" required><br>
|
||||
Show 5min marks: <input type="checkbox" name="O5"><br></div>
|
||||
Seconds (as trail): <input type="checkbox" name="OS"><br>
|
||||
</div>
|
||||
<div id="ccc">
|
||||
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:<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>
|
||||
1: <input name="M1" maxlength="64"><br>
|
||||
2: <input name="M2" maxlength="64"><br>
|
||||
3: <input name="M3" maxlength="64"><br>
|
||||
4: <input name="M4" maxlength="64"><br>
|
||||
5: <input name="M5" maxlength="64"><br>
|
||||
6: <input name="M6" maxlength="64"><br>
|
||||
7: <input name="M7" maxlength="64"><br>
|
||||
8: <input name="M8" maxlength="64"><br>
|
||||
9: <input name="M9" maxlength="64"><br>
|
||||
10: <input name="M10" maxlength="64"><br>
|
||||
11: <input name="M11" maxlength="64"><br>
|
||||
12: <input name="M12" maxlength="64"><br>
|
||||
13: <input name="M13" maxlength="64"><br>
|
||||
14: <input name="M14" maxlength="64"><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>
|
||||
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 short press macro: <input name="MP" type="number" min="0" max="16" required><br>
|
||||
Long press: <input name="ML" type="number" min="0" max="16" required> Double press: <input name="MD" 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><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>)=====";
|
||||
|
||||
|
||||
//security settings and about
|
||||
const char PAGE_settings_sec[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
<html><head><meta name="viewport" content="width=500"><meta charset="utf-8">
|
||||
<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;
|
||||
%CSS%%SCSS%</head>
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
|
||||
<h2>Security & Update setup</h2>
|
||||
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>
|
||||
<b>Disable OTA when not in use, otherwise an attacker can reflash device software!</b><br>
|
||||
<i>Settings on this page are only changable if OTA lock is disabled!</i><br>
|
||||
Deny access to WiFi settings if locked: <input type="checkbox" name="OW"><br><br>
|
||||
Factory reset: <input type="checkbox" name="RS"><br>
|
||||
All EEPROM content (settings) will be erased.<br><br>
|
||||
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
|
||||
<h3>Software Update</h3>
|
||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||
<h3>About</h3>
|
||||
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.9.0-b1<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>
|
||||
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>)=====";
|
||||
1459
wled00/html_ui.h
Normal file
1459
wled00/html_ui.h
Normal file
File diff suppressed because it is too large
Load Diff
185
wled00/htmls00.h
185
wled00/htmls00.h
File diff suppressed because one or more lines are too long
354
wled00/htmls01.h
354
wled00/htmls01.h
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
)=====";
|
||||
|
||||
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>
|
||||
</head>
|
||||
<body>
|
||||
<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>
|
||||
<form action=/settings/sync><button type=submit>Sync Interfaces</button></form>
|
||||
<form action=/settings/time><button type=submit>Time & Macros</button></form>
|
||||
<form action=/settings/sec><button type=submit>Security & Updates</button></form>
|
||||
</body>
|
||||
</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>
|
||||
<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>WiFi setup</h2>
|
||||
<h3>Connect to existing network</h3>
|
||||
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
|
||||
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
|
||||
Static IP (leave at 0.0.0.0 for DHCP):<br>
|
||||
<input name="I0" type="number" min="0" max="255" required> .
|
||||
<input name="I1" type="number" min="0" max="255" required> .
|
||||
<input name="I2" type="number" min="0" max="255" required> .
|
||||
<input name="I3" type="number" min="0" max="255" required><br>
|
||||
Static gateway:<br>
|
||||
<input name="G0" type="number" min="0" max="255" required> .
|
||||
<input name="G1" type="number" min="0" max="255" required> .
|
||||
<input name="G2" type="number" min="0" max="255" required> .
|
||||
<input name="G3" type="number" min="0" max="255" required><br>
|
||||
Static subnet mask:<br>
|
||||
<input name="S0" type="number" min="0" max="255" required> .
|
||||
<input name="S1" type="number" min="0" max="255" required> .
|
||||
<input name="S2" type="number" min="0" max="255" required> .
|
||||
<input name="S3" type="number" min="0" max="255" required><br>
|
||||
mDNS address (leave empty for no mDNS):<br/>
|
||||
http:// <input name="CM" maxlength="32"> .local<br>
|
||||
Try connecting before opening AP for: <input name="AT" type="number" min="0" max="255" required> s <br>
|
||||
Client IP: <span class="sip"> Not connected </span><br>
|
||||
<h3>Configure Access Point</h3>
|
||||
AP SSID (leave empty for no AP):<br> <input name="AS" maxlength="32"><br>
|
||||
Hide AP name: <input type="checkbox" name="AH"><br>
|
||||
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63"> <br>
|
||||
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
|
||||
AP IP: <span class="sip"> Not active </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||
</form>
|
||||
</body>
|
||||
</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()">
|
||||
<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>
|
||||
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>
|
||||
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>
|
||||
<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>
|
||||
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 Time: <input name="TD" maxlength="5" size="2"> ms
|
||||
<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>
|
||||
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>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
|
||||
const char PAGE_settings_ui0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<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>
|
||||
<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>
|
||||
Use HSB sliders instead of RGB by default: <input type="checkbox" name="MD"><br>
|
||||
Color Theme:
|
||||
<select name="TH" onchange="Ct()">
|
||||
<option value="0" selected>Night</option>
|
||||
<option value="1">Modern</option>
|
||||
<option value="2">Bright</option>
|
||||
<option value="3">Wine</option>
|
||||
<option value="4">Electric</option>
|
||||
<option value="5">Mint</option>
|
||||
<option value="6">Amber</option>
|
||||
<option value="7">Club</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="14">The End</option>
|
||||
<option value="15" id="co">Custom</option>
|
||||
</select><br>
|
||||
<div id="cth">
|
||||
Please specify your custom hex colors (e.g. FF0000 for red)<br>
|
||||
Custom accent color: <input maxlength=9 name="C0"><br>
|
||||
Custom background: <input maxlength=9 name="C1"><br>
|
||||
Custom panel color: <input maxlength=9 name="C2"><br>
|
||||
Custom icon color: <input maxlength=9 name="C3"><br>
|
||||
Custom shadow: <input maxlength=9 name="C4"><br>
|
||||
Custom text color: <input maxlength=9 name="C5"><br></div>
|
||||
Use font: <input maxlength=32 name="CF"><br>
|
||||
Make sure the font you use is installed on your system!<br>
|
||||
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</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>
|
||||
<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">
|
||||
<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>
|
||||
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">
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||
Alexa invocation name: <input name="AI" maxlength="32"><br>
|
||||
<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>
|
||||
Hue Bridge IP:<br>
|
||||
<input name="H0" type="number" min="0" max="255" required> .
|
||||
<input name="H1" type="number" min="0" max="255" required> .
|
||||
<input name="H2" type="number" min="0" max="255" required> .
|
||||
<input name="H3" type="number" min="0" max="255" required><br>
|
||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||
(when first connecting)<br>
|
||||
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>
|
||||
)=====";
|
||||
|
||||
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>
|
||||
<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>Time setup</h2>
|
||||
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
||||
Use 24h format: <input type="checkbox" name="CF"><br>
|
||||
Time zone:
|
||||
<select name="TZ">
|
||||
<option value="0" selected>GMT(UTC)</option>
|
||||
<option value="1">GMT/BST</option>
|
||||
<option value="2">CET/CEST</option>
|
||||
<option value="3">EET/EEST</option>
|
||||
<option value="4">US-EST/EDT</option>
|
||||
<option value="5">US-CST/CDT</option>
|
||||
<option value="6">US-MST/MDT</option>
|
||||
<option value="7">US-AZ</option>
|
||||
<option value="8">US-PST/PDT</option>
|
||||
<option value="9">CST(AWST)</option>
|
||||
<option value="10">JST(KST)</option>
|
||||
<option value="11">AEST/AEDT</option>
|
||||
<option value="12">NZST/NZDT</option>
|
||||
<option value="13">North Korea</option>
|
||||
</select><br>
|
||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||
Current local time is <span class="times">unknown</span>.
|
||||
<h3>Clock</h3>
|
||||
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>
|
||||
</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>
|
||||
<div id="cac">
|
||||
12h LED: <input name="OM" type="number" min="0" max="255" required><br>
|
||||
Show 5min marks: <input type="checkbox" name="O5"><br></div>
|
||||
Seconds (as trail): <input type="checkbox" name="OS"><br>
|
||||
</div>
|
||||
<div id="ccc">
|
||||
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>
|
||||
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>
|
||||
1: <input name="M1" maxlength="64"><br>
|
||||
2: <input name="M2" maxlength="64"><br>
|
||||
3: <input name="M3" maxlength="64"><br>
|
||||
4: <input name="M4" maxlength="64"><br>
|
||||
5: <input name="M5" maxlength="64"><br>
|
||||
6: <input name="M6" maxlength="64"><br>
|
||||
7: <input name="M7" maxlength="64"><br>
|
||||
8: <input name="M8" maxlength="64"><br>
|
||||
9: <input name="M9" maxlength="64"><br>
|
||||
10: <input name="M10" maxlength="64"><br>
|
||||
11: <input name="M11" maxlength="64"><br>
|
||||
12: <input name="M12" maxlength="64"><br>
|
||||
13: <input name="M13" maxlength="64"><br>
|
||||
14: <input name="M14" maxlength="64"><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>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
|
||||
const char PAGE_settings_sec0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<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>
|
||||
<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>
|
||||
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>
|
||||
<b>Disable OTA when not in use, otherwise an attacker can reflash device software!</b><br>
|
||||
<i>Settings on this page are only changable if OTA lock is disabled!</i><br>
|
||||
Deny access to WiFi settings if locked: <input type="checkbox" name="OW"><br><br>
|
||||
Disable recovery AP: <input type="checkbox" name="NA"><br>
|
||||
In case of an error there will be no wireless recovery possible!<br>
|
||||
Completely disables all Access Point functions.<br><br>
|
||||
Factory reset: <input type="checkbox" name="RS"><br>
|
||||
All EEPROM content (settings) will be erased.<br><br>
|
||||
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
|
||||
<h3>Software Update</h3>
|
||||
<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.3<br>
|
||||
(c) 2016-2018 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>
|
||||
)=====";
|
||||
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
|
||||
633
wled00/palettes.h
Normal file
633
wled00/palettes.h
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* 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};
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Orangery_gp ) {
|
||||
0, 255, 95, 23,
|
||||
30, 255, 82, 0,
|
||||
60, 223, 13, 8,
|
||||
90, 144, 44, 2,
|
||||
120, 255,110, 17,
|
||||
150, 255, 69, 0,
|
||||
180, 158, 13, 11,
|
||||
210, 241, 82, 17,
|
||||
255, 213, 37, 4};
|
||||
|
||||
//inspired by Mark Kriegsman https://gist.github.com/kriegsman/756ea6dcae8e30845b5a
|
||||
DEFINE_GRADIENT_PALETTE( C9_gp ) {
|
||||
0, 184, 4, 0, //red
|
||||
60, 184, 4, 0,
|
||||
65, 144, 44, 2, //amber
|
||||
125, 144, 44, 2,
|
||||
130, 4, 96, 2, //green
|
||||
190, 4, 96, 2,
|
||||
195, 7, 7, 88, //blue
|
||||
255, 7, 7, 88};
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Sakura_gp ) {
|
||||
0, 196, 19, 10,
|
||||
65, 255, 69, 45,
|
||||
130, 223, 45, 72,
|
||||
195, 255, 82,103,
|
||||
255, 223, 13, 17};
|
||||
|
||||
DEFINE_GRADIENT_PALETTE( Aurora_gp ) {
|
||||
0, 1, 5, 45, //deep blue
|
||||
64, 0,200, 23,
|
||||
128, 0,255, 0, //green
|
||||
170, 0,243, 45,
|
||||
200, 0,135, 7,
|
||||
255, 1, 5, 45};//deep blue
|
||||
|
||||
|
||||
// Single array of defined cpt-city color palettes.
|
||||
// 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
|
||||
Orangery_gp, //47-34 Orangery
|
||||
C9_gp, //48-35 C9
|
||||
Sakura_gp, //49-36 Sakura
|
||||
Aurora_gp, //50-37 Aurora
|
||||
};
|
||||
|
||||
|
||||
// Count of how many cpt-city gradients are defined:
|
||||
const uint8_t gGradientPaletteCount =
|
||||
sizeof( gGradientPalettes) / sizeof( TProgmemRGBGradientPalettePtr );
|
||||
|
||||
#endif
|
||||
877
wled00/src/dependencies/async-mqtt-client/AsyncMqttClient.cpp
Normal file
877
wled00/src/dependencies/async-mqtt-client/AsyncMqttClient.cpp
Normal file
@@ -0,0 +1,877 @@
|
||||
#include "AsyncMqttClient.hpp"
|
||||
|
||||
AsyncMqttClient::AsyncMqttClient()
|
||||
: _connected(false)
|
||||
, _connectPacketNotEnoughSpace(false)
|
||||
, _disconnectFlagged(false)
|
||||
, _tlsBadFingerprint(false)
|
||||
, _lastClientActivity(0)
|
||||
, _lastServerActivity(0)
|
||||
, _lastPingRequestTime(0)
|
||||
, _host(nullptr)
|
||||
, _useIp(false)
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
, _secure(false)
|
||||
#endif
|
||||
, _port(0)
|
||||
, _keepAlive(15)
|
||||
, _cleanSession(true)
|
||||
, _clientId(nullptr)
|
||||
, _username(nullptr)
|
||||
, _password(nullptr)
|
||||
, _willTopic(nullptr)
|
||||
, _willPayload(nullptr)
|
||||
, _willPayloadLength(0)
|
||||
, _willQos(0)
|
||||
, _willRetain(false)
|
||||
, _parsingInformation { .bufferState = AsyncMqttClientInternals::BufferState::NONE }
|
||||
, _currentParsedPacket(nullptr)
|
||||
, _remainingLengthBufferPosition(0)
|
||||
, _nextPacketId(1) {
|
||||
_client.onConnect([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onConnect(c); }, this);
|
||||
_client.onDisconnect([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onDisconnect(c); }, this);
|
||||
_client.onError([](void* obj, AsyncClient* c, int8_t error) { (static_cast<AsyncMqttClient*>(obj))->_onError(c, error); }, this);
|
||||
_client.onTimeout([](void* obj, AsyncClient* c, uint32_t time) { (static_cast<AsyncMqttClient*>(obj))->_onTimeout(c, time); }, this);
|
||||
_client.onAck([](void* obj, AsyncClient* c, size_t len, uint32_t time) { (static_cast<AsyncMqttClient*>(obj))->_onAck(c, len, time); }, this);
|
||||
_client.onData([](void* obj, AsyncClient* c, void* data, size_t len) { (static_cast<AsyncMqttClient*>(obj))->_onData(c, static_cast<char*>(data), len); }, this);
|
||||
_client.onPoll([](void* obj, AsyncClient* c) { (static_cast<AsyncMqttClient*>(obj))->_onPoll(c); }, this);
|
||||
|
||||
#ifdef ESP32
|
||||
sprintf(_generatedClientId, "esp32%06x", ESP.getEfuseMac());
|
||||
_xSemaphore = xSemaphoreCreateMutex();
|
||||
#elif defined(ESP8266)
|
||||
sprintf(_generatedClientId, "esp8266%06x", ESP.getChipId());
|
||||
#endif
|
||||
_clientId = _generatedClientId;
|
||||
|
||||
setMaxTopicLength(128);
|
||||
}
|
||||
|
||||
AsyncMqttClient::~AsyncMqttClient() {
|
||||
delete _currentParsedPacket;
|
||||
delete[] _parsingInformation.topicBuffer;
|
||||
#ifdef ESP32
|
||||
vSemaphoreDelete(_xSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setKeepAlive(uint16_t keepAlive) {
|
||||
_keepAlive = keepAlive;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setClientId(const char* clientId) {
|
||||
_clientId = clientId;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setCleanSession(bool cleanSession) {
|
||||
_cleanSession = cleanSession;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setMaxTopicLength(uint16_t maxTopicLength) {
|
||||
_parsingInformation.maxTopicLength = maxTopicLength;
|
||||
delete[] _parsingInformation.topicBuffer;
|
||||
_parsingInformation.topicBuffer = new char[maxTopicLength + 1];
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setCredentials(const char* username, const char* password) {
|
||||
_username = username;
|
||||
_password = password;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setWill(const char* topic, uint8_t qos, bool retain, const char* payload, size_t length) {
|
||||
_willTopic = topic;
|
||||
_willQos = qos;
|
||||
_willRetain = retain;
|
||||
_willPayload = payload;
|
||||
_willPayloadLength = length;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setServer(IPAddress ip, uint16_t port) {
|
||||
_useIp = true;
|
||||
_ip = ip;
|
||||
_port = port;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::setServer(const char* host, uint16_t port) {
|
||||
_useIp = false;
|
||||
_host = host;
|
||||
_port = port;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
AsyncMqttClient& AsyncMqttClient::setSecure(bool secure) {
|
||||
_secure = secure;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::addServerFingerprint(const uint8_t* fingerprint) {
|
||||
std::array<uint8_t, SHA1_SIZE> newFingerprint;
|
||||
memcpy(newFingerprint.data(), fingerprint, SHA1_SIZE);
|
||||
_secureServerFingerprints.push_back(newFingerprint);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::onConnect(AsyncMqttClientInternals::OnConnectUserCallback callback) {
|
||||
_onConnectUserCallbacks.push_back(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::onDisconnect(AsyncMqttClientInternals::OnDisconnectUserCallback callback) {
|
||||
_onDisconnectUserCallbacks.push_back(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::onSubscribe(AsyncMqttClientInternals::OnSubscribeUserCallback callback) {
|
||||
_onSubscribeUserCallbacks.push_back(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::onUnsubscribe(AsyncMqttClientInternals::OnUnsubscribeUserCallback callback) {
|
||||
_onUnsubscribeUserCallbacks.push_back(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::onMessage(AsyncMqttClientInternals::OnMessageUserCallback callback) {
|
||||
_onMessageUserCallbacks.push_back(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AsyncMqttClient& AsyncMqttClient::onPublish(AsyncMqttClientInternals::OnPublishUserCallback callback) {
|
||||
_onPublishUserCallbacks.push_back(callback);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_freeCurrentParsedPacket() {
|
||||
delete _currentParsedPacket;
|
||||
_currentParsedPacket = nullptr;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_clear() {
|
||||
_lastPingRequestTime = 0;
|
||||
_connected = false;
|
||||
_disconnectFlagged = false;
|
||||
_connectPacketNotEnoughSpace = false;
|
||||
_tlsBadFingerprint = false;
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
_pendingPubRels.clear();
|
||||
_pendingPubRels.shrink_to_fit();
|
||||
|
||||
_toSendAcks.clear();
|
||||
_toSendAcks.shrink_to_fit();
|
||||
|
||||
_nextPacketId = 1;
|
||||
_parsingInformation.bufferState = AsyncMqttClientInternals::BufferState::NONE;
|
||||
}
|
||||
|
||||
/* TCP */
|
||||
void AsyncMqttClient::_onConnect(AsyncClient* client) {
|
||||
(void)client;
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
if (_secure && _secureServerFingerprints.size() > 0) {
|
||||
SSL* clientSsl = _client.getSSL();
|
||||
|
||||
bool sslFoundFingerprint = false;
|
||||
for (std::array<uint8_t, SHA1_SIZE> fingerprint : _secureServerFingerprints) {
|
||||
if (ssl_match_fingerprint(clientSsl, fingerprint.data()) == SSL_OK) {
|
||||
sslFoundFingerprint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sslFoundFingerprint) {
|
||||
_tlsBadFingerprint = true;
|
||||
_client.close(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
char fixedHeader[5];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.CONNECT;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.CONNECT_RESERVED;
|
||||
|
||||
uint16_t protocolNameLength = 4;
|
||||
char protocolNameLengthBytes[2];
|
||||
protocolNameLengthBytes[0] = protocolNameLength >> 8;
|
||||
protocolNameLengthBytes[1] = protocolNameLength & 0xFF;
|
||||
|
||||
char protocolLevel[1];
|
||||
protocolLevel[0] = 0x04;
|
||||
|
||||
char connectFlags[1];
|
||||
connectFlags[0] = 0;
|
||||
if (_cleanSession) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.CLEAN_SESSION;
|
||||
if (_username != nullptr) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.USERNAME;
|
||||
if (_password != nullptr) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.PASSWORD;
|
||||
if (_willTopic != nullptr) {
|
||||
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL;
|
||||
if (_willRetain) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_RETAIN;
|
||||
switch (_willQos) {
|
||||
case 0:
|
||||
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS0;
|
||||
break;
|
||||
case 1:
|
||||
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS1;
|
||||
break;
|
||||
case 2:
|
||||
connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char keepAliveBytes[2];
|
||||
keepAliveBytes[0] = _keepAlive >> 8;
|
||||
keepAliveBytes[1] = _keepAlive & 0xFF;
|
||||
|
||||
uint16_t clientIdLength = strlen(_clientId);
|
||||
char clientIdLengthBytes[2];
|
||||
clientIdLengthBytes[0] = clientIdLength >> 8;
|
||||
clientIdLengthBytes[1] = clientIdLength & 0xFF;
|
||||
|
||||
// Optional fields
|
||||
uint16_t willTopicLength = 0;
|
||||
char willTopicLengthBytes[2];
|
||||
uint16_t willPayloadLength = _willPayloadLength;
|
||||
char willPayloadLengthBytes[2];
|
||||
if (_willTopic != nullptr) {
|
||||
willTopicLength = strlen(_willTopic);
|
||||
willTopicLengthBytes[0] = willTopicLength >> 8;
|
||||
willTopicLengthBytes[1] = willTopicLength & 0xFF;
|
||||
|
||||
if (_willPayload != nullptr && willPayloadLength == 0) willPayloadLength = strlen(_willPayload);
|
||||
|
||||
willPayloadLengthBytes[0] = willPayloadLength >> 8;
|
||||
willPayloadLengthBytes[1] = willPayloadLength & 0xFF;
|
||||
}
|
||||
|
||||
uint16_t usernameLength = 0;
|
||||
char usernameLengthBytes[2];
|
||||
if (_username != nullptr) {
|
||||
usernameLength = strlen(_username);
|
||||
usernameLengthBytes[0] = usernameLength >> 8;
|
||||
usernameLengthBytes[1] = usernameLength & 0xFF;
|
||||
}
|
||||
|
||||
uint16_t passwordLength = 0;
|
||||
char passwordLengthBytes[2];
|
||||
if (_password != nullptr) {
|
||||
passwordLength = strlen(_password);
|
||||
passwordLengthBytes[0] = passwordLength >> 8;
|
||||
passwordLengthBytes[1] = passwordLength & 0xFF;
|
||||
}
|
||||
|
||||
uint32_t remainingLength = 2 + protocolNameLength + 1 + 1 + 2 + 2 + clientIdLength; // always present
|
||||
if (_willTopic != nullptr) remainingLength += 2 + willTopicLength + 2 + willPayloadLength;
|
||||
if (_username != nullptr) remainingLength += 2 + usernameLength;
|
||||
if (_password != nullptr) remainingLength += 2 + passwordLength;
|
||||
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(remainingLength, fixedHeader + 1);
|
||||
|
||||
uint32_t neededSpace = 1 + remainingLengthLength;
|
||||
neededSpace += 2;
|
||||
neededSpace += protocolNameLength;
|
||||
neededSpace += 1;
|
||||
neededSpace += 1;
|
||||
neededSpace += 2;
|
||||
neededSpace += 2;
|
||||
neededSpace += clientIdLength;
|
||||
if (_willTopic != nullptr) {
|
||||
neededSpace += 2;
|
||||
neededSpace += willTopicLength;
|
||||
|
||||
neededSpace += 2;
|
||||
if (_willPayload != nullptr) neededSpace += willPayloadLength;
|
||||
}
|
||||
if (_username != nullptr) {
|
||||
neededSpace += 2;
|
||||
neededSpace += usernameLength;
|
||||
}
|
||||
if (_password != nullptr) {
|
||||
neededSpace += 2;
|
||||
neededSpace += passwordLength;
|
||||
}
|
||||
|
||||
SEMAPHORE_TAKE();
|
||||
if (_client.space() < neededSpace) {
|
||||
_connectPacketNotEnoughSpace = true;
|
||||
_client.close(true);
|
||||
SEMAPHORE_GIVE();
|
||||
return;
|
||||
}
|
||||
|
||||
_client.add(fixedHeader, 1 + remainingLengthLength);
|
||||
_client.add(protocolNameLengthBytes, 2);
|
||||
_client.add("MQTT", protocolNameLength);
|
||||
_client.add(protocolLevel, 1);
|
||||
_client.add(connectFlags, 1);
|
||||
_client.add(keepAliveBytes, 2);
|
||||
_client.add(clientIdLengthBytes, 2);
|
||||
_client.add(_clientId, clientIdLength);
|
||||
if (_willTopic != nullptr) {
|
||||
_client.add(willTopicLengthBytes, 2);
|
||||
_client.add(_willTopic, willTopicLength);
|
||||
|
||||
_client.add(willPayloadLengthBytes, 2);
|
||||
if (_willPayload != nullptr) _client.add(_willPayload, willPayloadLength);
|
||||
}
|
||||
if (_username != nullptr) {
|
||||
_client.add(usernameLengthBytes, 2);
|
||||
_client.add(_username, usernameLength);
|
||||
}
|
||||
if (_password != nullptr) {
|
||||
_client.add(passwordLengthBytes, 2);
|
||||
_client.add(_password, passwordLength);
|
||||
}
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
SEMAPHORE_GIVE();
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onDisconnect(AsyncClient* client) {
|
||||
(void)client;
|
||||
if (!_disconnectFlagged) {
|
||||
AsyncMqttClientDisconnectReason reason;
|
||||
|
||||
if (_connectPacketNotEnoughSpace) {
|
||||
reason = AsyncMqttClientDisconnectReason::ESP8266_NOT_ENOUGH_SPACE;
|
||||
} else if (_tlsBadFingerprint) {
|
||||
reason = AsyncMqttClientDisconnectReason::TLS_BAD_FINGERPRINT;
|
||||
} else {
|
||||
reason = AsyncMqttClientDisconnectReason::TCP_DISCONNECTED;
|
||||
}
|
||||
for (auto callback : _onDisconnectUserCallbacks) callback(reason);
|
||||
}
|
||||
_clear();
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onError(AsyncClient* client, int8_t error) {
|
||||
(void)client;
|
||||
(void)error;
|
||||
// _onDisconnect called anyway
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onTimeout(AsyncClient* client, uint32_t time) {
|
||||
(void)client;
|
||||
(void)time;
|
||||
// disconnection will be handled by ping/pong management
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onAck(AsyncClient* client, size_t len, uint32_t time) {
|
||||
(void)client;
|
||||
(void)len;
|
||||
(void)time;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onData(AsyncClient* client, char* data, size_t len) {
|
||||
(void)client;
|
||||
size_t currentBytePosition = 0;
|
||||
char currentByte;
|
||||
do {
|
||||
switch (_parsingInformation.bufferState) {
|
||||
case AsyncMqttClientInternals::BufferState::NONE:
|
||||
currentByte = data[currentBytePosition++];
|
||||
_parsingInformation.packetType = currentByte >> 4;
|
||||
_parsingInformation.packetFlags = (currentByte << 4) >> 4;
|
||||
_parsingInformation.bufferState = AsyncMqttClientInternals::BufferState::REMAINING_LENGTH;
|
||||
_lastServerActivity = millis();
|
||||
switch (_parsingInformation.packetType) {
|
||||
case AsyncMqttClientInternals::PacketType.CONNACK:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::ConnAckPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onConnAck, this, std::placeholders::_1, std::placeholders::_2));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.PINGRESP:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::PingRespPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onPingResp, this));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.SUBACK:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::SubAckPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onSubAck, this, std::placeholders::_1, std::placeholders::_2));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.UNSUBACK:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::UnsubAckPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onUnsubAck, this, std::placeholders::_1));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.PUBLISH:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::PublishPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9), std::bind(&AsyncMqttClient::_onPublish, this, std::placeholders::_1, std::placeholders::_2));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.PUBREL:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::PubRelPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onPubRel, this, std::placeholders::_1));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.PUBACK:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::PubAckPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onPubAck, this, std::placeholders::_1));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.PUBREC:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::PubRecPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onPubRec, this, std::placeholders::_1));
|
||||
break;
|
||||
case AsyncMqttClientInternals::PacketType.PUBCOMP:
|
||||
_currentParsedPacket = new AsyncMqttClientInternals::PubCompPacket(&_parsingInformation, std::bind(&AsyncMqttClient::_onPubComp, this, std::placeholders::_1));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AsyncMqttClientInternals::BufferState::REMAINING_LENGTH:
|
||||
currentByte = data[currentBytePosition++];
|
||||
_remainingLengthBuffer[_remainingLengthBufferPosition++] = currentByte;
|
||||
if (currentByte >> 7 == 0) {
|
||||
_parsingInformation.remainingLength = AsyncMqttClientInternals::Helpers::decodeRemainingLength(_remainingLengthBuffer);
|
||||
_remainingLengthBufferPosition = 0;
|
||||
if (_parsingInformation.remainingLength > 0) {
|
||||
_parsingInformation.bufferState = AsyncMqttClientInternals::BufferState::VARIABLE_HEADER;
|
||||
} else {
|
||||
// PINGRESP is a special case where it has no variable header, so the packet ends right here
|
||||
_parsingInformation.bufferState = AsyncMqttClientInternals::BufferState::NONE;
|
||||
_onPingResp();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AsyncMqttClientInternals::BufferState::VARIABLE_HEADER:
|
||||
_currentParsedPacket->parseVariableHeader(data, len, ¤tBytePosition);
|
||||
break;
|
||||
case AsyncMqttClientInternals::BufferState::PAYLOAD:
|
||||
_currentParsedPacket->parsePayload(data, len, ¤tBytePosition);
|
||||
break;
|
||||
default:
|
||||
currentBytePosition = len;
|
||||
}
|
||||
} while (currentBytePosition != len);
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onPoll(AsyncClient* client) {
|
||||
if (!_connected) return;
|
||||
|
||||
// if there is too much time the client has sent a ping request without a response, disconnect client to avoid half open connections
|
||||
if (_lastPingRequestTime != 0 && (millis() - _lastPingRequestTime) >= (_keepAlive * 1000 * 2)) {
|
||||
disconnect();
|
||||
return;
|
||||
// send ping to ensure the server will receive at least one message inside keepalive window
|
||||
} else if (_lastPingRequestTime == 0 && (millis() - _lastClientActivity) >= (_keepAlive * 1000 * 0.7)) {
|
||||
_sendPing();
|
||||
|
||||
// send ping to verify if the server is still there (ensure this is not a half connection)
|
||||
} else if (_connected && _lastPingRequestTime == 0 && (millis() - _lastServerActivity) >= (_keepAlive * 1000 * 0.7)) {
|
||||
_sendPing();
|
||||
}
|
||||
|
||||
// handle to send ack packets
|
||||
|
||||
_sendAcks();
|
||||
|
||||
// handle disconnect
|
||||
|
||||
if (_disconnectFlagged) {
|
||||
_sendDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/* MQTT */
|
||||
void AsyncMqttClient::_onPingResp() {
|
||||
_freeCurrentParsedPacket();
|
||||
_lastPingRequestTime = 0;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onConnAck(bool sessionPresent, uint8_t connectReturnCode) {
|
||||
(void)sessionPresent;
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
if (connectReturnCode == 0) {
|
||||
_connected = true;
|
||||
for (auto callback : _onConnectUserCallbacks) callback(sessionPresent);
|
||||
} else {
|
||||
for (auto callback : _onDisconnectUserCallbacks) callback(static_cast<AsyncMqttClientDisconnectReason>(connectReturnCode));
|
||||
_disconnectFlagged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onSubAck(uint16_t packetId, char status) {
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
for (auto callback : _onSubscribeUserCallbacks) callback(packetId, status);
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onUnsubAck(uint16_t packetId) {
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
for (auto callback : _onUnsubscribeUserCallbacks) callback(packetId);
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onMessage(char* topic, char* payload, uint8_t qos, bool dup, bool retain, size_t len, size_t index, size_t total, uint16_t packetId) {
|
||||
bool notifyPublish = true;
|
||||
|
||||
if (qos == 2) {
|
||||
for (AsyncMqttClientInternals::PendingPubRel pendingPubRel : _pendingPubRels) {
|
||||
if (pendingPubRel.packetId == packetId) {
|
||||
notifyPublish = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (notifyPublish) {
|
||||
AsyncMqttClientMessageProperties properties;
|
||||
properties.qos = qos;
|
||||
properties.dup = dup;
|
||||
properties.retain = retain;
|
||||
|
||||
for (auto callback : _onMessageUserCallbacks) callback(topic, payload, properties, len, index, total);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onPublish(uint16_t packetId, uint8_t qos) {
|
||||
AsyncMqttClientInternals::PendingAck pendingAck;
|
||||
|
||||
if (qos == 1) {
|
||||
pendingAck.packetType = AsyncMqttClientInternals::PacketType.PUBACK;
|
||||
pendingAck.headerFlag = AsyncMqttClientInternals::HeaderFlag.PUBACK_RESERVED;
|
||||
pendingAck.packetId = packetId;
|
||||
_toSendAcks.push_back(pendingAck);
|
||||
} else if (qos == 2) {
|
||||
pendingAck.packetType = AsyncMqttClientInternals::PacketType.PUBREC;
|
||||
pendingAck.headerFlag = AsyncMqttClientInternals::HeaderFlag.PUBREC_RESERVED;
|
||||
pendingAck.packetId = packetId;
|
||||
_toSendAcks.push_back(pendingAck);
|
||||
|
||||
bool pubRelAwaiting = false;
|
||||
for (AsyncMqttClientInternals::PendingPubRel pendingPubRel : _pendingPubRels) {
|
||||
if (pendingPubRel.packetId == packetId) {
|
||||
pubRelAwaiting = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pubRelAwaiting) {
|
||||
AsyncMqttClientInternals::PendingPubRel pendingPubRel;
|
||||
pendingPubRel.packetId = packetId;
|
||||
_pendingPubRels.push_back(pendingPubRel);
|
||||
}
|
||||
|
||||
_sendAcks();
|
||||
}
|
||||
|
||||
_freeCurrentParsedPacket();
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onPubRel(uint16_t packetId) {
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
AsyncMqttClientInternals::PendingAck pendingAck;
|
||||
pendingAck.packetType = AsyncMqttClientInternals::PacketType.PUBCOMP;
|
||||
pendingAck.headerFlag = AsyncMqttClientInternals::HeaderFlag.PUBCOMP_RESERVED;
|
||||
pendingAck.packetId = packetId;
|
||||
_toSendAcks.push_back(pendingAck);
|
||||
|
||||
for (size_t i = 0; i < _pendingPubRels.size(); i++) {
|
||||
if (_pendingPubRels[i].packetId == packetId) {
|
||||
_pendingPubRels.erase(_pendingPubRels.begin() + i);
|
||||
_pendingPubRels.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
_sendAcks();
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onPubAck(uint16_t packetId) {
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
for (auto callback : _onPublishUserCallbacks) callback(packetId);
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onPubRec(uint16_t packetId) {
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
AsyncMqttClientInternals::PendingAck pendingAck;
|
||||
pendingAck.packetType = AsyncMqttClientInternals::PacketType.PUBREL;
|
||||
pendingAck.headerFlag = AsyncMqttClientInternals::HeaderFlag.PUBREL_RESERVED;
|
||||
pendingAck.packetId = packetId;
|
||||
_toSendAcks.push_back(pendingAck);
|
||||
|
||||
_sendAcks();
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_onPubComp(uint16_t packetId) {
|
||||
_freeCurrentParsedPacket();
|
||||
|
||||
for (auto callback : _onPublishUserCallbacks) callback(packetId);
|
||||
}
|
||||
|
||||
bool AsyncMqttClient::_sendPing() {
|
||||
char fixedHeader[2];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.PINGREQ;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.PINGREQ_RESERVED;
|
||||
fixedHeader[1] = 0;
|
||||
|
||||
size_t neededSpace = 2;
|
||||
|
||||
SEMAPHORE_TAKE(false);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return false; }
|
||||
|
||||
_client.add(fixedHeader, 2);
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
_lastPingRequestTime = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return true;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::_sendAcks() {
|
||||
uint8_t neededAckSpace = 2 + 2;
|
||||
|
||||
SEMAPHORE_TAKE();
|
||||
for (size_t i = 0; i < _toSendAcks.size(); i++) {
|
||||
if (_client.space() < neededAckSpace) break;
|
||||
|
||||
AsyncMqttClientInternals::PendingAck pendingAck = _toSendAcks[i];
|
||||
|
||||
char fixedHeader[2];
|
||||
fixedHeader[0] = pendingAck.packetType;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
fixedHeader[0] = fixedHeader[0] | pendingAck.headerFlag;
|
||||
fixedHeader[1] = 2;
|
||||
|
||||
char packetIdBytes[2];
|
||||
packetIdBytes[0] = pendingAck.packetId >> 8;
|
||||
packetIdBytes[1] = pendingAck.packetId & 0xFF;
|
||||
|
||||
_client.add(fixedHeader, 2);
|
||||
_client.add(packetIdBytes, 2);
|
||||
_client.send();
|
||||
|
||||
_toSendAcks.erase(_toSendAcks.begin() + i);
|
||||
_toSendAcks.shrink_to_fit();
|
||||
|
||||
_lastClientActivity = millis();
|
||||
}
|
||||
SEMAPHORE_GIVE();
|
||||
}
|
||||
|
||||
bool AsyncMqttClient::_sendDisconnect() {
|
||||
if (!_connected) return true;
|
||||
|
||||
const uint8_t neededSpace = 2;
|
||||
|
||||
SEMAPHORE_TAKE(false);
|
||||
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return false; }
|
||||
|
||||
char fixedHeader[2];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.DISCONNECT;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.DISCONNECT_RESERVED;
|
||||
fixedHeader[1] = 0;
|
||||
|
||||
_client.add(fixedHeader, 2);
|
||||
_client.send();
|
||||
_client.close(true);
|
||||
|
||||
_disconnectFlagged = false;
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t AsyncMqttClient::_getNextPacketId() {
|
||||
uint16_t nextPacketId = _nextPacketId;
|
||||
|
||||
if (_nextPacketId == 65535) _nextPacketId = 0; // 0 is forbidden
|
||||
_nextPacketId++;
|
||||
|
||||
return nextPacketId;
|
||||
}
|
||||
|
||||
bool AsyncMqttClient::connected() const {
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void AsyncMqttClient::connect() {
|
||||
if (_connected) return;
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
if (_useIp) {
|
||||
_client.connect(_ip, _port, _secure);
|
||||
} else {
|
||||
_client.connect(_host, _port, _secure);
|
||||
}
|
||||
#else
|
||||
if (_useIp) {
|
||||
_client.connect(_ip, _port);
|
||||
} else {
|
||||
_client.connect(_host, _port);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AsyncMqttClient::disconnect(bool force) {
|
||||
if (!_connected) return;
|
||||
|
||||
if (force) {
|
||||
_client.close(true);
|
||||
} else {
|
||||
_disconnectFlagged = true;
|
||||
_sendDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t AsyncMqttClient::subscribe(const char* topic, uint8_t qos) {
|
||||
if (!_connected) return 0;
|
||||
|
||||
char fixedHeader[5];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.SUBSCRIBE;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.SUBSCRIBE_RESERVED;
|
||||
|
||||
uint16_t topicLength = strlen(topic);
|
||||
char topicLengthBytes[2];
|
||||
topicLengthBytes[0] = topicLength >> 8;
|
||||
topicLengthBytes[1] = topicLength & 0xFF;
|
||||
|
||||
char qosByte[1];
|
||||
qosByte[0] = qos;
|
||||
|
||||
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(2 + 2 + topicLength + 1, fixedHeader + 1);
|
||||
|
||||
size_t neededSpace = 0;
|
||||
neededSpace += 1 + remainingLengthLength;
|
||||
neededSpace += 2;
|
||||
neededSpace += 2;
|
||||
neededSpace += topicLength;
|
||||
neededSpace += 1;
|
||||
|
||||
SEMAPHORE_TAKE(0);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return 0; }
|
||||
|
||||
uint16_t packetId = _getNextPacketId();
|
||||
char packetIdBytes[2];
|
||||
packetIdBytes[0] = packetId >> 8;
|
||||
packetIdBytes[1] = packetId & 0xFF;
|
||||
|
||||
_client.add(fixedHeader, 1 + remainingLengthLength);
|
||||
_client.add(packetIdBytes, 2);
|
||||
_client.add(topicLengthBytes, 2);
|
||||
_client.add(topic, topicLength);
|
||||
_client.add(qosByte, 1);
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return packetId;
|
||||
}
|
||||
|
||||
uint16_t AsyncMqttClient::unsubscribe(const char* topic) {
|
||||
if (!_connected) return 0;
|
||||
|
||||
char fixedHeader[5];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.UNSUBSCRIBE;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.UNSUBSCRIBE_RESERVED;
|
||||
|
||||
uint16_t topicLength = strlen(topic);
|
||||
char topicLengthBytes[2];
|
||||
topicLengthBytes[0] = topicLength >> 8;
|
||||
topicLengthBytes[1] = topicLength & 0xFF;
|
||||
|
||||
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(2 + 2 + topicLength, fixedHeader + 1);
|
||||
|
||||
size_t neededSpace = 0;
|
||||
neededSpace += 1 + remainingLengthLength;
|
||||
neededSpace += 2;
|
||||
neededSpace += 2;
|
||||
neededSpace += topicLength;
|
||||
|
||||
SEMAPHORE_TAKE(0);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return 0; }
|
||||
|
||||
uint16_t packetId = _getNextPacketId();
|
||||
char packetIdBytes[2];
|
||||
packetIdBytes[0] = packetId >> 8;
|
||||
packetIdBytes[1] = packetId & 0xFF;
|
||||
|
||||
_client.add(fixedHeader, 1 + remainingLengthLength);
|
||||
_client.add(packetIdBytes, 2);
|
||||
_client.add(topicLengthBytes, 2);
|
||||
_client.add(topic, topicLength);
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
return packetId;
|
||||
}
|
||||
|
||||
uint16_t AsyncMqttClient::publish(const char* topic, uint8_t qos, bool retain, const char* payload, size_t length, bool dup, uint16_t message_id) {
|
||||
if (!_connected) return 0;
|
||||
|
||||
char fixedHeader[5];
|
||||
fixedHeader[0] = AsyncMqttClientInternals::PacketType.PUBLISH;
|
||||
fixedHeader[0] = fixedHeader[0] << 4;
|
||||
if (dup) fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_DUP;
|
||||
if (retain) fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_RETAIN;
|
||||
switch (qos) {
|
||||
case 0:
|
||||
fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS0;
|
||||
break;
|
||||
case 1:
|
||||
fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS1;
|
||||
break;
|
||||
case 2:
|
||||
fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS2;
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t topicLength = strlen(topic);
|
||||
char topicLengthBytes[2];
|
||||
topicLengthBytes[0] = topicLength >> 8;
|
||||
topicLengthBytes[1] = topicLength & 0xFF;
|
||||
|
||||
uint32_t payloadLength = length;
|
||||
if (payload != nullptr && payloadLength == 0) payloadLength = strlen(payload);
|
||||
|
||||
uint32_t remainingLength = 2 + topicLength + payloadLength;
|
||||
if (qos != 0) remainingLength += 2;
|
||||
uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(remainingLength, fixedHeader + 1);
|
||||
|
||||
size_t neededSpace = 0;
|
||||
neededSpace += 1 + remainingLengthLength;
|
||||
neededSpace += 2;
|
||||
neededSpace += topicLength;
|
||||
if (qos != 0) neededSpace += 2;
|
||||
if (payload != nullptr) neededSpace += payloadLength;
|
||||
|
||||
SEMAPHORE_TAKE(0);
|
||||
if (_client.space() < neededSpace) { SEMAPHORE_GIVE(); return 0; }
|
||||
|
||||
uint16_t packetId = 0;
|
||||
char packetIdBytes[2];
|
||||
if (qos != 0) {
|
||||
if (dup && message_id > 0) {
|
||||
packetId = message_id;
|
||||
} else {
|
||||
packetId = _getNextPacketId();
|
||||
}
|
||||
|
||||
packetIdBytes[0] = packetId >> 8;
|
||||
packetIdBytes[1] = packetId & 0xFF;
|
||||
}
|
||||
|
||||
_client.add(fixedHeader, 1 + remainingLengthLength);
|
||||
_client.add(topicLengthBytes, 2);
|
||||
_client.add(topic, topicLength);
|
||||
if (qos != 0) _client.add(packetIdBytes, 2);
|
||||
if (payload != nullptr) _client.add(payload, payloadLength);
|
||||
_client.send();
|
||||
_lastClientActivity = millis();
|
||||
|
||||
SEMAPHORE_GIVE();
|
||||
if (qos != 0) {
|
||||
return packetId;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef SRC_ASYNCMQTTCLIENT_H_
|
||||
#define SRC_ASYNCMQTTCLIENT_H_
|
||||
|
||||
#include "AsyncMqttClient.hpp"
|
||||
|
||||
#endif // SRC_ASYNCMQTTCLIENT_H_
|
||||
166
wled00/src/dependencies/async-mqtt-client/AsyncMqttClient.hpp
Normal file
166
wled00/src/dependencies/async-mqtt-client/AsyncMqttClient.hpp
Normal file
@@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef ESP32
|
||||
#include <AsyncTCP.h>
|
||||
#include <freertos/semphr.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <ESPAsyncTCP.h>
|
||||
#else
|
||||
#error Platform not supported
|
||||
#endif
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
#include <tcp_axtls.h>
|
||||
#define SHA1_SIZE 20
|
||||
#endif
|
||||
|
||||
#include "AsyncMqttClient/Flags.hpp"
|
||||
#include "AsyncMqttClient/ParsingInformation.hpp"
|
||||
#include "AsyncMqttClient/MessageProperties.hpp"
|
||||
#include "AsyncMqttClient/Helpers.hpp"
|
||||
#include "AsyncMqttClient/Callbacks.hpp"
|
||||
#include "AsyncMqttClient/DisconnectReasons.hpp"
|
||||
#include "AsyncMqttClient/Storage.hpp"
|
||||
|
||||
#include "AsyncMqttClient/Packets/Packet.hpp"
|
||||
#include "AsyncMqttClient/Packets/ConnAckPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PingRespPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/SubAckPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/UnsubAckPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PublishPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PubRelPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PubAckPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PubRecPacket.hpp"
|
||||
#include "AsyncMqttClient/Packets/PubCompPacket.hpp"
|
||||
|
||||
#if ESP32
|
||||
#define SEMAPHORE_TAKE(X) if (xSemaphoreTake(_xSemaphore, 1000 / portTICK_PERIOD_MS) != pdTRUE) { return X; } // Waits max 1000ms
|
||||
#define SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore);
|
||||
#elif defined(ESP8266)
|
||||
#define SEMAPHORE_TAKE(X) void()
|
||||
#define SEMAPHORE_GIVE() void()
|
||||
#endif
|
||||
|
||||
class AsyncMqttClient {
|
||||
public:
|
||||
AsyncMqttClient();
|
||||
~AsyncMqttClient();
|
||||
|
||||
AsyncMqttClient& setKeepAlive(uint16_t keepAlive);
|
||||
AsyncMqttClient& setClientId(const char* clientId);
|
||||
AsyncMqttClient& setCleanSession(bool cleanSession);
|
||||
AsyncMqttClient& setMaxTopicLength(uint16_t maxTopicLength);
|
||||
AsyncMqttClient& setCredentials(const char* username, const char* password = nullptr);
|
||||
AsyncMqttClient& setWill(const char* topic, uint8_t qos, bool retain, const char* payload = nullptr, size_t length = 0);
|
||||
AsyncMqttClient& setServer(IPAddress ip, uint16_t port);
|
||||
AsyncMqttClient& setServer(const char* host, uint16_t port);
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
AsyncMqttClient& setSecure(bool secure);
|
||||
AsyncMqttClient& addServerFingerprint(const uint8_t* fingerprint);
|
||||
#endif
|
||||
|
||||
AsyncMqttClient& onConnect(AsyncMqttClientInternals::OnConnectUserCallback callback);
|
||||
AsyncMqttClient& onDisconnect(AsyncMqttClientInternals::OnDisconnectUserCallback callback);
|
||||
AsyncMqttClient& onSubscribe(AsyncMqttClientInternals::OnSubscribeUserCallback callback);
|
||||
AsyncMqttClient& onUnsubscribe(AsyncMqttClientInternals::OnUnsubscribeUserCallback callback);
|
||||
AsyncMqttClient& onMessage(AsyncMqttClientInternals::OnMessageUserCallback callback);
|
||||
AsyncMqttClient& onPublish(AsyncMqttClientInternals::OnPublishUserCallback callback);
|
||||
|
||||
bool connected() const;
|
||||
void connect();
|
||||
void disconnect(bool force = false);
|
||||
uint16_t subscribe(const char* topic, uint8_t qos);
|
||||
uint16_t unsubscribe(const char* topic);
|
||||
uint16_t publish(const char* topic, uint8_t qos, bool retain, const char* payload = nullptr, size_t length = 0, bool dup = false, uint16_t message_id = 0);
|
||||
|
||||
private:
|
||||
AsyncClient _client;
|
||||
|
||||
bool _connected;
|
||||
bool _connectPacketNotEnoughSpace;
|
||||
bool _disconnectFlagged;
|
||||
bool _tlsBadFingerprint;
|
||||
uint32_t _lastClientActivity;
|
||||
uint32_t _lastServerActivity;
|
||||
uint32_t _lastPingRequestTime;
|
||||
|
||||
char _generatedClientId[13 + 1]; // esp8266abc123
|
||||
IPAddress _ip;
|
||||
const char* _host;
|
||||
bool _useIp;
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
bool _secure;
|
||||
#endif
|
||||
uint16_t _port;
|
||||
uint16_t _keepAlive;
|
||||
bool _cleanSession;
|
||||
const char* _clientId;
|
||||
const char* _username;
|
||||
const char* _password;
|
||||
const char* _willTopic;
|
||||
const char* _willPayload;
|
||||
uint16_t _willPayloadLength;
|
||||
uint8_t _willQos;
|
||||
bool _willRetain;
|
||||
|
||||
#if ASYNC_TCP_SSL_ENABLED
|
||||
std::vector<std::array<uint8_t, SHA1_SIZE>> _secureServerFingerprints;
|
||||
#endif
|
||||
|
||||
std::vector<AsyncMqttClientInternals::OnConnectUserCallback> _onConnectUserCallbacks;
|
||||
std::vector<AsyncMqttClientInternals::OnDisconnectUserCallback> _onDisconnectUserCallbacks;
|
||||
std::vector<AsyncMqttClientInternals::OnSubscribeUserCallback> _onSubscribeUserCallbacks;
|
||||
std::vector<AsyncMqttClientInternals::OnUnsubscribeUserCallback> _onUnsubscribeUserCallbacks;
|
||||
std::vector<AsyncMqttClientInternals::OnMessageUserCallback> _onMessageUserCallbacks;
|
||||
std::vector<AsyncMqttClientInternals::OnPublishUserCallback> _onPublishUserCallbacks;
|
||||
|
||||
AsyncMqttClientInternals::ParsingInformation _parsingInformation;
|
||||
AsyncMqttClientInternals::Packet* _currentParsedPacket;
|
||||
uint8_t _remainingLengthBufferPosition;
|
||||
char _remainingLengthBuffer[4];
|
||||
|
||||
uint16_t _nextPacketId;
|
||||
|
||||
std::vector<AsyncMqttClientInternals::PendingPubRel> _pendingPubRels;
|
||||
|
||||
std::vector<AsyncMqttClientInternals::PendingAck> _toSendAcks;
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t _xSemaphore = nullptr;
|
||||
#endif
|
||||
|
||||
void _clear();
|
||||
void _freeCurrentParsedPacket();
|
||||
|
||||
// TCP
|
||||
void _onConnect(AsyncClient* client);
|
||||
void _onDisconnect(AsyncClient* client);
|
||||
static void _onError(AsyncClient* client, int8_t error);
|
||||
void _onTimeout(AsyncClient* client, uint32_t time);
|
||||
static void _onAck(AsyncClient* client, size_t len, uint32_t time);
|
||||
void _onData(AsyncClient* client, char* data, size_t len);
|
||||
void _onPoll(AsyncClient* client);
|
||||
|
||||
// MQTT
|
||||
void _onPingResp();
|
||||
void _onConnAck(bool sessionPresent, uint8_t connectReturnCode);
|
||||
void _onSubAck(uint16_t packetId, char status);
|
||||
void _onUnsubAck(uint16_t packetId);
|
||||
void _onMessage(char* topic, char* payload, uint8_t qos, bool dup, bool retain, size_t len, size_t index, size_t total, uint16_t packetId);
|
||||
void _onPublish(uint16_t packetId, uint8_t qos);
|
||||
void _onPubRel(uint16_t packetId);
|
||||
void _onPubAck(uint16_t packetId);
|
||||
void _onPubRec(uint16_t packetId);
|
||||
void _onPubComp(uint16_t packetId);
|
||||
|
||||
bool _sendPing();
|
||||
void _sendAcks();
|
||||
bool _sendDisconnect();
|
||||
|
||||
uint16_t _getNextPacketId();
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "DisconnectReasons.hpp"
|
||||
#include "MessageProperties.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
// user callbacks
|
||||
typedef std::function<void(bool sessionPresent)> OnConnectUserCallback;
|
||||
typedef std::function<void(AsyncMqttClientDisconnectReason reason)> OnDisconnectUserCallback;
|
||||
typedef std::function<void(uint16_t packetId, uint8_t qos)> OnSubscribeUserCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnUnsubscribeUserCallback;
|
||||
typedef std::function<void(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)> OnMessageUserCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnPublishUserCallback;
|
||||
|
||||
// internal callbacks
|
||||
typedef std::function<void(bool sessionPresent, uint8_t connectReturnCode)> OnConnAckInternalCallback;
|
||||
typedef std::function<void()> OnPingRespInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId, char status)> OnSubAckInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnUnsubAckInternalCallback;
|
||||
typedef std::function<void(char* topic, char* payload, uint8_t qos, bool dup, bool retain, size_t len, size_t index, size_t total, uint16_t packetId)> OnMessageInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId, uint8_t qos)> OnPublishInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnPubRelInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnPubAckInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnPubRecInternalCallback;
|
||||
typedef std::function<void(uint16_t packetId)> OnPubCompInternalCallback;
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
enum class AsyncMqttClientDisconnectReason : int8_t {
|
||||
TCP_DISCONNECTED = 0,
|
||||
|
||||
MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 1,
|
||||
MQTT_IDENTIFIER_REJECTED = 2,
|
||||
MQTT_SERVER_UNAVAILABLE = 3,
|
||||
MQTT_MALFORMED_CREDENTIALS = 4,
|
||||
MQTT_NOT_AUTHORIZED = 5,
|
||||
|
||||
ESP8266_NOT_ENOUGH_SPACE = 6,
|
||||
|
||||
TLS_BAD_FINGERPRINT = 7
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
constexpr struct {
|
||||
const uint8_t RESERVED = 0;
|
||||
const uint8_t CONNECT = 1;
|
||||
const uint8_t CONNACK = 2;
|
||||
const uint8_t PUBLISH = 3;
|
||||
const uint8_t PUBACK = 4;
|
||||
const uint8_t PUBREC = 5;
|
||||
const uint8_t PUBREL = 6;
|
||||
const uint8_t PUBCOMP = 7;
|
||||
const uint8_t SUBSCRIBE = 8;
|
||||
const uint8_t SUBACK = 9;
|
||||
const uint8_t UNSUBSCRIBE = 10;
|
||||
const uint8_t UNSUBACK = 11;
|
||||
const uint8_t PINGREQ = 12;
|
||||
const uint8_t PINGRESP = 13;
|
||||
const uint8_t DISCONNECT = 14;
|
||||
const uint8_t RESERVED2 = 1;
|
||||
} PacketType;
|
||||
|
||||
constexpr struct {
|
||||
const uint8_t CONNECT_RESERVED = 0x00;
|
||||
const uint8_t CONNACK_RESERVED = 0x00;
|
||||
const uint8_t PUBLISH_DUP = 0x08;
|
||||
const uint8_t PUBLISH_QOS0 = 0x00;
|
||||
const uint8_t PUBLISH_QOS1 = 0x02;
|
||||
const uint8_t PUBLISH_QOS2 = 0x04;
|
||||
const uint8_t PUBLISH_QOSRESERVED = 0x06;
|
||||
const uint8_t PUBLISH_RETAIN = 0x01;
|
||||
const uint8_t PUBACK_RESERVED = 0x00;
|
||||
const uint8_t PUBREC_RESERVED = 0x00;
|
||||
const uint8_t PUBREL_RESERVED = 0x02;
|
||||
const uint8_t PUBCOMP_RESERVED = 0x00;
|
||||
const uint8_t SUBSCRIBE_RESERVED = 0x02;
|
||||
const uint8_t SUBACK_RESERVED = 0x00;
|
||||
const uint8_t UNSUBSCRIBE_RESERVED = 0x02;
|
||||
const uint8_t UNSUBACK_RESERVED = 0x00;
|
||||
const uint8_t PINGREQ_RESERVED = 0x00;
|
||||
const uint8_t PINGRESP_RESERVED = 0x00;
|
||||
const uint8_t DISCONNECT_RESERVED = 0x00;
|
||||
const uint8_t RESERVED2_RESERVED = 0x00;
|
||||
} HeaderFlag;
|
||||
|
||||
constexpr struct {
|
||||
const uint8_t USERNAME = 0x80;
|
||||
const uint8_t PASSWORD = 0x40;
|
||||
const uint8_t WILL_RETAIN = 0x20;
|
||||
const uint8_t WILL_QOS0 = 0x00;
|
||||
const uint8_t WILL_QOS1 = 0x08;
|
||||
const uint8_t WILL_QOS2 = 0x10;
|
||||
const uint8_t WILL = 0x04;
|
||||
const uint8_t CLEAN_SESSION = 0x02;
|
||||
const uint8_t RESERVED = 0x00;
|
||||
} ConnectFlag;
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class Helpers {
|
||||
public:
|
||||
static uint32_t decodeRemainingLength(char* bytes) {
|
||||
uint32_t multiplier = 1;
|
||||
uint32_t value = 0;
|
||||
uint8_t currentByte = 0;
|
||||
uint8_t encodedByte;
|
||||
do {
|
||||
encodedByte = bytes[currentByte++];
|
||||
value += (encodedByte & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((encodedByte & 128) != 0);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static uint8_t encodeRemainingLength(uint32_t remainingLength, char* destination) {
|
||||
uint8_t currentByte = 0;
|
||||
uint8_t bytesNeeded = 0;
|
||||
|
||||
do {
|
||||
uint8_t encodedByte = remainingLength % 128;
|
||||
remainingLength /= 128;
|
||||
if (remainingLength > 0) {
|
||||
encodedByte = encodedByte | 128;
|
||||
}
|
||||
|
||||
destination[currentByte++] = encodedByte;
|
||||
bytesNeeded++;
|
||||
} while (remainingLength > 0);
|
||||
|
||||
return bytesNeeded;
|
||||
}
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
struct AsyncMqttClientMessageProperties {
|
||||
uint8_t qos;
|
||||
bool dup;
|
||||
bool retain;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "ConnAckPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::ConnAckPacket;
|
||||
|
||||
ConnAckPacket::ConnAckPacket(ParsingInformation* parsingInformation, OnConnAckInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _sessionPresent(false)
|
||||
, _connectReturnCode(0) {
|
||||
}
|
||||
|
||||
ConnAckPacket::~ConnAckPacket() {
|
||||
}
|
||||
|
||||
void ConnAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_sessionPresent = (currentByte << 7) >> 7;
|
||||
} else {
|
||||
_connectReturnCode = currentByte;
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_sessionPresent, _connectReturnCode);
|
||||
}
|
||||
}
|
||||
|
||||
void ConnAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class ConnAckPacket : public Packet {
|
||||
public:
|
||||
explicit ConnAckPacket(ParsingInformation* parsingInformation, OnConnAckInternalCallback callback);
|
||||
~ConnAckPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnConnAckInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
bool _sessionPresent;
|
||||
uint8_t _connectReturnCode;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class Packet {
|
||||
public:
|
||||
virtual ~Packet() {}
|
||||
|
||||
virtual void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) = 0;
|
||||
virtual void parsePayload(char* data, size_t len, size_t* currentBytePosition) = 0;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "PingRespPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::PingRespPacket;
|
||||
|
||||
PingRespPacket::PingRespPacket(ParsingInformation* parsingInformation, OnPingRespInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback) {
|
||||
}
|
||||
|
||||
PingRespPacket::~PingRespPacket() {
|
||||
}
|
||||
|
||||
void PingRespPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
|
||||
void PingRespPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class PingRespPacket : public Packet {
|
||||
public:
|
||||
explicit PingRespPacket(ParsingInformation* parsingInformation, OnPingRespInternalCallback callback);
|
||||
~PingRespPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnPingRespInternalCallback _callback;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "PubAckPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::PubAckPacket;
|
||||
|
||||
PubAckPacket::PubAckPacket(ParsingInformation* parsingInformation, OnPubAckInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0) {
|
||||
}
|
||||
|
||||
PubAckPacket::~PubAckPacket() {
|
||||
}
|
||||
|
||||
void PubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_packetId);
|
||||
}
|
||||
}
|
||||
|
||||
void PubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class PubAckPacket : public Packet {
|
||||
public:
|
||||
explicit PubAckPacket(ParsingInformation* parsingInformation, OnPubAckInternalCallback callback);
|
||||
~PubAckPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnPubAckInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "PubCompPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::PubCompPacket;
|
||||
|
||||
PubCompPacket::PubCompPacket(ParsingInformation* parsingInformation, OnPubCompInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0) {
|
||||
}
|
||||
|
||||
PubCompPacket::~PubCompPacket() {
|
||||
}
|
||||
|
||||
void PubCompPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_packetId);
|
||||
}
|
||||
}
|
||||
|
||||
void PubCompPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class PubCompPacket : public Packet {
|
||||
public:
|
||||
explicit PubCompPacket(ParsingInformation* parsingInformation, OnPubCompInternalCallback callback);
|
||||
~PubCompPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnPubCompInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "PubRecPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::PubRecPacket;
|
||||
|
||||
PubRecPacket::PubRecPacket(ParsingInformation* parsingInformation, OnPubRecInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0) {
|
||||
}
|
||||
|
||||
PubRecPacket::~PubRecPacket() {
|
||||
}
|
||||
|
||||
void PubRecPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_packetId);
|
||||
}
|
||||
}
|
||||
|
||||
void PubRecPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class PubRecPacket : public Packet {
|
||||
public:
|
||||
explicit PubRecPacket(ParsingInformation* parsingInformation, OnPubRecInternalCallback callback);
|
||||
~PubRecPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnPubRecInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "PubRelPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::PubRelPacket;
|
||||
|
||||
PubRelPacket::PubRelPacket(ParsingInformation* parsingInformation, OnPubRelInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0) {
|
||||
}
|
||||
|
||||
PubRelPacket::~PubRelPacket() {
|
||||
}
|
||||
|
||||
void PubRelPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_packetId);
|
||||
}
|
||||
}
|
||||
|
||||
void PubRelPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class PubRelPacket : public Packet {
|
||||
public:
|
||||
explicit PubRelPacket(ParsingInformation* parsingInformation, OnPubRelInternalCallback callback);
|
||||
~PubRelPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnPubRelInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "PublishPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::PublishPacket;
|
||||
|
||||
PublishPacket::PublishPacket(ParsingInformation* parsingInformation, OnMessageInternalCallback dataCallback, OnPublishInternalCallback completeCallback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _dataCallback(dataCallback)
|
||||
, _completeCallback(completeCallback)
|
||||
, _dup(false)
|
||||
, _qos(0)
|
||||
, _retain(0)
|
||||
, _bytePosition(0)
|
||||
, _topicLengthMsb(0)
|
||||
, _topicLength(0)
|
||||
, _ignore(false)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0)
|
||||
, _payloadLength(0)
|
||||
, _payloadBytesRead(0) {
|
||||
_dup = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_DUP;
|
||||
_retain = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_RETAIN;
|
||||
char qosMasked = _parsingInformation->packetFlags & 0x06;
|
||||
switch (qosMasked) {
|
||||
case HeaderFlag.PUBLISH_QOS0:
|
||||
_qos = 0;
|
||||
break;
|
||||
case HeaderFlag.PUBLISH_QOS1:
|
||||
_qos = 1;
|
||||
break;
|
||||
case HeaderFlag.PUBLISH_QOS2:
|
||||
_qos = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PublishPacket::~PublishPacket() {
|
||||
}
|
||||
|
||||
void PublishPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition == 0) {
|
||||
_topicLengthMsb = currentByte;
|
||||
} else if (_bytePosition == 1) {
|
||||
_topicLength = currentByte | _topicLengthMsb << 8;
|
||||
if (_topicLength > _parsingInformation->maxTopicLength) {
|
||||
_ignore = true;
|
||||
} else {
|
||||
_parsingInformation->topicBuffer[_topicLength] = '\0';
|
||||
}
|
||||
} else if (_bytePosition >= 2 && _bytePosition < 2 + _topicLength) {
|
||||
// Starting from here, _ignore might be true
|
||||
if (!_ignore) _parsingInformation->topicBuffer[_bytePosition - 2] = currentByte;
|
||||
if (_bytePosition == 2 + _topicLength - 1 && _qos == 0) {
|
||||
_preparePayloadHandling(_parsingInformation->remainingLength - (_bytePosition + 1));
|
||||
return;
|
||||
}
|
||||
} else if (_bytePosition == 2 + _topicLength) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_preparePayloadHandling(_parsingInformation->remainingLength - (_bytePosition + 1));
|
||||
}
|
||||
_bytePosition++;
|
||||
}
|
||||
|
||||
void PublishPacket::_preparePayloadHandling(uint32_t payloadLength) {
|
||||
_payloadLength = payloadLength;
|
||||
if (payloadLength == 0) {
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
if (!_ignore) {
|
||||
_dataCallback(_parsingInformation->topicBuffer, nullptr, _qos, _dup, _retain, 0, 0, 0, _packetId);
|
||||
_completeCallback(_packetId, _qos);
|
||||
}
|
||||
} else {
|
||||
_parsingInformation->bufferState = BufferState::PAYLOAD;
|
||||
}
|
||||
}
|
||||
|
||||
void PublishPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
size_t remainToRead = len - (*currentBytePosition);
|
||||
if (_payloadBytesRead + remainToRead > _payloadLength) remainToRead = _payloadLength - _payloadBytesRead;
|
||||
|
||||
if (!_ignore) _dataCallback(_parsingInformation->topicBuffer, data + (*currentBytePosition), _qos, _dup, _retain, remainToRead, _payloadBytesRead, _payloadLength, _packetId);
|
||||
_payloadBytesRead += remainToRead;
|
||||
(*currentBytePosition) += remainToRead;
|
||||
|
||||
if (_payloadBytesRead == _payloadLength) {
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
if (!_ignore) _completeCallback(_packetId, _qos);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../Flags.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class PublishPacket : public Packet {
|
||||
public:
|
||||
explicit PublishPacket(ParsingInformation* parsingInformation, OnMessageInternalCallback dataCallback, OnPublishInternalCallback completeCallback);
|
||||
~PublishPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnMessageInternalCallback _dataCallback;
|
||||
OnPublishInternalCallback _completeCallback;
|
||||
|
||||
void _preparePayloadHandling(uint32_t payloadLength);
|
||||
|
||||
bool _dup;
|
||||
uint8_t _qos;
|
||||
bool _retain;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _topicLengthMsb;
|
||||
uint16_t _topicLength;
|
||||
bool _ignore;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
uint32_t _payloadLength;
|
||||
uint32_t _payloadBytesRead;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "SubAckPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::SubAckPacket;
|
||||
|
||||
SubAckPacket::SubAckPacket(ParsingInformation* parsingInformation, OnSubAckInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0) {
|
||||
}
|
||||
|
||||
SubAckPacket::~SubAckPacket() {
|
||||
}
|
||||
|
||||
void SubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_parsingInformation->bufferState = BufferState::PAYLOAD;
|
||||
}
|
||||
}
|
||||
|
||||
void SubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char status = data[(*currentBytePosition)++];
|
||||
|
||||
/* switch (status) {
|
||||
case 0:
|
||||
Serial.println("Success QoS 0");
|
||||
break;
|
||||
case 1:
|
||||
Serial.println("Success QoS 1");
|
||||
break;
|
||||
case 2:
|
||||
Serial.println("Success QoS 2");
|
||||
break;
|
||||
case 0x80:
|
||||
Serial.println("Failure");
|
||||
break;
|
||||
} */
|
||||
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_packetId, status);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class SubAckPacket : public Packet {
|
||||
public:
|
||||
explicit SubAckPacket(ParsingInformation* parsingInformation, OnSubAckInternalCallback callback);
|
||||
~SubAckPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnSubAckInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "UnsubAckPacket.hpp"
|
||||
|
||||
using AsyncMqttClientInternals::UnsubAckPacket;
|
||||
|
||||
UnsubAckPacket::UnsubAckPacket(ParsingInformation* parsingInformation, OnUnsubAckInternalCallback callback)
|
||||
: _parsingInformation(parsingInformation)
|
||||
, _callback(callback)
|
||||
, _bytePosition(0)
|
||||
, _packetIdMsb(0)
|
||||
, _packetId(0) {
|
||||
}
|
||||
|
||||
UnsubAckPacket::~UnsubAckPacket() {
|
||||
}
|
||||
|
||||
void UnsubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) {
|
||||
char currentByte = data[(*currentBytePosition)++];
|
||||
if (_bytePosition++ == 0) {
|
||||
_packetIdMsb = currentByte;
|
||||
} else {
|
||||
_packetId = currentByte | _packetIdMsb << 8;
|
||||
_parsingInformation->bufferState = BufferState::NONE;
|
||||
_callback(_packetId);
|
||||
}
|
||||
}
|
||||
|
||||
void UnsubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) {
|
||||
(void)data;
|
||||
(void)currentBytePosition;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Packet.hpp"
|
||||
#include "../ParsingInformation.hpp"
|
||||
#include "../Callbacks.hpp"
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
class UnsubAckPacket : public Packet {
|
||||
public:
|
||||
explicit UnsubAckPacket(ParsingInformation* parsingInformation, OnUnsubAckInternalCallback callback);
|
||||
~UnsubAckPacket();
|
||||
|
||||
void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition);
|
||||
void parsePayload(char* data, size_t len, size_t* currentBytePosition);
|
||||
|
||||
private:
|
||||
ParsingInformation* _parsingInformation;
|
||||
OnUnsubAckInternalCallback _callback;
|
||||
|
||||
uint8_t _bytePosition;
|
||||
char _packetIdMsb;
|
||||
uint16_t _packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
enum class BufferState : uint8_t {
|
||||
NONE = 0,
|
||||
REMAINING_LENGTH = 2,
|
||||
VARIABLE_HEADER = 3,
|
||||
PAYLOAD = 4
|
||||
};
|
||||
|
||||
struct ParsingInformation {
|
||||
BufferState bufferState;
|
||||
|
||||
uint16_t maxTopicLength;
|
||||
char* topicBuffer;
|
||||
|
||||
uint8_t packetType;
|
||||
uint16_t packetFlags;
|
||||
uint32_t remainingLength;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace AsyncMqttClientInternals {
|
||||
struct PendingPubRel {
|
||||
uint16_t packetId;
|
||||
};
|
||||
|
||||
struct PendingAck {
|
||||
uint8_t packetType;
|
||||
uint8_t headerFlag;
|
||||
uint16_t packetId;
|
||||
};
|
||||
} // namespace AsyncMqttClientInternals
|
||||
21
wled00/src/dependencies/async-mqtt-client/LICENSE
Normal file
21
wled00/src/dependencies/async-mqtt-client/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marvin Roger
|
||||
|
||||
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.
|
||||
18
wled00/src/dependencies/async-mqtt-client/README.md
Normal file
18
wled00/src/dependencies/async-mqtt-client/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
Async MQTT client for ESP8266 and ESP32 (Github: https://github.com/marvinroger/async-mqtt-client)
|
||||
=============================
|
||||
|
||||
[](https://travis-ci.org/marvinroger/async-mqtt-client)
|
||||
|
||||
An Arduino for ESP8266 and ESP32 asynchronous [MQTT](http://mqtt.org/) client implementation, built on [me-no-dev/ESPAsyncTCP (ESP8266)](https://github.com/me-no-dev/ESPAsyncTCP) | [me-no-dev/AsyncTCP (ESP32)](https://github.com/me-no-dev/AsyncTCP) .
|
||||
## Features
|
||||
|
||||
* Compliant with the 3.1.1 version of the protocol
|
||||
* Fully asynchronous
|
||||
* Subscribe at QoS 0, 1 and 2
|
||||
* Publish at QoS 0, 1 and 2
|
||||
* SSL/TLS support
|
||||
* Available in the [PlatformIO registry](http://platformio.org/lib/show/346/AsyncMqttClient)
|
||||
|
||||
## Requirements, installation and usage
|
||||
|
||||
The project is documented in the [/docs folder](docs).
|
||||
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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user