Merge branch 'master' into CCT-support
This commit is contained in:
commit
0465298507
14
CHANGELOG.md
14
CHANGELOG.md
@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
### Builds after release 0.12.0
|
### Builds after release 0.12.0
|
||||||
|
|
||||||
|
#### Build 2111160
|
||||||
|
|
||||||
|
- Version bump to 0.13.0-b5 "Toki"
|
||||||
|
- Improv Serial support (PR #2334)
|
||||||
|
- Button improvements (PR #2284)
|
||||||
|
- Added two time zones (PR #2264, 2311)
|
||||||
|
- JSON in/decrementing support for brightness and presets
|
||||||
|
- Fixed no gamma correction for JSON individual LED control
|
||||||
|
- Preset cycle bugfix
|
||||||
|
- Removed ledCount
|
||||||
|
- LED settings buffer bugfix
|
||||||
|
- Network pin conflict bugfix
|
||||||
|
- Changed default ESP32 partition layout to 4M, 1M FS
|
||||||
|
|
||||||
#### Build 2110110
|
#### Build 2110110
|
||||||
|
|
||||||
- Version bump to 0.13.0-b4 "Toki"
|
- Version bump to 0.13.0-b4 "Toki"
|
||||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wled",
|
"name": "wled",
|
||||||
"version": "0.13.0-b4",
|
"version": "0.13.0-b5",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wled",
|
"name": "wled",
|
||||||
"version": "0.13.0-b4",
|
"version": "0.13.0-b5",
|
||||||
"description": "Tools for WLED project",
|
"description": "Tools for WLED project",
|
||||||
"main": "tools/cdata.js",
|
"main": "tools/cdata.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
@ -207,6 +207,8 @@ build_flags = -g
|
|||||||
-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
||||||
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
||||||
|
|
||||||
|
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
makuna/NeoPixelBus @ 2.6.7
|
makuna/NeoPixelBus @ 2.6.7
|
||||||
@ -292,6 +294,7 @@ platform = espressif32@2.0
|
|||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET
|
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
|
||||||
[env:esp32_eth]
|
[env:esp32_eth]
|
||||||
board = esp32-poe
|
board = esp32-poe
|
||||||
@ -300,6 +303,7 @@ upload_speed = 921600
|
|||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
|
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
|
||||||
[env:esp32s2_saola]
|
[env:esp32s2_saola]
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
@ -406,6 +410,7 @@ build_flags = ${common.build_flags_esp32}
|
|||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
OneWire@~2.3.5
|
OneWire@~2.3.5
|
||||||
olikraus/U8g2 @ ^2.28.8
|
olikraus/U8g2 @ ^2.28.8
|
||||||
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
|
||||||
[env:m5atom]
|
[env:m5atom]
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
@ -413,6 +418,7 @@ build_unflags = ${common.build_unflags}
|
|||||||
build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39
|
build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
platform = espressif32@3.2
|
platform = espressif32@3.2
|
||||||
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
|
||||||
[env:sp501e]
|
[env:sp501e]
|
||||||
board = esp_wroom_02
|
board = esp_wroom_02
|
||||||
@ -498,3 +504,4 @@ monitor_filters = esp32_exception_decoder
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${esp32.lib_deps}
|
${esp32.lib_deps}
|
||||||
TFT_eSPI @ ^2.3.70
|
TFT_eSPI @ ^2.3.70
|
||||||
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
@ -299,8 +299,11 @@ void handleIO()
|
|||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
// turn off built-in LED if strip is turned off
|
// turn off built-in LED if strip is turned off
|
||||||
// this will break digital bus so will need to be reinitialised on On
|
// this will break digital bus so will need to be reinitialised on On
|
||||||
|
PinOwner ledPinOwner = pinManager.getPinOwner(LED_BUILTIN);
|
||||||
|
if (!strip.isOffRefreshRequred && (ledPinOwner == PinOwner::None || ledPinOwner == PinOwner::BusDigital)) {
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
digitalWrite(LED_BUILTIN, HIGH);
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (rlyPin>=0) {
|
if (rlyPin>=0) {
|
||||||
pinMode(rlyPin, OUTPUT);
|
pinMode(rlyPin, OUTPUT);
|
||||||
|
@ -397,11 +397,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(DMXStartLED,dmx[F("start-led")]);
|
CJSON(DMXStartLED,dmx[F("start-led")]);
|
||||||
|
|
||||||
JsonArray dmx_fixmap = dmx[F("fixmap")];
|
JsonArray dmx_fixmap = dmx[F("fixmap")];
|
||||||
it = 0;
|
for (int i = 0; i < dmx_fixmap.size(); i++) {
|
||||||
for (int i : dmx_fixmap) {
|
if (i > 14) break;
|
||||||
if (it > 14) break;
|
|
||||||
CJSON(DMXFixtureMap[i],dmx_fixmap[i]);
|
CJSON(DMXFixtureMap[i],dmx_fixmap[i]);
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -265,12 +265,20 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// string temp buffer (now stored in stack locally)
|
// string temp buffer (now stored in stack locally)
|
||||||
#define OMAX 2048
|
#ifdef ESP8266
|
||||||
|
#define SETTINGS_STACK_BUF_SIZE 2048
|
||||||
|
#else
|
||||||
|
#define SETTINGS_STACK_BUF_SIZE 3096
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
#define E131_MAX_UNIVERSE_COUNT 20
|
#define E131_MAX_UNIVERSE_COUNT 20
|
||||||
#else
|
#else
|
||||||
#define E131_MAX_UNIVERSE_COUNT 10
|
#ifdef ESP8266
|
||||||
|
#define E131_MAX_UNIVERSE_COUNT 9
|
||||||
|
#else
|
||||||
|
#define E131_MAX_UNIVERSE_COUNT 12
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ABL_MILLIAMPS_DEFAULT 850 // auto lower brightness to stay close to milliampere limit
|
#define ABL_MILLIAMPS_DEFAULT 850 // auto lower brightness to stay close to milliampere limit
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
if (n2.substring(0,1)==="L") {
|
if (n2.substring(0,1)==="L") {
|
||||||
var m = LCs[j].name.substring(2);
|
var m = LCs[j].name.substring(2);
|
||||||
var t2 = parseInt(d.getElementsByName("LT"+m)[0].value, 10);
|
var t2 = parseInt(d.getElementsByName("LT"+m)[0].value, 10);
|
||||||
if (t2<16) continue;
|
if (t2>=80) continue;
|
||||||
}
|
}
|
||||||
if (LCs[j].value!="" && LCs[i].value==LCs[j].value) {alert(`Pin conflict between ${LCs[i].name}/${LCs[j].name}!`);LCs[j].value="";LCs[j].focus();return false;}
|
if (LCs[j].value!="" && LCs[i].value==LCs[j].value) {alert(`Pin conflict between ${LCs[i].name}/${LCs[j].name}!`);LCs[j].value="";LCs[j].focus();return false;}
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,12 @@ void onHueConnect(void* arg, AsyncClient* client);
|
|||||||
void sendHuePoll();
|
void sendHuePoll();
|
||||||
void onHueData(void* arg, AsyncClient* client, void *data, size_t len);
|
void onHueData(void* arg, AsyncClient* client, void *data, size_t len);
|
||||||
|
|
||||||
|
//improv.cpp
|
||||||
|
void handleImprovPacket();
|
||||||
|
void sendImprovStateResponse(uint8_t state, bool error = false);
|
||||||
|
void sendImprovInfoResponse();
|
||||||
|
void sendImprovRPCResponse(uint8_t commandId);
|
||||||
|
|
||||||
//ir.cpp
|
//ir.cpp
|
||||||
bool decodeIRCustom(uint32_t code);
|
bool decodeIRCustom(uint32_t code);
|
||||||
void applyRepeatActions();
|
void applyRepeatActions();
|
||||||
|
@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st
|
|||||||
.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%}#msg{display:none}
|
.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%}#msg{display:none}
|
||||||
</style></head><body><h2>WLED Software Update</h2><form method="POST"
|
</style></head><body><h2>WLED Software Update</h2><form method="POST"
|
||||||
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
|
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
|
||||||
Installed version: 0.13.0-b4<br>Download the latest binary: <a
|
Installed version: 0.13.0-b5<br>Download the latest binary: <a
|
||||||
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
|
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
|
||||||
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
|
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
|
||||||
</a><br><input type="file" class="bt" name="update" required><br><input
|
</a><br><input type="file" class="bt" name="update" required><br><input
|
||||||
|
@ -353,30 +353,29 @@ North Korea</option><option value="14">IST (India)</option><option value="15">
|
|||||||
CA-Saskatchewan</option><option value="16">ACST</option><option value="17">
|
CA-Saskatchewan</option><option value="16">ACST</option><option value="17">
|
||||||
ACST/ACDT</option><option value="18">HST (Hawaii)</option><option value="19">
|
ACST/ACDT</option><option value="18">HST (Hawaii)</option><option value="19">
|
||||||
NOVT (Novosibirsk)</option><option value="20">AKST/AKDT (Anchorage)</option>
|
NOVT (Novosibirsk)</option><option value="20">AKST/AKDT (Anchorage)</option>
|
||||||
<option value="21">MX-CST/CDT</option>
|
<option value="21">MX-CST/CDT</option></select><br>UTC offset: <input name="UO"
|
||||||
</select><br>UTC offset: <input name="UO" type="number" min="-65500"
|
type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||||
max="65500" required> seconds (max. 18 hours)<br>Current local time is <span
|
Current local time is <span class="times">unknown</span>.<br>Latitude (N):
|
||||||
class="times">unknown</span>.<br>Latitude (N): <input name="LT" type="number"
|
<input name="LT" type="number" min="-66.6" max="66.6" step="0.01">
|
||||||
min="-66.6" max="66.6" step="0.01"> Longitude (E): <input name="LN"
|
Longitude (E): <input name="LN" type="number" min="-180" max="180" step="0.01">
|
||||||
type="number" min="-180" max="180" step="0.01"><div id="sun" class="times">
|
<div id="sun" class="times"></div><h3>Clock</h3>Clock Overlay: <select
|
||||||
</div><h3>Clock</h3>Clock Overlay: <select name="OL" onchange="Cs()"><option
|
name="OL" onchange="Cs()"><option value="0" id="cn" selected="selected">None
|
||||||
value="0" id="cn" selected="selected">None</option><option value="1" id="ca">
|
</option><option value="1" id="ca">Analog Clock</option><option value="2">
|
||||||
Analog Clock</option><option value="2">Single Digit Clock</option><option
|
Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
|
||||||
value="3" id="cc">Cronixie Clock</option></select><br><div id="coc">First LED:
|
</select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
|
||||||
<input name="O1" type="number" min="0" max="255" required> Last LED: <input
|
max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
|
||||||
name="O2" type="number" min="0" max="255" required><br><div id="cac">12h LED:
|
required><br><div id="cac">12h LED: <input name="OM" type="number" min="0"
|
||||||
<input name="OM" type="number" min="0" max="255" required><br>Show 5min marks:
|
max="255" required><br>Show 5min marks: <input type="checkbox" name="O5"><br>
|
||||||
<input type="checkbox" name="O5"><br></div>Seconds (as trail): <input
|
</div>Seconds (as trail): <input type="checkbox" name="OS"><br></div><div
|
||||||
type="checkbox" name="OS"><br></div><div id="ccc">Cronixie Display: <input
|
id="ccc">Cronixie Display: <input name="CX" maxlength="6"><br>
|
||||||
name="CX" maxlength="6"><br>Cronixie Backlight: <input type="checkbox"
|
Cronixie Backlight: <input type="checkbox" name="CB"><br></div>Countdown Mode:
|
||||||
name="CB"><br></div>Countdown Mode: <input type="checkbox" name="CE"><br>
|
<input type="checkbox" name="CE"><br>Countdown Goal:<br>Year: 20 <input
|
||||||
Countdown Goal:<br>Year: 20 <input name="CY" type="number" min="0" max="99"
|
name="CY" type="number" min="0" max="99" required> Month: <input name="CI"
|
||||||
required> Month: <input name="CI" type="number" min="1" max="12" required> Day:
|
type="number" min="1" max="12" required> Day: <input name="CD" type="number"
|
||||||
<input name="CD" type="number" min="1" max="31" required><br>Hour: <input
|
min="1" max="31" required><br>Hour: <input name="CH" type="number" min="0"
|
||||||
name="CH" type="number" min="0" max="23" required> Minute: <input name="CM"
|
max="23" required> Minute: <input name="CM" type="number" min="0" max="59"
|
||||||
type="number" min="0" max="59" required> Second: <input name="CS" type="number"
|
required> Second: <input name="CS" type="number" min="0" max="59" required><br>
|
||||||
min="0" max="59" required><br><h3>Macro presets</h3><b>Macros have moved!</b>
|
<h3>Macro presets</h3><b>Macros have moved!</b><br><i>
|
||||||
<br><i>
|
|
||||||
Presets now also can be used as macros to save both JSON and HTTP API commands.
|
Presets now also can be used as macros to save both JSON and HTTP API commands.
|
||||||
<br>Just enter the preset id below!</i> <i>
|
<br>Just enter the preset id below!</i> <i>
|
||||||
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
|
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
|
||||||
@ -428,7 +427,7 @@ onclick='uploadFile(d.Sf.data2,"/cfg.json")'><br></div><div style="color:#fa0">
|
|||||||
Incorrect configuration may require a factory reset or re-flashing of your ESP.
|
Incorrect configuration may require a factory reset or re-flashing of your ESP.
|
||||||
</div>For security reasons, passwords are not backed up.<h3>About</h3><a
|
</div>For security reasons, passwords are not backed up.<h3>About</h3><a
|
||||||
href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
|
href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
|
||||||
version 0.13.0-b4<br><br><a
|
version 0.13.0-b5<br><br><a
|
||||||
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
|
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
|
||||||
target="_blank">Contributors, dependencies and special thanks</a><br>
|
target="_blank">Contributors, dependencies and special thanks</a><br>
|
||||||
A huge thank you to everyone who helped me create WLED!<br><br>
|
A huge thank you to everyone who helped me create WLED!<br><br>
|
||||||
|
244
wled00/improv.cpp
Normal file
244
wled00/improv.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
#include "wled.h"
|
||||||
|
|
||||||
|
#ifdef WLED_DEBUG_IMPROV
|
||||||
|
#define DIMPROV_PRINT(x) Serial.print(x)
|
||||||
|
#define DIMPROV_PRINTLN(x) Serial.println(x)
|
||||||
|
#define DIMPROV_PRINTF(x...) Serial.printf(x)
|
||||||
|
#else
|
||||||
|
#define DIMPROV_PRINT(x)
|
||||||
|
#define DIMPROV_PRINTLN(x)
|
||||||
|
#define DIMPROV_PRINTF(x...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IMPROV_VERSION 1
|
||||||
|
|
||||||
|
void parseWiFiCommand(char *rpcData);
|
||||||
|
|
||||||
|
enum ImprovPacketType {
|
||||||
|
Current_State = 0x01,
|
||||||
|
Error_State = 0x02,
|
||||||
|
RPC_Command = 0x03,
|
||||||
|
RPC_Response = 0x04
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImprovPacketByte {
|
||||||
|
Version = 6,
|
||||||
|
PacketType = 7,
|
||||||
|
Length = 8,
|
||||||
|
RPC_CommandType = 9
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImprovRPCType {
|
||||||
|
Command_Wifi = 0x01,
|
||||||
|
Request_State = 0x02,
|
||||||
|
Request_Info = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
//File dbgf;
|
||||||
|
|
||||||
|
//blocking function to parse an Improv Serial packet
|
||||||
|
void handleImprovPacket() {
|
||||||
|
uint8_t header[6] = {'I','M','P','R','O','V'};
|
||||||
|
|
||||||
|
//dbgf = WLED_FS.open("/improv.log","a");
|
||||||
|
|
||||||
|
bool timeout = false;
|
||||||
|
uint8_t waitTime = 25;
|
||||||
|
uint16_t packetByte = 0;
|
||||||
|
uint8_t packetLen = 9;
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
|
||||||
|
uint8_t rpcCommandType = 0;
|
||||||
|
char rpcData[128];
|
||||||
|
rpcData[0] = 0;
|
||||||
|
|
||||||
|
while (!timeout) {
|
||||||
|
if (Serial.available() < 1) {
|
||||||
|
delay(1);
|
||||||
|
waitTime--;
|
||||||
|
if (!waitTime) timeout = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
byte next = Serial.read();
|
||||||
|
|
||||||
|
DIMPROV_PRINT("Received improv byte: "); DIMPROV_PRINTF("%x\r\n",next);
|
||||||
|
//f.write(next);
|
||||||
|
switch (packetByte) {
|
||||||
|
case ImprovPacketByte::Version: {
|
||||||
|
if (next != IMPROV_VERSION) {
|
||||||
|
DIMPROV_PRINTLN(F("Invalid version"));
|
||||||
|
//dbgf.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ImprovPacketByte::PacketType: {
|
||||||
|
if (next != ImprovPacketType::RPC_Command) {
|
||||||
|
DIMPROV_PRINTF("Non RPC-command improv packet type %i\n",next);
|
||||||
|
//dbgf.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!improvActive) improvActive = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ImprovPacketByte::Length: packetLen = 9 + next; break;
|
||||||
|
case ImprovPacketByte::RPC_CommandType: rpcCommandType = next; break;
|
||||||
|
default: {
|
||||||
|
if (packetByte >= packetLen) { //end of packet, check checksum match
|
||||||
|
|
||||||
|
if (checksum != next) {
|
||||||
|
DIMPROV_PRINTF("Got RPC checksum %i, expected %i",next,checksum);
|
||||||
|
sendImprovStateResponse(0x01, true);
|
||||||
|
//dbgf.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rpcCommandType) {
|
||||||
|
case ImprovRPCType::Command_Wifi: parseWiFiCommand(rpcData); break;
|
||||||
|
case ImprovRPCType::Request_State: {
|
||||||
|
uint8_t improvState = 0x02; //authorized
|
||||||
|
if (WLED_WIFI_CONFIGURED) improvState = 0x03; //provisioning
|
||||||
|
if (Network.isConnected()) improvState = 0x04; //provisioned
|
||||||
|
sendImprovStateResponse(improvState, false);
|
||||||
|
if (improvState == 0x04) sendImprovRPCResponse(ImprovRPCType::Request_State);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ImprovRPCType::Request_Info: sendImprovInfoResponse(); break;
|
||||||
|
default: {
|
||||||
|
DIMPROV_PRINTF("Unknown RPC command %i\n",next);
|
||||||
|
sendImprovStateResponse(0x02, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//dbgf.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (packetByte < 6) { //check header
|
||||||
|
if (next != header[packetByte]) {
|
||||||
|
DIMPROV_PRINTLN(F("Invalid improv header"));
|
||||||
|
//dbgf.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (packetByte > 9) { //RPC data
|
||||||
|
rpcData[packetByte - 10] = next;
|
||||||
|
if (packetByte > 137) return; //prevent buffer overflow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum += next;
|
||||||
|
packetByte++;
|
||||||
|
}
|
||||||
|
//dbgf.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendImprovStateResponse(uint8_t state, bool error) {
|
||||||
|
if (!error && improvError > 0 && improvError < 3) sendImprovStateResponse(0x00, true);
|
||||||
|
if (error) improvError = state;
|
||||||
|
char out[11] = {'I','M','P','R','O','V'};
|
||||||
|
out[6] = IMPROV_VERSION;
|
||||||
|
out[7] = error? ImprovPacketType::Error_State : ImprovPacketType::Current_State;
|
||||||
|
out[8] = 1;
|
||||||
|
out[9] = state;
|
||||||
|
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (uint8_t i = 0; i < 10; i++) checksum += out[i];
|
||||||
|
out[10] = checksum;
|
||||||
|
Serial.write((uint8_t*)out, 11);
|
||||||
|
Serial.write('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendImprovRPCResponse(byte commandId) {
|
||||||
|
if (improvError > 0 && improvError < 3) sendImprovStateResponse(0x00, true);
|
||||||
|
uint8_t packetLen = 12;
|
||||||
|
char out[64] = {'I','M','P','R','O','V'};
|
||||||
|
out[6] = IMPROV_VERSION;
|
||||||
|
out[7] = ImprovPacketType::RPC_Response;
|
||||||
|
out[8] = 2; //Length (set below)
|
||||||
|
out[9] = commandId;
|
||||||
|
out[10] = 0; //Data len (set below)
|
||||||
|
out[11] = '\0'; //URL len (set below)
|
||||||
|
|
||||||
|
if (Network.isConnected())
|
||||||
|
{
|
||||||
|
IPAddress localIP = Network.localIP();
|
||||||
|
uint8_t len = sprintf(out+12, "http://%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
|
||||||
|
if (len > 24) return; //sprintf fail?
|
||||||
|
out[11] = len;
|
||||||
|
out[10] = 1 + len;
|
||||||
|
out[8] = 3 + len; //RPC command type + data len + url len + url
|
||||||
|
packetLen = 13 + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (uint8_t i = 0; i < packetLen -1; i++) checksum += out[i];
|
||||||
|
out[packetLen -1] = checksum;
|
||||||
|
Serial.write((uint8_t*)out, packetLen);
|
||||||
|
Serial.write('\n');
|
||||||
|
improvActive = 1; //no longer provisioning
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendImprovInfoResponse() {
|
||||||
|
if (improvError > 0 && improvError < 3) sendImprovStateResponse(0x00, true);
|
||||||
|
uint8_t packetLen = 12;
|
||||||
|
char out[128] = {'I','M','P','R','O','V'};
|
||||||
|
out[6] = IMPROV_VERSION;
|
||||||
|
out[7] = ImprovPacketType::RPC_Response;
|
||||||
|
//out[8] = 2; //Length (set below)
|
||||||
|
out[9] = ImprovRPCType::Request_Info;
|
||||||
|
//out[10] = 0; //Data len (set below)
|
||||||
|
out[11] = 4; //Firmware len ("WLED")
|
||||||
|
out[12] = 'W'; out[13] = 'L'; out[14] = 'E'; out[15] = 'D';
|
||||||
|
uint8_t lengthSum = 17;
|
||||||
|
uint8_t vlen = sprintf_P(out+lengthSum,PSTR("0.13.0-b5/%i"),VERSION);
|
||||||
|
out[16] = vlen; lengthSum += vlen;
|
||||||
|
uint8_t hlen = 7;
|
||||||
|
#ifdef ESP8266
|
||||||
|
strcpy(out+lengthSum+1,"esp8266");
|
||||||
|
#else
|
||||||
|
hlen = 5;
|
||||||
|
strcpy(out+lengthSum+1,"esp32");
|
||||||
|
#endif
|
||||||
|
out[lengthSum] = hlen;
|
||||||
|
lengthSum += hlen + 1;
|
||||||
|
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
||||||
|
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
||||||
|
strcpy(out+lengthSum+1,useMdnsName ? cmDNS : serverDescription);
|
||||||
|
uint8_t nlen = strlen(useMdnsName ? cmDNS : serverDescription);
|
||||||
|
out[lengthSum] = nlen;
|
||||||
|
lengthSum += nlen + 1;
|
||||||
|
|
||||||
|
packetLen = lengthSum +1;
|
||||||
|
out[8] = lengthSum -9;
|
||||||
|
out[10] = lengthSum -11;
|
||||||
|
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (uint8_t i = 0; i < packetLen -1; i++) checksum += out[i];
|
||||||
|
out[packetLen -1] = checksum;
|
||||||
|
Serial.write((uint8_t*)out, packetLen);
|
||||||
|
Serial.write('\n');
|
||||||
|
DIMPROV_PRINT("Info checksum");
|
||||||
|
DIMPROV_PRINTLN(checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parseWiFiCommand(char* rpcData) {
|
||||||
|
uint8_t len = rpcData[0];
|
||||||
|
if (!len || len > 126) return;
|
||||||
|
|
||||||
|
uint8_t ssidLen = rpcData[1];
|
||||||
|
if (ssidLen > len -1 || ssidLen > 32) return;
|
||||||
|
memset(clientSSID, 0, 32);
|
||||||
|
memcpy(clientSSID, rpcData+2, ssidLen);
|
||||||
|
|
||||||
|
memset(clientPass, 0, 64);
|
||||||
|
if (len > ssidLen +1) {
|
||||||
|
uint8_t passLen = rpcData[2+ssidLen];
|
||||||
|
memset(clientPass, 0, 64);
|
||||||
|
memcpy(clientPass, rpcData+3+ssidLen, passLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendImprovStateResponse(0x03); //provisioning
|
||||||
|
improvActive = 2;
|
||||||
|
|
||||||
|
forceReconnect = true;
|
||||||
|
serializeConfig();
|
||||||
|
}
|
@ -205,8 +205,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
|
|
||||||
if (set < 2) stop = start + 1;
|
if (set < 2) stop = start + 1;
|
||||||
for (uint16_t i = start; i < stop; i++) {
|
for (uint16_t i = start; i < stop; i++) {
|
||||||
|
if (strip.gammaCorrectCol) {
|
||||||
|
strip.setPixelColor(i, strip.gamma8(rgbw[0]), strip.gamma8(rgbw[1]), strip.gamma8(rgbw[2]), strip.gamma8(rgbw[3]));
|
||||||
|
} else {
|
||||||
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
|
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!set) start++;
|
if (!set) start++;
|
||||||
set = 0;
|
set = 0;
|
||||||
}
|
}
|
||||||
@ -522,7 +526,7 @@ void serializeInfo(JsonObject root)
|
|||||||
leds[F("fps")] = strip.getFps();
|
leds[F("fps")] = strip.getFps();
|
||||||
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||||
leds[F("maxseg")] = strip.getMaxSegments();
|
leds[F("maxseg")] = strip.getMaxSegments();
|
||||||
leds[F("seglock")] = false; //will be used in the future to prevent modifications to segment config
|
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||||
|
|
||||||
root[F("str")] = syncToggleReceive;
|
root[F("str")] = syncToggleReceive;
|
||||||
|
|
||||||
@ -584,7 +588,7 @@ void serializeInfo(JsonObject root)
|
|||||||
root[F("resetReason0")] = (int)rtc_get_reset_reason(0);
|
root[F("resetReason0")] = (int)rtc_get_reset_reason(0);
|
||||||
root[F("resetReason1")] = (int)rtc_get_reset_reason(1);
|
root[F("resetReason1")] = (int)rtc_get_reset_reason(1);
|
||||||
#endif
|
#endif
|
||||||
root[F("lwip")] = 0;
|
root[F("lwip")] = 0; //deprecated
|
||||||
#else
|
#else
|
||||||
root[F("arch")] = "esp8266";
|
root[F("arch")] = "esp8266";
|
||||||
root[F("core")] = ESP.getCoreVersion();
|
root[F("core")] = ESP.getCoreVersion();
|
||||||
|
@ -125,6 +125,11 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PinOwner PinManagerClass::getPinOwner(byte gpio) {
|
||||||
|
if (!isPinOk(gpio, false)) return PinOwner::None;
|
||||||
|
return ownerTag[gpio];
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
byte PinManagerClass::allocateLedc(byte channels)
|
byte PinManagerClass::allocateLedc(byte channels)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +92,8 @@ class PinManagerClass {
|
|||||||
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
|
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
|
||||||
bool isPinOk(byte gpio, bool output = true);
|
bool isPinOk(byte gpio, bool output = true);
|
||||||
|
|
||||||
|
PinOwner getPinOwner(byte gpio);
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
byte allocateLedc(byte channels);
|
byte allocateLedc(byte channels);
|
||||||
void deallocateLedc(byte pos, byte channels);
|
void deallocateLedc(byte pos, byte channels);
|
||||||
|
@ -42,7 +42,7 @@ bool oappendi(int i)
|
|||||||
bool oappend(const char* txt)
|
bool oappend(const char* txt)
|
||||||
{
|
{
|
||||||
uint16_t len = strlen(txt);
|
uint16_t len = strlen(txt);
|
||||||
if (olen + len >= OMAX)
|
if (olen + len >= SETTINGS_STACK_BUF_SIZE)
|
||||||
return false; // buffer full
|
return false; // buffer full
|
||||||
strcpy(obuf + olen, txt);
|
strcpy(obuf + olen, txt);
|
||||||
olen += len;
|
olen += len;
|
||||||
@ -303,7 +303,7 @@ void WLED::setup()
|
|||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
pinManager.allocatePin(1, true, PinOwner::DebugOut); // GPIO1 reserved for debug output
|
pinManager.allocatePin(1, true, PinOwner::DebugOut); // GPIO1 reserved for debug output
|
||||||
#endif
|
#endif
|
||||||
#ifdef WLED_USE_DMX //reserve GPIO2 as hardcoded DMX pin
|
#ifdef WLED_ENABLE_DMX //reserve GPIO2 as hardcoded DMX pin
|
||||||
pinManager.allocatePin(2, true, PinOwner::DMX);
|
pinManager.allocatePin(2, true, PinOwner::DMX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -374,6 +374,8 @@ void WLED::setup()
|
|||||||
sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6);
|
sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
|
||||||
|
|
||||||
strip.service();
|
strip.service();
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_OTA
|
#ifndef WLED_DISABLE_OTA
|
||||||
@ -391,6 +393,8 @@ void WLED::setup()
|
|||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
initDMX();
|
initDMX();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (Serial.available() > 0 && Serial.peek() == 'I') handleImprovPacket();
|
||||||
// HTTP server page init
|
// HTTP server page init
|
||||||
initServer();
|
initServer();
|
||||||
|
|
||||||
@ -720,14 +724,26 @@ void WLED::handleConnection()
|
|||||||
interfacesInited = false;
|
interfacesInited = false;
|
||||||
initConnection();
|
initConnection();
|
||||||
}
|
}
|
||||||
if (now - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED)
|
//send improv failed 6 seconds after second init attempt (24 sec. after provisioning)
|
||||||
|
if (improvActive > 2 && now - lastReconnectAttempt > 6000) {
|
||||||
|
sendImprovStateResponse(0x03, true);
|
||||||
|
improvActive = 2;
|
||||||
|
}
|
||||||
|
if (now - lastReconnectAttempt > ((stac) ? 300000 : 18000) && WLED_WIFI_CONFIGURED) {
|
||||||
|
if (improvActive == 2) improvActive = 3;
|
||||||
initConnection();
|
initConnection();
|
||||||
|
}
|
||||||
if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN))
|
if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN))
|
||||||
initAP();
|
initAP();
|
||||||
} else if (!interfacesInited) { //newly connected
|
} else if (!interfacesInited) { //newly connected
|
||||||
DEBUG_PRINTLN("");
|
DEBUG_PRINTLN("");
|
||||||
DEBUG_PRINT(F("Connected! IP address: "));
|
DEBUG_PRINT(F("Connected! IP address: "));
|
||||||
DEBUG_PRINTLN(Network.localIP());
|
DEBUG_PRINTLN(Network.localIP());
|
||||||
|
if (improvActive) {
|
||||||
|
if (improvError == 3) sendImprovStateResponse(0x00, true);
|
||||||
|
sendImprovStateResponse(0x04);
|
||||||
|
if (improvActive > 1) sendImprovRPCResponse(0x01);
|
||||||
|
}
|
||||||
initInterfaces();
|
initInterfaces();
|
||||||
userConnected();
|
userConnected();
|
||||||
usermods.connected();
|
usermods.connected();
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
/*
|
/*
|
||||||
Main sketch, global variable declarations
|
Main sketch, global variable declarations
|
||||||
@title WLED project sketch
|
@title WLED project sketch
|
||||||
@version 0.13.0-b4
|
@version 0.13.0-b5
|
||||||
@author Christian Schwinne
|
@author Christian Schwinne
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2110110
|
#define VERSION 2111170
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -507,6 +507,10 @@ WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 25
|
|||||||
// blynk
|
// blynk
|
||||||
WLED_GLOBAL bool blynkEnabled _INIT(false);
|
WLED_GLOBAL bool blynkEnabled _INIT(false);
|
||||||
|
|
||||||
|
//improv
|
||||||
|
WLED_GLOBAL byte improvActive _INIT(0); //0: no improv packet received, 1: improv active, 2: provisioning
|
||||||
|
WLED_GLOBAL byte improvError _INIT(0);
|
||||||
|
|
||||||
//playlists
|
//playlists
|
||||||
WLED_GLOBAL int16_t currentPlaylist _INIT(-1);
|
WLED_GLOBAL int16_t currentPlaylist _INIT(-1);
|
||||||
//still used for "PL=~" HTTP API command
|
//still used for "PL=~" HTTP API command
|
||||||
|
@ -16,7 +16,7 @@ enum class AdaState {
|
|||||||
Data_Blue,
|
Data_Blue,
|
||||||
TPM2_Header_Type,
|
TPM2_Header_Type,
|
||||||
TPM2_Header_CountHi,
|
TPM2_Header_CountHi,
|
||||||
TPM2_Header_CountLo
|
TPM2_Header_CountLo,
|
||||||
};
|
};
|
||||||
|
|
||||||
void handleSerial()
|
void handleSerial()
|
||||||
@ -41,7 +41,12 @@ void handleSerial()
|
|||||||
else if (next == 0xC9) { //TPM2 start byte
|
else if (next == 0xC9) { //TPM2 start byte
|
||||||
state = AdaState::TPM2_Header_Type;
|
state = AdaState::TPM2_Header_Type;
|
||||||
}
|
}
|
||||||
else if (next == '{') { //JSON API
|
else if (next == 'I') {
|
||||||
|
handleImprovPacket();
|
||||||
|
return;
|
||||||
|
} else if (next == 'v') {
|
||||||
|
Serial.print("WLED"); Serial.write(' '); Serial.println(VERSION);
|
||||||
|
} else if (next == '{') { //JSON API
|
||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
{
|
{
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
@ -61,6 +66,7 @@ void handleSerial()
|
|||||||
serializeInfo(info);
|
serializeInfo(info);
|
||||||
|
|
||||||
serializeJson(doc, Serial);
|
serializeJson(doc, Serial);
|
||||||
|
Serial.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -362,9 +362,10 @@ void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& h
|
|||||||
String settingsProcessor(const String& var)
|
String settingsProcessor(const String& var)
|
||||||
{
|
{
|
||||||
if (var == "CSS") {
|
if (var == "CSS") {
|
||||||
char buf[2048];
|
char buf[SETTINGS_STACK_BUF_SIZE];
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
getSettingsJS(optionType, buf);
|
getSettingsJS(optionType, buf);
|
||||||
|
//Serial.println(uxTaskGetStackHighWaterMark(NULL));
|
||||||
return String(buf);
|
return String(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user