From 1cdbb980f1859f1d2986c069875b9f6a855c4306 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 14 Oct 2022 23:55:07 +0300
Subject: [PATCH 001/319] Add support DS18x20_MULTI_GPIOs for esp8266
---
tasmota/include/tasmota.h | 3 +
tasmota/include/tasmota_template.h | 5 ++
tasmota/my_user_config.h | 3 +-
tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 2 +-
.../tasmota_xsns_sensor/xsns_05_ds18x20.ino | 78 ++++++++++++++++---
5 files changed, 79 insertions(+), 12 deletions(-)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index 614832513..3e696ba18 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -303,6 +303,9 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
#define XPT2046_MAXX 3895
#define XPT2046_MINY 346
#define XPT2046_MAXY 3870
+
+// Max number GPIO for DS18x20_MULTI_GPIOs
+#define MAX_DSB 4
/*********************************************************************************************\
* Enumeration
\*********************************************************************************************/
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 09b52c94f..13b4ce85b 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -661,8 +661,13 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321
#endif
#ifdef USE_DS18x20
+#ifdef DS18x20_MULTI_GPIOs
+ AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20
+ AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20
+#else
AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20
AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20
+#endif //DS18x20_MULTI_GPIOs
#endif
#ifdef USE_LMT01
AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 751a48b44..382982cb2 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -579,7 +579,8 @@
// -- One wire sensors ----------------------------
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
// #define W1_PARASITE_POWER // Optimize for parasite powered sensors
-// #define DS18x20_USE_ID_ALIAS
+ #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files.
+ #define DS18x20_MULTI_GPIOs // Add support for multiple GPIOs for DS18x20 sensors
// -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
index bb3d0ae71..33ba550b1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
@@ -491,7 +491,7 @@ void KNX_INIT(void)
device_param[KNX_HUMIDITY-1].show = true;
}
#ifdef USE_DS18x20
- if (PinUsed(GPIO_DSB)) {
+ if (PinUsed(GPIO_DSB, GPIO_ANY)) {
device_param[KNX_TEMPERATURE-1].show = true;
}
#endif
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 96f5b5882..520a30c94 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -63,8 +63,20 @@ struct {
#ifdef DS18x20_USE_ID_ALIAS
uint8_t alias;
#endif //DS18x20_USE_ID_ALIAS
+#ifdef DS18x20_MULTI_GPIOs
+ int8_t pins_id = 0;
+#endif //DS18x20_MULTI_GPIOs
} ds18x20_sensor[DS18X20_MAX_SENSORS];
+#ifdef DS18x20_MULTI_GPIOs
+struct {
+ int8_t pin = 0; // Shelly GPIO3 input only
+ int8_t pin_out = 0; // Shelly GPIO00 output only
+ bool dual_mode = false; // Single pin mode
+} ds18x20_gpios[MAX_DSB];
+uint8_t ds18x20_ngpio = 0; // Count of GPIO found
+#endif
+
struct {
#ifdef W1_PARASITE_POWER
uint32_t w1_power_until = 0;
@@ -301,16 +313,8 @@ bool OneWireCrc8(uint8_t *addr) {
/********************************************************************************************/
void Ds18x20Init(void) {
- DS18X20Data.pin = Pin(GPIO_DSB);
DS18X20Data.input_mode = Settings->flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT; // SetOption74 - Enable internal pullup for single DS18x20 sensor
- if (PinUsed(GPIO_DSB_OUT)) {
- DS18X20Data.pin_out = Pin(GPIO_DSB_OUT);
- DS18X20Data.dual_mode = true; // Dual pins mode as used by Shelly
- pinMode(DS18X20Data.pin_out, OUTPUT);
- pinMode(DS18X20Data.pin, DS18X20Data.input_mode);
- }
-
onewire_last_discrepancy = 0;
onewire_last_device_flag = false;
onewire_last_family_discrepancy = 0;
@@ -320,6 +324,39 @@ void Ds18x20Init(void) {
uint64_t ids[DS18X20_MAX_SENSORS];
DS18X20Data.sensors = 0;
+
+#ifdef DS18x20_MULTI_GPIOs
+uint8_t pins;
+ for (pins = 0; pins < MAX_DSB; pins++) {
+ if (PinUsed(GPIO_DSB, pins)) {
+ ds18x20_gpios[pins].pin = Pin(GPIO_DSB, pins);
+
+ if (PinUsed(GPIO_DSB_OUT, pins)) {
+ ds18x20_gpios[pins].dual_mode = true;
+ ds18x20_gpios[pins].pin_out = Pin(GPIO_DSB_OUT, pins);
+ }
+ ds18x20_ngpio++;
+ }
+ }
+ for (pins = 0; pins < ds18x20_ngpio; pins++) {
+ DS18X20Data.pin = ds18x20_gpios[pins].pin;
+ DS18X20Data.dual_mode = ds18x20_gpios[pins].dual_mode;
+ if (ds18x20_gpios[pins].dual_mode) {
+ DS18X20Data.pin_out = ds18x20_gpios[pins].pin_out;
+ pinMode(DS18X20Data.pin_out, OUTPUT);
+ pinMode(DS18X20Data.pin, DS18X20Data.input_mode);
+ }
+#else
+ DS18X20Data.pin = Pin(GPIO_DSB);
+
+ if (PinUsed(GPIO_DSB_OUT)) {
+ DS18X20Data.pin_out = Pin(GPIO_DSB_OUT);
+ DS18X20Data.dual_mode = true; // Dual pins mode as used by Shelly
+ pinMode(DS18X20Data.pin_out, OUTPUT);
+ pinMode(DS18X20Data.pin, DS18X20Data.input_mode);
+ }
+#endif //DS18x20_MULTI_GPIOs
+
while (DS18X20Data.sensors < DS18X20_MAX_SENSORS) {
if (!OneWireSearch(ds18x20_sensor[DS18X20Data.sensors].address)) {
break;
@@ -337,9 +374,16 @@ void Ds18x20Init(void) {
#ifdef DS18x20_USE_ID_ALIAS
ds18x20_sensor[DS18X20Data.sensors].alias=0;
#endif
+#ifdef DS18x20_MULTI_GPIOs
+ ds18x20_sensor[DS18X20Data.sensors].pins_id = pins;
+#endif //DS18x20_MULTI_GPIOs
DS18X20Data.sensors++;
}
}
+#ifdef DS18x20_MULTI_GPIOs
+ }
+#endif //DS18x20_MULTI_GPIOs
+
for (uint32_t i = 0; i < DS18X20Data.sensors; i++) {
for (uint32_t j = i + 1; j < DS18X20Data.sensors; j++) {
if (ids[ds18x20_sensor[i].index] > ids[ds18x20_sensor[j].index]) { // Sort ascending
@@ -351,6 +395,12 @@ void Ds18x20Init(void) {
}
void Ds18x20Convert(void) {
+#ifdef DS18x20_MULTI_GPIOs
+ for (uint8_t i = 0; i < ds18x20_ngpio; i++) {
+ DS18X20Data.pin = ds18x20_gpios[i].pin;
+ DS18X20Data.dual_mode = ds18x20_gpios[i].dual_mode;
+ DS18X20Data.pin_out = ds18x20_gpios[i].pin_out;
+#endif
OneWireReset();
#ifdef W1_PARASITE_POWER
// With parasite power address one sensor at a time
@@ -362,6 +412,9 @@ void Ds18x20Convert(void) {
#endif
OneWireWrite(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
// delay(750); // 750ms should be enough for 12bit conv
+#ifdef DS18x20_MULTI_GPIOs
+ }
+#endif
}
bool Ds18x20Read(uint8_t sensor) {
@@ -369,6 +422,11 @@ bool Ds18x20Read(uint8_t sensor) {
uint8_t data[9];
int8_t sign = 1;
+#ifdef DS18x20_MULTI_GPIOs
+ DS18X20Data.pin = ds18x20_gpios[ds18x20_sensor[sensor].pins_id].pin;
+ DS18X20Data.pin_out = ds18x20_gpios[ds18x20_sensor[sensor].pins_id].pin_out;
+ DS18X20Data.dual_mode = ds18x20_gpios[ds18x20_sensor[sensor].pins_id].dual_mode;
+#endif
uint8_t index = ds18x20_sensor[sensor].index;
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
for (uint32_t retry = 0; retry < 3; retry++) {
@@ -580,8 +638,8 @@ void CmndDSAlias(void) {
bool Xsns05(uint8_t function) {
bool result = false;
-
- if (PinUsed(GPIO_DSB)) {
+
+ if (PinUsed(GPIO_DSB,GPIO_ANY)) {
switch (function) {
case FUNC_INIT:
Ds18x20Init();
From 9ae38a979799b0aac0a99361a6ab9e6273393f0d Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 14 Oct 2022 23:56:58 +0300
Subject: [PATCH 002/319] tests
From d8a356049703b9ce6684bbb8e017e5838cfeaf91 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 12:05:38 +0300
Subject: [PATCH 003/319] Ready fo tests
---
tasmota/my_user_config.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 382982cb2..f00e84225 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -579,8 +579,8 @@
// -- One wire sensors ----------------------------
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
// #define W1_PARASITE_POWER // Optimize for parasite powered sensors
- #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files.
- #define DS18x20_MULTI_GPIOs // Add support for multiple GPIOs for DS18x20 sensors
+ #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
+ #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
// -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
From 59c7488e70f30f7d1973c9bd0fac4ef1aecb18a8 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 14:25:43 +0300
Subject: [PATCH 004/319] Corrections based on sensor sorting
---
.../tasmota_xsns_sensor/xsns_05_ds18x20.ino | 36 +++++++++++--------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 520a30c94..37c45e88d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -16,6 +16,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
+// #define W1_PARASITE_POWER // Optimize for parasite powered sensors
+ #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
+ #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
#ifdef ESP8266
#ifdef USE_DS18x20
@@ -58,14 +62,14 @@ struct {
float temp_sum;
uint16_t numread;
uint8_t address[8];
- uint8_t index;
- uint8_t valid;
#ifdef DS18x20_USE_ID_ALIAS
uint8_t alias;
#endif //DS18x20_USE_ID_ALIAS
#ifdef DS18x20_MULTI_GPIOs
int8_t pins_id = 0;
#endif //DS18x20_MULTI_GPIOs
+ uint8_t index;
+ uint8_t valid;
} ds18x20_sensor[DS18X20_MAX_SENSORS];
#ifdef DS18x20_MULTI_GPIOs
@@ -315,15 +319,9 @@ bool OneWireCrc8(uint8_t *addr) {
void Ds18x20Init(void) {
DS18X20Data.input_mode = Settings->flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT; // SetOption74 - Enable internal pullup for single DS18x20 sensor
- onewire_last_discrepancy = 0;
- onewire_last_device_flag = false;
- onewire_last_family_discrepancy = 0;
- for (uint32_t i = 0; i < 8; i++) {
- onewire_rom_id[i] = 0;
- }
-
uint64_t ids[DS18X20_MAX_SENSORS];
DS18X20Data.sensors = 0;
+ ds18x20_ngpio=0;
#ifdef DS18x20_MULTI_GPIOs
uint8_t pins;
@@ -338,6 +336,7 @@ uint8_t pins;
ds18x20_ngpio++;
}
}
+
for (pins = 0; pins < ds18x20_ngpio; pins++) {
DS18X20Data.pin = ds18x20_gpios[pins].pin;
DS18X20Data.dual_mode = ds18x20_gpios[pins].dual_mode;
@@ -357,6 +356,13 @@ uint8_t pins;
}
#endif //DS18x20_MULTI_GPIOs
+ onewire_last_discrepancy = 0;
+ onewire_last_device_flag = false;
+ onewire_last_family_discrepancy = 0;
+ for (uint32_t i = 0; i < 8; i++) {
+ onewire_rom_id[i] = 0;
+ }
+
while (DS18X20Data.sensors < DS18X20_MAX_SENSORS) {
if (!OneWireSearch(ds18x20_sensor[DS18X20Data.sensors].address)) {
break;
@@ -384,6 +390,7 @@ uint8_t pins;
}
#endif //DS18x20_MULTI_GPIOs
+//#ifndef DS18x20_MULTI_GPIOs
for (uint32_t i = 0; i < DS18X20Data.sensors; i++) {
for (uint32_t j = i + 1; j < DS18X20Data.sensors; j++) {
if (ids[ds18x20_sensor[i].index] > ids[ds18x20_sensor[j].index]) { // Sort ascending
@@ -391,6 +398,7 @@ uint8_t pins;
}
}
}
+//#endif
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors);
}
@@ -422,12 +430,12 @@ bool Ds18x20Read(uint8_t sensor) {
uint8_t data[9];
int8_t sign = 1;
-#ifdef DS18x20_MULTI_GPIOs
- DS18X20Data.pin = ds18x20_gpios[ds18x20_sensor[sensor].pins_id].pin;
- DS18X20Data.pin_out = ds18x20_gpios[ds18x20_sensor[sensor].pins_id].pin_out;
- DS18X20Data.dual_mode = ds18x20_gpios[ds18x20_sensor[sensor].pins_id].dual_mode;
-#endif
uint8_t index = ds18x20_sensor[sensor].index;
+#ifdef DS18x20_MULTI_GPIOs
+ DS18X20Data.pin = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin;
+ DS18X20Data.pin_out = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin_out;
+ DS18X20Data.dual_mode = ds18x20_gpios[ds18x20_sensor[index].pins_id].dual_mode;
+#endif
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
for (uint32_t retry = 0; retry < 3; retry++) {
OneWireReset();
From 8c81ee7487630154fc33a438313662645f8f550e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 14:52:45 +0300
Subject: [PATCH 005/319] Ready for test esp8266
---
tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 37c45e88d..5eb83b454 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -2,6 +2,7 @@
xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Tasmota
Copyright (C) 2021 Theo Arends
+ Supplement by md5sum-as
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,10 +17,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
-// #define W1_PARASITE_POWER // Optimize for parasite powered sensors
- #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
- #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
#ifdef ESP8266
#ifdef USE_DS18x20
@@ -34,7 +31,7 @@
/* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h
* Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255
- * Result in JSON: "DS18Alias_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2)
+ * Result in JSON: "DS18Sens_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2)
* add 8 bytes used memory
*/
@@ -512,15 +509,14 @@ void Ds18x20Name(uint8_t sensor) {
}
snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%s"), DS18X20Data.name, IndexSeparator(), address);
#else
+uint8_t print_ind = sensor +1;
#ifdef DS18x20_USE_ID_ALIAS
if (ds18x20_sensor[sensor].alias) {
- snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Alias%c%d"), IndexSeparator(), ds18x20_sensor[sensor].alias);
- } else {
-#endif
- snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), sensor +1);
-#ifdef DS18x20_USE_ID_ALIAS
+ snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Sens"));
+ print_ind = ds18x20_sensor[sensor].alias;
}
#endif
+ snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), print_ind);
#endif
}
}
From 5c9c7f2e26cae57928534caef338e98fbf2c437c Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 14:58:23 +0300
Subject: [PATCH 006/319] Ready for test esp8266
---
tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 5eb83b454..59a6a06b3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -2,7 +2,7 @@
xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Tasmota
Copyright (C) 2021 Theo Arends
- Supplement by md5sum-as
+ Supplement by md5sum-as (https://github.com/md5sum-as)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
From 61027810fa4966e376eca5d67b9c9eda2db0ef89 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 18:38:47 +0300
Subject: [PATCH 007/319] Ready for test on esp8266 and esp32
---
tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 59a6a06b3..8f130d93a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -2,8 +2,7 @@
xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Tasmota
Copyright (C) 2021 Theo Arends
- Supplement by md5sum-as (https://github.com/md5sum-as)
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -16,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
+
+ Updated by md5sum-as (https://github.com/md5sum-as)
*/
#ifdef ESP8266
@@ -59,14 +60,14 @@ struct {
float temp_sum;
uint16_t numread;
uint8_t address[8];
+ uint8_t index;
+ uint8_t valid;
#ifdef DS18x20_USE_ID_ALIAS
uint8_t alias;
#endif //DS18x20_USE_ID_ALIAS
#ifdef DS18x20_MULTI_GPIOs
int8_t pins_id = 0;
#endif //DS18x20_MULTI_GPIOs
- uint8_t index;
- uint8_t valid;
} ds18x20_sensor[DS18X20_MAX_SENSORS];
#ifdef DS18x20_MULTI_GPIOs
From c4ba1457a13cc8e92493c9134c423d5ad39c2b42 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 18:39:37 +0300
Subject: [PATCH 008/319] Ready for test on esp8266 and esp32
---
.../xsns_05_esp32_ds18x20.ino | 56 ++++++++++++++++---
1 file changed, 47 insertions(+), 9 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
index dd6bc33ea..345747b87 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
@@ -2,7 +2,7 @@
xsns_05_esp32_ds18x20.ino - DS18x20 temperature sensor support for ESP32 Tasmota
Copyright (C) 2021 Heiko Krupp and Theo Arends
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -15,8 +15,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-*/
+ Updated by md5sum-as (https://github.com/md5sum-as)
+*/
#ifdef ESP32
#ifdef USE_DS18x20
@@ -59,9 +60,19 @@ struct {
uint8_t valid;
#ifdef DS18x20_USE_ID_ALIAS
uint8_t alias;
-#endif //DS18x20_USE_ID_ALIAS
+#endif //DS18x20_USE_ID_ALIAS
+#ifdef DS18x20_MULTI_GPIOs
+ int8_t pins_id = 0;
+#endif //DS18x20_MULTI_GPIOs
} ds18x20_sensor[DS18X20_MAX_SENSORS];
+#include
+
+#ifdef DS18x20_MULTI_GPIOs
+OneWire *ds18x20_gpios[MAX_DSB];
+uint8_t ds18x20_ngpio = 0; // Count of GPIO found
+#endif
+
struct {
char name[17];
uint8_t sensors = 0;
@@ -69,13 +80,20 @@ struct {
/********************************************************************************************/
-#include
-
OneWire *ds = nullptr;
void Ds18x20Init(void) {
- ds = new OneWire(Pin(GPIO_DSB));
+#ifdef DS18x20_MULTI_GPIOs
+ for (uint8_t pins = 0; pins < MAX_DSB; pins++) {
+ if (PinUsed(GPIO_DSB, pins)) {
+ ds18x20_gpios[pins] = new OneWire(Pin(GPIO_DSB,pins));
+ ds18x20_ngpio++;
+ }
+ }
+#else
+ ds = new OneWire(Pin(GPIO_DSB));
+#endif
Ds18x20Search();
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors);
}
@@ -84,8 +102,12 @@ void Ds18x20Search(void) {
uint8_t num_sensors=0;
uint8_t sensor = 0;
+#ifdef DS18x20_MULTI_GPIOs
+ for (uint8_t pins=0; pins < ds18x20_ngpio; pins++) {
+ ds=ds18x20_gpios[pins];
+#endif
ds->reset_search();
- for (num_sensors = 0; num_sensors < DS18X20_MAX_SENSORS; num_sensors) {
+ for (num_sensors; num_sensors < DS18X20_MAX_SENSORS; num_sensors) {
if (!ds->search(ds18x20_sensor[num_sensors].address)) {
ds->reset_search();
break;
@@ -99,9 +121,16 @@ void Ds18x20Search(void) {
#ifdef DS18x20_USE_ID_ALIAS
ds18x20_sensor[num_sensors].alias=0;
#endif
+#ifdef DS18x20_MULTI_GPIOs
+ ds18x20_sensor[num_sensors].pins_id = pins;
+#endif //DS18x20_MULTI_GPIOs
num_sensors++;
}
}
+#ifdef DS18x20_MULTI_GPIOs
+ }
+#endif //DS18x20_MULTI_GPIOs
+
for (uint32_t i = 0; i < num_sensors; i++) {
ds18x20_sensor[i].index = i;
}
@@ -116,10 +145,17 @@ void Ds18x20Search(void) {
}
void Ds18x20Convert(void) {
+#ifdef DS18x20_MULTI_GPIOs
+ for (uint8_t i = 0; i < ds18x20_ngpio; i++) {
+ ds=ds18x20_gpios[i];
+#endif
ds->reset();
ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
// delay(750); // 750ms should be enough for 12bit conv
+#ifdef DS18x20_MULTI_GPIOs
+ }
+#endif
}
bool Ds18x20Read(uint8_t sensor, float &t) {
@@ -130,7 +166,9 @@ bool Ds18x20Read(uint8_t sensor, float &t) {
uint8_t index = ds18x20_sensor[sensor].index;
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
-
+#ifdef DS18x20_MULTI_GPIOs
+ ds=ds18x20_gpios[ds18x20_sensor[index].pins_id];
+#endif
ds->reset();
ds->select(ds18x20_sensor[index].address);
ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad
@@ -315,7 +353,7 @@ void CmndDSAlias(void) {
bool Xsns05(uint8_t function) {
bool result = false;
- if (PinUsed(GPIO_DSB)) {
+ if (PinUsed(GPIO_DSB,GPIO_ANY)) {
switch (function) {
case FUNC_INIT:
Ds18x20Init();
From 4b2181482f37afbbeef8c9b142dedbdd4316c28c Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 18:40:17 +0300
Subject: [PATCH 009/319] Ready for test on esp8266 and esp32
---
tasmota/my_user_config.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index f00e84225..967c41de4 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -579,8 +579,8 @@
// -- One wire sensors ----------------------------
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
// #define W1_PARASITE_POWER // Optimize for parasite powered sensors
- #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
- #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
+// #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
+// #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
// -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
From d4f3bc732bd71705670cef2e613a4b76f4825b8f Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 18:57:29 +0300
Subject: [PATCH 010/319] ESP32 don't support dual pin mode
---
tasmota/include/tasmota_template.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 13b4ce85b..35d928b31 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -663,10 +663,14 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#ifdef USE_DS18x20
#ifdef DS18x20_MULTI_GPIOs
AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20
+#ifdef ESP8266 // ESP32 don't support dual pin mode
AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20
+#endif
#else
AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20
+#ifdef ESP8266 // ESP32 don't support dual pin mode
AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20
+#endif
#endif //DS18x20_MULTI_GPIOs
#endif
#ifdef USE_LMT01
From fa649ec1742bc6478bb3f812a5e5f060e0126ae9 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 19:05:35 +0300
Subject: [PATCH 011/319] naming optimization
---
tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
index 345747b87..b37639c7a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
@@ -223,15 +223,14 @@ void Ds18x20Name(uint8_t sensor) {
}
snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%s"), DS18X20Data.name, IndexSeparator(), address);
#else
+uint8_t print_ind = sensor +1;
#ifdef DS18x20_USE_ID_ALIAS
if (ds18x20_sensor[sensor].alias) {
- snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Alias%c%d"), IndexSeparator(), ds18x20_sensor[sensor].alias);
- } else {
-#endif
- snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), sensor +1);
-#ifdef DS18x20_USE_ID_ALIAS
+ snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Sens"));
+ print_ind = ds18x20_sensor[sensor].alias;
}
#endif
+ snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), print_ind);
#endif
}
}
From 1f8012482e28bc24ce66d228f119b53df2a51df7 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sat, 15 Oct 2022 19:27:06 +0300
Subject: [PATCH 012/319] Fix compilation error
---
tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 8f130d93a..bbc71b1a5 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -319,9 +319,9 @@ void Ds18x20Init(void) {
uint64_t ids[DS18X20_MAX_SENSORS];
DS18X20Data.sensors = 0;
- ds18x20_ngpio=0;
#ifdef DS18x20_MULTI_GPIOs
+ ds18x20_ngpio=0;
uint8_t pins;
for (pins = 0; pins < MAX_DSB; pins++) {
if (PinUsed(GPIO_DSB, pins)) {
From 065396ff73dc1529e5242602c54dc11d17886a0d Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 17 Oct 2022 11:25:22 +0200
Subject: [PATCH 013/319] Bump version v12.2.0.1
---
CHANGELOG.md | 22 ++++++++----
RELEASENOTES.md | 59 ++++---------------------------
tasmota/include/tasmota_version.h | 2 +-
3 files changed, 23 insertions(+), 60 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de43ebc1d..d475bd835 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,12 +3,10 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [12.1.1.6]
+## [12.2.0.1]
### Added
-- Command ``WcClock 10..200`` set webcam clock in MHz. Default is 20
-- ESP32 Automatically resize FS to max flash size at initial boot (#16838)
-- Command ``SspmPowerOnState 0|1|2`` to set Sonoff SPM 4Relay module v1.2.0 power on state overruling tasmota global power on state. 0 = Off, 1 = On, 2 = Saved state (#13447)
-- Support for Flash size 32/64/128 MB in Partition Wizard and auto-resize
+
+### Breaking Changed
### Changed
@@ -16,6 +14,18 @@ All notable changes to this project will be documented in this file.
### Removed
+## [Released]
+
+## [12.2.0] 20221017
+- Release Patrick
+
+## [12.1.1.6] 20221017
+### Added
+- Command ``WcClock 10..200`` set webcam clock in MHz. Default is 20
+- ESP32 Automatically resize FS to max flash size at initial boot (#16838)
+- Command ``SspmPowerOnState 0|1|2`` to set Sonoff SPM 4Relay module v1.2.0 power on state overruling tasmota global power on state. 0 = Off, 1 = On, 2 = Saved state (#13447)
+- Support for Flash size 32/64/128 MB in Partition Wizard and auto-resize
+
## [12.1.1.5] 20221013
### Added
- Command ``Sunrise 0..3`` to select sunrise dawn angle between Normal, Civil, Nautical or Astronomical (#16795)
@@ -91,8 +101,6 @@ All notable changes to this project will be documented in this file.
### Changed
- ESP32 NimBLE library from v1.3.6 to v1.4.0
-## [Released]
-
## [12.1.1] 20220825
- Release Patricia
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index aaa20d4a2..9884f96f3 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -72,7 +72,7 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release
Historical binaries can be downloaded from
-- http://ota.tasmota.com/tasmota/release-12.1.1
+- http://ota.tasmota.com/tasmota/release-12.2.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
@@ -97,7 +97,7 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota32/release
Historical binaries can be downloaded from
-- http://ota.tasmota.com/tasmota32/release-12.1.1
+- http://ota.tasmota.com/tasmota32/release-12.2.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota32/release/tasmota32.bin``
@@ -107,58 +107,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v12.1.1.6
+## Changelog v12.2.0.1
### Added
-- Command ``SetOption46 0..255`` to add 0..255 * 10 milliseconds power on delay before initializing I/O [#15438](https://github.com/arendst/Tasmota/issues/15438)
-- Command ``SetOption146 1`` to enable display of ESP32 internal temperature
-- Command ``DspSpeed 2..127`` to control message rotation speed on display of POWR3xxD and THR3xxD
-- Command ``DspLine<1|2> ,,,,...`` to select message(s) on display of POWR3xxD and THR3xxD
-- Command ``SspmPowerOnState 0|1|2`` to set Sonoff SPM 4Relay module v1.2.0 power on state overruling tasmota global power on state. 0 = Off, 1 = On, 2 = Saved state [#13447](https://github.com/arendst/Tasmota/issues/13447)
-- Command ``StatusRetain 0|1`` [#11109](https://github.com/arendst/Tasmota/issues/11109)
-- Command ``Sunrise 0..3`` to select sunrise dawn angle between Normal, Civil, Nautical or Astronomical [#16795](https://github.com/arendst/Tasmota/issues/16795)
-- Command ``UrlFetch `` to download a file to filesystem
-- Command ``WcClock 10..200`` set webcam clock in MHz. Default is 20
-- Support for Shelly Plus 2PM
-- Support for SGP40 gas and air quality sensor [#16341](https://github.com/arendst/Tasmota/issues/16341)
-- Support for Modbus writing using ModbusBridge by JeroenSt [#16351](https://github.com/arendst/Tasmota/issues/16351)
-- Support for DFRobot SEN0390 V30B ambient light sensor [#16105](https://github.com/arendst/Tasmota/issues/16105)
-- Support for QMC5883L magnetic induction sensor by Helge Scheunemann [#16714](https://github.com/arendst/Tasmota/issues/16714)
-- Support for Modbus Energy Monitoring devices using a rule file. See ``xnrg_29_modbus.ino`` for more information
-- Support for flowrate meter flow amount/duration, show values in table format [#16385](https://github.com/arendst/Tasmota/issues/16385)
-- Support of optional file calib.dat on ADE7953 based energy monitors like Shelly EM [#16486](https://github.com/arendst/Tasmota/issues/16486)
-- Zigbee device plugin mechanism with commands ``ZbLoad``, ``ZbUnload`` and ``ZbLoadDump`` [#16252](https://github.com/arendst/Tasmota/issues/16252)
-- Zigbee basic support for Green Power [#16407](https://github.com/arendst/Tasmota/issues/16407)
-- Zigbee friendly names per endpoint
-- Zigbee Alexa/Hue emulation, support multiple switches on separate endpoints [#16718](https://github.com/arendst/Tasmota/issues/16718)
-- Support for Ethernet in ESP32 safeboot firmware [#16388](https://github.com/arendst/Tasmota/issues/16388)
-- ESP32-S3 support for internal temperature sensor
-- ESP32-S2 and ESP32-S3 touch button support
-- ESP32 Automatically resize FS to max flash size at initial boot [#16838](https://github.com/arendst/Tasmota/issues/16838)
-- Berry has persistent MQTT subscriptions: auto-subscribe at (re)connection
-- Berry automated solidification of code
-- LVGL/HASPmota add tiny "pixel perfect" fonts for small screens [#16758](https://github.com/arendst/Tasmota/issues/16758)
-- HASPmota support for TTF fonts [#16759](https://github.com/arendst/Tasmota/issues/16759)
+
+### Breaking Changed
### Changed
-- IRremoteESP8266 library from v2.8.2 to v2.8.4
-- TasmotaModbus library from v3.5.0 to v3.6.0 [#16351](https://github.com/arendst/Tasmota/issues/16351)
-- ESP32 NimBLE library from v1.3.6 to v1.4.0
-- ESP32 LVGL library from v8.3.0 to v8.3.2
-- ESP32 Tasmota Core32 from 2.0.4.1 to 2.0.5
-- Command ``SerialBuffer`` raise max allowed buffer size to 2048 characters [#16374](https://github.com/arendst/Tasmota/issues/16374)
-- Increase serial console input buffer size from 520 to 800
-- Button debouncing V3 by adopting switch debounce code [#16339](https://github.com/arendst/Tasmota/issues/16339)
-- Thermostat max allowed temperature from 100 to 200C [#16363](https://github.com/arendst/Tasmota/issues/16363)
-- Shelly EM swap internal channels A and B to match P1 and P2 [#16486](https://github.com/arendst/Tasmota/issues/16486)
-- Shelly EM phase calibration set to 200 (from 0) [#16486](https://github.com/arendst/Tasmota/issues/16486)
-- Zigbee report unprocessed attributes
-- ESP32 Increase number of button GPIOs from 8 to 28 [#16518](https://github.com/arendst/Tasmota/issues/16518)
-- ESP32 Platformio one Platform for all Tasmota frameworks Core32 2.0.5 [#16644](https://github.com/arendst/Tasmota/issues/16644)
### Fixed
-- RTC not detected when lights are present [#16242](https://github.com/arendst/Tasmota/issues/16242)
-- DNS lookup for .local domains [#16273](https://github.com/arendst/Tasmota/issues/16273)
-- Button response delay regression from v12.0.2.4 [#16319](https://github.com/arendst/Tasmota/issues/16319)
-- Lost module name in GUI regression from v12.0.2.4 - 20220803 [#16324](https://github.com/arendst/Tasmota/issues/16324)
-- Removed whitespace from JSON values with no decimals [#16365](https://github.com/arendst/Tasmota/issues/16365)
-- ESP32 touch button multi-press and hold detection [#16596](https://github.com/arendst/Tasmota/issues/16596)
+
+### Removed
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index 0c687d1ac..992709ba0 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x0C010106; // 12.1.1.6
+const uint32_t VERSION = 0x0C020001; // 12.2.0.1
#endif // _TASMOTA_VERSION_H_
From bc4fb77db0c91c6d9418b6ed700261a74f4fcf18 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 17 Oct 2022 15:37:26 +0200
Subject: [PATCH 014/319] refac (#16845)
* Update sensor.h
* Update esp_camera.h
* refactor boards manifests
* fix s3 safebooot env
* fix env
---
boards/{esp32-cam.json => esp32-fix.json} | 8 +--
boards/esp32-m5core2.json | 38 --------------
boards/esp32-odroid.json | 38 --------------
boards/{esp32_4M.json => esp32.json} | 2 +-
boards/esp32_16M.json | 38 --------------
boards/esp32_4M_FS.json | 46 -----------------
boards/esp32_4M_Legacy.json | 38 --------------
boards/esp32_8M.json | 38 --------------
.../{esp32_solo1_4M.json => esp32_solo1.json} | 4 +-
boards/esp32c3.json | 2 +-
boards/esp32c3cdc.json | 2 +-
boards/esp32c3cdc_Legacy.json | 37 --------------
boards/esp32s2.json | 2 +-
boards/esp32s2_Legacy.json | 35 -------------
boards/esp32s2cdc.json | 2 +-
.../{esp32s3_8M.json => esp32s3-qio_opi.json} | 20 +++++---
.../{esp32s3.json => esp32s3-qio_qspi.json} | 2 +-
boards/esp32s3cdc-box.json | 40 ---------------
boards/esp32s3cdc-cam.json | 49 -------------------
boards/esp32s3cdc-eye.json | 49 -------------------
...dc_Legacy.json => esp32s3cdc-qio_opi.json} | 24 +++++++--
...p32s3cdc.json => esp32s3cdc-qio_qspi.json} | 14 +++++-
boards/esp32s3cdc_LilyTDisp.json | 47 ------------------
.../esp32-camera/driver/include/esp_camera.h | 43 ++++++++++++----
.../esp32-camera/driver/include/sensor.h | 18 ++++++-
platformio_override_sample.ini | 17 +++----
platformio_tasmota_cenv_sample.ini | 37 ++++++++++----
platformio_tasmota_env32.ini | 37 ++++++--------
28 files changed, 161 insertions(+), 566 deletions(-)
rename boards/{esp32-cam.json => esp32-fix.json} (67%)
delete mode 100644 boards/esp32-m5core2.json
delete mode 100644 boards/esp32-odroid.json
rename boards/{esp32_4M.json => esp32.json} (92%)
delete mode 100644 boards/esp32_16M.json
delete mode 100644 boards/esp32_4M_FS.json
delete mode 100644 boards/esp32_4M_Legacy.json
delete mode 100644 boards/esp32_8M.json
rename boards/{esp32_solo1_4M.json => esp32_solo1.json} (81%)
delete mode 100644 boards/esp32c3cdc_Legacy.json
delete mode 100644 boards/esp32s2_Legacy.json
rename boards/{esp32s3_8M.json => esp32s3-qio_opi.json} (63%)
rename boards/{esp32s3.json => esp32s3-qio_qspi.json} (92%)
delete mode 100644 boards/esp32s3cdc-box.json
delete mode 100644 boards/esp32s3cdc-cam.json
delete mode 100644 boards/esp32s3cdc-eye.json
rename boards/{esp32s3cdc_Legacy.json => esp32s3cdc-qio_opi.json} (64%)
rename boards/{esp32s3cdc.json => esp32s3cdc-qio_qspi.json} (78%)
delete mode 100644 boards/esp32s3cdc_LilyTDisp.json
diff --git a/boards/esp32-cam.json b/boards/esp32-fix.json
similarity index 67%
rename from boards/esp32-cam.json
rename to boards/esp32-fix.json
index 165b8ef58..90132b94e 100644
--- a/boards/esp32-cam.json
+++ b/boards/esp32-fix.json
@@ -4,7 +4,7 @@
"ldscript": "esp32_out.ld"
},
"core": "esp32",
- "extra_flags": "-DCAMERA_MODEL_AI_THINKER -DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "AI Thinker ESP32-CAM, 4M Flash 4MB PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 >= 4M Flash, PSRAM with fix, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
@@ -41,6 +41,6 @@
"require_upload_port": true,
"speed": 460800
},
- "url": "https://wiki.ai-thinker.com/esp32-cam",
- "vendor": "AI Thinker"
+ "url": "https://en.wikipedia.org/wiki/ESP32",
+ "vendor": "Espressif"
}
diff --git a/boards/esp32-m5core2.json b/boards/esp32-m5core2.json
deleted file mode 100644
index 7fc157edb..000000000
--- a/boards/esp32-m5core2.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_M5STACK_Core2 -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "mcu": "esp32",
- "variant": "m5stack_core2",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "M5Stack Core2 16M Flash, 4MB PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 2000000
- },
- "url": "http://www.m5stack.com",
- "vendor": "M5Stack"
-}
diff --git a/boards/esp32-odroid.json b/boards/esp32-odroid.json
deleted file mode 100644
index f7804af4e..000000000
--- a/boards/esp32-odroid.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ODROID_ESP32 -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "odroid_esp32",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "ESP32 ODROID-GO 16M Flash, 4MB PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 2000000
- },
- "url": "https://www.hardkernel.com/main/products/prdt_info.php?g_code=G152875062626",
- "vendor": "Hardkernel"
-}
diff --git a/boards/esp32_4M.json b/boards/esp32.json
similarity index 92%
rename from boards/esp32_4M.json
rename to boards/esp32.json
index d8e39873f..0159ea555 100644
--- a/boards/esp32_4M.json
+++ b/boards/esp32.json
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32_16M.json b/boards/esp32_16M.json
deleted file mode 100644
index c0956a642..000000000
--- a/boards/esp32_16M.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 16M Flash, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32_4M_FS.json b/boards/esp32_4M_FS.json
deleted file mode 100644
index c2c7fb2ef..000000000
--- a/boards/esp32_4M_FS.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app1856k_fs1344k.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
- "upload": {
- "arduino": {
- "flash_extra_images": [
- [
- "0x10000",
- "variants/tasmota/tasmota32-safeboot.bin"
- ]
- ]
- },
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
- }
diff --git a/boards/esp32_4M_Legacy.json b/boards/esp32_4M_Legacy.json
deleted file mode 100644
index fccad9d15..000000000
--- a/boards/esp32_4M_Legacy.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
- "upload": {
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
- }
diff --git a/boards/esp32_8M.json b/boards/esp32_8M.json
deleted file mode 100644
index e7a351a4d..000000000
--- a/boards/esp32_8M.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_8M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
- "upload": {
- "flash_size": "8MB",
- "maximum_ram_size": 327680,
- "maximum_size": 8388608,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32_solo1_4M.json b/boards/esp32_solo1.json
similarity index 81%
rename from boards/esp32_solo1_4M.json
rename to boards/esp32_solo1.json
index ebc5affe9..3723e27b2 100644
--- a/boards/esp32_solo1_4M.json
+++ b/boards/esp32_solo1.json
@@ -4,7 +4,7 @@
"ldscript": "esp32_out.ld"
},
"core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
"f_cpu": "80000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3.json b/boards/esp32c3.json
index 955589dd3..74a740dee 100644
--- a/boards/esp32c3.json
+++ b/boards/esp32c3.json
@@ -23,7 +23,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3cdc.json b/boards/esp32c3cdc.json
index 648fce5ec..b29b2ca98 100644
--- a/boards/esp32c3cdc.json
+++ b/boards/esp32c3cdc.json
@@ -23,7 +23,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3cdc_Legacy.json b/boards/esp32c3cdc_Legacy.json
deleted file mode 100644
index 8a5d88804..000000000
--- a/boards/esp32c3cdc_Legacy.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32c3_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3 -DUSE_USB_CDC_CONSOLE",
- "f_cpu": "160000000L",
- "f_flash": "80000000L",
- "flash_mode": "dio",
- "mcu": "esp32c3",
- "variant": "esp32c3",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth"
- ],
- "debug": {
- "openocd_target": "esp32c3.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
- "upload": {
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
- "vendor": "Espressif"
- }
diff --git a/boards/esp32s2.json b/boards/esp32s2.json
index 1fd5f0768..e24ffd17d 100644
--- a/boards/esp32s2.json
+++ b/boards/esp32s2.json
@@ -22,7 +22,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s2_Legacy.json b/boards/esp32s2_Legacy.json
deleted file mode 100644
index 9bbae7b88..000000000
--- a/boards/esp32s2_Legacy.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s2_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S2",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "dio",
- "mcu": "esp32s2",
- "variant": "esp32s2",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
- },
- "connectivity": [
- "wifi"
- ],
- "debug": {
- "openocd_target": "esp32s2.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
- "upload": {
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32s2cdc.json b/boards/esp32s2cdc.json
index e71bdbdf6..03be3a6c0 100644
--- a/boards/esp32s2cdc.json
+++ b/boards/esp32s2cdc.json
@@ -22,7 +22,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s3_8M.json b/boards/esp32s3-qio_opi.json
similarity index 63%
rename from boards/esp32s3_8M.json
rename to boards/esp32s3-qio_opi.json
index 46dea18ba..003053268 100644
--- a/boards/esp32s3_8M.json
+++ b/boards/esp32s3-qio_opi.json
@@ -2,16 +2,16 @@
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
- "memory_type": "qio_qspi"
+ "memory_type": "qio_opi"
},
"core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_8M -DESP32S3",
+ "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s3",
"variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
+ "partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@@ -25,11 +25,19 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
- "flash_size": "8MB",
+ "arduino": {
+ "flash_extra_images": [
+ [
+ "0x10000",
+ "variants/tasmota/tasmota32s3-safeboot.bin"
+ ]
+ ]
+ },
+ "flash_size": "4MB",
"maximum_ram_size": 327680,
- "maximum_size": 8388608,
+ "maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
diff --git a/boards/esp32s3.json b/boards/esp32s3-qio_qspi.json
similarity index 92%
rename from boards/esp32s3.json
rename to boards/esp32s3-qio_qspi.json
index df9527c2c..64633ab50 100644
--- a/boards/esp32s3.json
+++ b/boards/esp32s3-qio_qspi.json
@@ -25,7 +25,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s3cdc-box.json b/boards/esp32s3cdc-box.json
deleted file mode 100644
index 5388523be..000000000
--- a/boards/esp32s3cdc-box.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "Espressif Generic ESP32-S3 16M Flash, Tasmota 2880k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
- "vendor": "Espressif"
-}
-
diff --git a/boards/esp32s3cdc-cam.json b/boards/esp32s3cdc-cam.json
deleted file mode 100644
index 761236e61..000000000
--- a/boards/esp32s3cdc-cam.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DCAMERA_MODEL_TTGO_T_CAM_SIM -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": [
- "esp-builtin"
- ],
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "LilyGo T-SIMCAM ESP32-S3 16M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://github.com/Xinyuan-LilyGO/LilyGo-Camera-Series",
- "vendor": "LilyGo"
-}
diff --git a/boards/esp32s3cdc-eye.json b/boards/esp32s3cdc-eye.json
deleted file mode 100644
index 3254a45df..000000000
--- a/boards/esp32s3cdc-eye.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DCAMERA_MODEL_ESP32S3_EYE -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_8M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": [
- "esp-builtin"
- ],
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "ESP32-S3-EYE 8M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 2M FS",
- "upload": {
- "flash_size": "8MB",
- "maximum_ram_size": 327680,
- "maximum_size": 8388608,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://github.com/espressif/esp-who/blob/master/docs/en/get-started/ESP32-S3-EYE_Getting_Started_Guide.md",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32s3cdc_Legacy.json b/boards/esp32s3cdc-qio_opi.json
similarity index 64%
rename from boards/esp32s3cdc_Legacy.json
rename to boards/esp32s3cdc-qio_opi.json
index 2fe80ff44..ad577df29 100644
--- a/boards/esp32s3cdc_Legacy.json
+++ b/boards/esp32s3cdc-qio_opi.json
@@ -2,16 +2,22 @@
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
- "memory_type": "qio_qspi"
+ "memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
"mcu": "esp32s3",
"variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
+ "partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@@ -19,14 +25,26 @@
"ethernet"
],
"debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": [
+ "esp-builtin"
+ ],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
+ "arduino": {
+ "flash_extra_images": [
+ [
+ "0x10000",
+ "variants/tasmota/tasmota32s3-safeboot.bin"
+ ]
+ ]
+ },
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
diff --git a/boards/esp32s3cdc.json b/boards/esp32s3cdc-qio_qspi.json
similarity index 78%
rename from boards/esp32s3cdc.json
rename to boards/esp32s3cdc-qio_qspi.json
index f4cb53cde..81ac63bd2 100644
--- a/boards/esp32s3cdc.json
+++ b/boards/esp32s3cdc-qio_qspi.json
@@ -9,6 +9,12 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
@@ -19,19 +25,23 @@
"ethernet"
],
"debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": [
+ "esp-builtin"
+ ],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
- "variants/tasmota/tasmota32s3cdc-safeboot.bin"
+ "variants/tasmota/tasmota32s3-safeboot.bin"
]
]
},
diff --git a/boards/esp32s3cdc_LilyTDisp.json b/boards/esp32s3cdc_LilyTDisp.json
deleted file mode 100644
index f9a7c0702..000000000
--- a/boards/esp32s3cdc_LilyTDisp.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_8M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": "esp-builtin",
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "LilyGo T-Display-S3 16M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://github.com/Xinyuan-LilyGO/T-Display-S3",
- "vendor": "LilyGo"
- }
diff --git a/lib/libesp32/esp32-camera/driver/include/esp_camera.h b/lib/libesp32/esp32-camera/driver/include/esp_camera.h
index e9981671f..ee84b307b 100644
--- a/lib/libesp32/esp32-camera/driver/include/esp_camera.h
+++ b/lib/libesp32/esp32-camera/driver/include/esp_camera.h
@@ -18,8 +18,8 @@
.pin_pwdn = PIN_PWDN,
.pin_reset = PIN_RESET,
.pin_xclk = PIN_XCLK,
- .pin_sscb_sda = PIN_SIOD,
- .pin_sscb_scl = PIN_SIOC,
+ .pin_sccb_sda = PIN_SIOD,
+ .pin_sccb_scl = PIN_SIOC,
.pin_d7 = PIN_D7,
.pin_d6 = PIN_D6,
.pin_d5 = PIN_D5,
@@ -70,6 +70,7 @@
#include "driver/ledc.h"
#include "sensor.h"
#include "sys/time.h"
+#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
@@ -84,13 +85,26 @@ typedef enum {
} camera_grab_mode_t;
/**
- * @brief Camera frame buffer location
+ * @brief Camera frame buffer location
*/
typedef enum {
CAMERA_FB_IN_PSRAM, /*!< Frame buffer is placed in external PSRAM */
CAMERA_FB_IN_DRAM /*!< Frame buffer is placed in internal DRAM */
} camera_fb_location_t;
+#if CONFIG_CAMERA_CONVERTER_ENABLED
+/**
+ * @brief Camera RGB\YUV conversion mode
+ */
+typedef enum {
+ CONV_DISABLE,
+ RGB565_TO_YUV422,
+
+ YUV422_TO_RGB565,
+ YUV422_TO_YUV420
+} camera_conv_mode_t;
+#endif
+
/**
* @brief Configuration structure for camera initialization
*/
@@ -98,8 +112,14 @@ typedef struct {
int pin_pwdn; /*!< GPIO pin for camera power down line */
int pin_reset; /*!< GPIO pin for camera reset line */
int pin_xclk; /*!< GPIO pin for camera XCLK line */
- int pin_sscb_sda; /*!< GPIO pin for camera SDA line */
- int pin_sscb_scl; /*!< GPIO pin for camera SCL line */
+ union {
+ int pin_sccb_sda; /*!< GPIO pin for camera SDA line */
+ int pin_sscb_sda __attribute__((deprecated("please use pin_sccb_sda instead"))); /*!< GPIO pin for camera SDA line (legacy name) */
+ };
+ union {
+ int pin_sccb_scl; /*!< GPIO pin for camera SCL line */
+ int pin_sscb_scl __attribute__((deprecated("please use pin_sccb_scl instead"))); /*!< GPIO pin for camera SCL line (legacy name) */
+ };
int pin_d7; /*!< GPIO pin for camera D7 line */
int pin_d6; /*!< GPIO pin for camera D6 line */
int pin_d5; /*!< GPIO pin for camera D5 line */
@@ -124,6 +144,11 @@ typedef struct {
size_t fb_count; /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed) */
camera_fb_location_t fb_location; /*!< The location where the frame buffer will be allocated */
camera_grab_mode_t grab_mode; /*!< When buffers should be filled */
+#if CONFIG_CAMERA_CONVERTER_ENABLED
+ camera_conv_mode_t conv_mode; /*!< RGB<->YUV Conversion mode */
+#endif
+
+ int sccb_i2c_port; /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
} camera_config_t;
/**
@@ -194,15 +219,15 @@ sensor_t * esp_camera_sensor_get();
/**
* @brief Save camera settings to non-volatile-storage (NVS)
- *
- * @param key A unique nvs key name for the camera settings
+ *
+ * @param key A unique nvs key name for the camera settings
*/
esp_err_t esp_camera_save_to_nvs(const char *key);
/**
* @brief Load camera settings from non-volatile-storage (NVS)
- *
- * @param key A unique nvs key name for the camera settings
+ *
+ * @param key A unique nvs key name for the camera settings
*/
esp_err_t esp_camera_load_from_nvs(const char *key);
diff --git a/lib/libesp32/esp32-camera/driver/include/sensor.h b/lib/libesp32/esp32-camera/driver/include/sensor.h
index 1f99c1541..6ab12a21a 100644
--- a/lib/libesp32/esp32-camera/driver/include/sensor.h
+++ b/lib/libesp32/esp32-camera/driver/include/sensor.h
@@ -26,6 +26,11 @@ typedef enum {
GC2145_PID = 0x2145,
GC032A_PID = 0x232a,
GC0308_PID = 0x9b,
+ BF3005_PID = 0x30,
+ BF20A6_PID = 0x20a6,
+ SC101IOT_PID = 0xda4a,
+ SC030IOT_PID = 0x9a46,
+ SC031GS_PID = 0x0031,
} camera_pid_t;
typedef enum {
@@ -38,6 +43,11 @@ typedef enum {
CAMERA_GC2145,
CAMERA_GC032A,
CAMERA_GC0308,
+ CAMERA_BF3005,
+ CAMERA_BF20A6,
+ CAMERA_SC101IOT,
+ CAMERA_SC030IOT,
+ CAMERA_SC031GS,
CAMERA_MODEL_MAX,
CAMERA_NONE,
} camera_model_t;
@@ -52,11 +62,17 @@ typedef enum {
GC2145_SCCB_ADDR = 0x3C,// 0x78 >> 1
GC032A_SCCB_ADDR = 0x21,// 0x42 >> 1
GC0308_SCCB_ADDR = 0x21,// 0x42 >> 1
+ BF3005_SCCB_ADDR = 0x6E,
+ BF20A6_SCCB_ADDR = 0x6E,
+ SC101IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
+ SC030IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
+ SC031GS_SCCB_ADDR = 0x30,
} camera_sccb_addr_t;
typedef enum {
PIXFORMAT_RGB565, // 2BPP/RGB565
PIXFORMAT_YUV422, // 2BPP/YUV422
+ PIXFORMAT_YUV420, // 1.5BPP/YUV420
PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
PIXFORMAT_JPEG, // JPEG/COMPRESSED
PIXFORMAT_RGB888, // 3BPP/RGB888
@@ -196,7 +212,7 @@ typedef struct _sensor {
// Sensor function pointers
int (*init_status) (sensor_t *sensor);
- int (*reset) (sensor_t *sensor);
+ int (*reset) (sensor_t *sensor); // Reset the configuration of the sensor, and return ESP_OK if reset is successful
int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat);
int (*set_framesize) (sensor_t *sensor, framesize_t framesize);
int (*set_contrast) (sensor_t *sensor, int level);
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index ad7937d1c..02a8f92e6 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -98,19 +98,18 @@ lib_extra_dirs = ${library.lib_extra_dirs}
; *** Uncomment next lines ";" to enable development Tasmota Arduino version ESP32
;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.1/platform-espressif32-2.0.5.1.zip
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1008/framework-arduinoespressif32-IDF_Arduino-d772747b2.zip
-; = framework-arduino-ITEAD @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1014/framework-arduinoespressif32-solo1-IDF_Arduino-d772747b2.zip
-; framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1013/framework-arduinoespressif32-ITEAD-IDF_Arduino-d772747b2.zip
+; framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1014/framework-arduinoespressif32-solo1-IDF_Arduino-d772747b2.zip
+; framework-arduino-ITEAD @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1013/framework-arduinoespressif32-ITEAD-IDF_Arduino-d772747b2.zip
;build_unflags = ${esp32_defaults.build_unflags}
;build_flags = ${esp32_defaults.build_flags}
-
-; Build variant ESP32 4M Flash, Tasmota 1856k Code/OTA, 1344k LITTLEFS (default)
-;board = esp32_4M
-; Build variant ESP32 8M Flash, Tasmota 2944k Code/OTA, 2112k LITTLEFS
-;board = esp32_8M
-; Build variant ESP32 16M Flash, Tasmota 2944k Code/OTA, 10M LITTLEFS
-;board = esp32_16M
+;board = esp32
;board_build.f_cpu = 240000000L
;board_build.f_flash = 40000000L
+;board_build.flash_mode = qio
+;board_build.flash_size = 8MB
+;board_upload.maximum_size = 8388608
+;board_upload.arduino.flash_extra_images =
+;board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv
monitor_speed = 115200
; *** Serial port used for erasing/flashing the ESP32
;upload_port = ${common.upload_port}
diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini
index bb10ec1b1..397ac0792 100644
--- a/platformio_tasmota_cenv_sample.ini
+++ b/platformio_tasmota_cenv_sample.ini
@@ -14,12 +14,29 @@ build_flags = ${env:tasmota32_base.build_flags}
[env:tasmota32s3-file]
extends = env:tasmota32_base
-board = esp32s3
+board = esp32s3-qio_qspi
+board_build.f_cpu = 240000000L
+board_build.f_flash = 80000000L
build_flags = ${env:tasmota32_base.build_flags} -D FIRMWARE_TASMOTA32
-; example for custom file upload in Tasmota Filesystem
-; custom_files_upload = ${env:tasmota32_base.custom_files_upload}
-; tasmota/berry/modules/Partition_wizard.tapp
-; https://github.com/tasmota/autoconf/raw/main/esp32s3/DevKitC-1.autoconf
+; !!! Real flash size needed, avoid autoresize since it is formating FS !!!
+board_upload.flash_size = 8MB
+board_upload.maximum_size = 8388608
+; Without autoresize a partition scheme is needed which does fit to flash size
+board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv
+; Dont use safeboot, not used in this partition scheme -> an empty entry needed to overwrite the default setting
+board_upload.arduino.flash_extra_images =
+; Example for custom file upload in Tasmota Filesystem
+custom_files_upload = ${env:tasmota32_base.custom_files_upload}
+ tasmota/berry/modules/Partition_wizard.tapp
+ https://github.com/tasmota/autoconf/raw/main/esp32s3/DevKitC-1.autoconf
+
+[env:tasmota32s3-qio_opi-all]
+extends = env:tasmota32_base
+board = esp32s3-qio_opi
+board_build.f_cpu = 240000000L
+board_build.f_flash = 80000000L
+build_flags = ${env:tasmota32_base.build_flags} -DUSE_WEBCAM -DUSE_BERRY_ULP -DFIRMWARE_LVGL -DUSE_LVGL_OPENHASP
+
[env:tasmota32c3-bluetooth]
extends = env:tasmota32c3
@@ -64,7 +81,7 @@ lib_ignore = ESP8266Audio
TTGO TWatch Library
Micro-RTSP
epdiy
- esp32-camera
+ esp32-camera
[env:tasmota32s3-mi32-homebridge]
extends = env:tasmota32s3
@@ -108,7 +125,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32-ocd]
build_type = debug
extends = env:tasmota32_base
-board = esp32_4M
+board = esp32
debug_tool = esp-prog
upload_protocol = esp-prog
debug_init_break = tbreak setup
@@ -119,7 +136,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32solo1-ocd]
build_type = debug
extends = env:tasmota32solo1
-board = esp32_solo1_4M
+board = esp32_solo1
debug_tool = esp-prog
upload_protocol = esp-prog
debug_init_break = tbreak setup
@@ -143,7 +160,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32s3cdc-ocd]
build_type = debug
extends = env:tasmota32s3
-board = esp32s3cdc
+board = esp32s3cdc-qio_opi
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_init_break = tbreak setup
@@ -154,7 +171,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32c3cdc-ocd]
build_type = debug
extends = env:tasmota32c3
-board = esp32c3cdc
+board = esp32c3cdc-qio_opi
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_init_break = tbreak setup
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index 154d5d42f..c938bb876 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -4,7 +4,7 @@ platform = ${core32.platform}
platform_packages = ${core32.platform_packages}
board_build.filesystem = ${common.board_build.filesystem}
custom_unpack_dir = ${common.custom_unpack_dir}
-board = esp32_4M
+board = esp32
monitor_speed = 115200
upload_port = ${common.upload_port}
upload_resetmethod = ${common.upload_resetmethod}
@@ -54,29 +54,24 @@ lib_ignore =
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
-[env:tasmota32_8M]
-extends = env:tasmota32_base
-board = esp32_8M
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
-
-[env:tasmota32_16M]
-extends = env:tasmota32_base
-board = esp32_16M
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
-
[env:tasmota32-webcam]
extends = env:tasmota32_base
-board = esp32-cam
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM
+board = esp32-fix
+board_build.f_cpu = 240000000L
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM -DCAMERA_MODEL_AI_THINKER
lib_extra_dirs = lib/lib_ssl, lib/libesp32
[env:tasmota32-odroidgo]
extends = env:tasmota32-lvgl
-board = esp32-odroid
+board_build.f_cpu = 240000000L
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 -DARDUINO_ODROID_ESP32
+board = esp32-fix
[env:tasmota32-core2]
extends = env:tasmota32-lvgl
-board = esp32-m5core2
+board_build.flash_mode = qio
+board_build.f_cpu = 240000000L
+board_build.f_flash = 80000000L
build_flags = ${env:tasmota32-lvgl.build_flags} -DUSE_I2S_SAY_TIME -DUSE_I2S_WEBRADIO -DUSE_SENDMAIL
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display, lib/lib_audio
@@ -93,7 +88,7 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_display, lib/lib_
[env:tasmota32-lvgl]
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_LVGL
-board_build.f_cpu = 160000000L
+board_build.f_cpu = 240000000L
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display
[env:tasmota32-ir]
@@ -103,11 +98,11 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl
[env:tasmota32solo1]
extends = env:tasmota32_base
-board = esp32_solo1_4M
+board = esp32_solo1
[env:tasmota32solo1-safeboot]
extends = env:tasmota32_base
-board = esp32_solo1_4M
+board = esp32_solo1
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
@@ -117,7 +112,7 @@ lib_ignore =
[env:tasmota32-zbbrdgpro]
extends = env:tasmota32_base
-board = esp32_4M_FS
+board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tasmota32_base.build_flags}
-DFIRMWARE_ZBBRDGPRO
-DFRAMEWORK_ARDUINO_ITEAD
@@ -201,7 +196,7 @@ board = esp32s2cdc
[env:tasmota32s3-safeboot]
extends = env:tasmota32_base
-board = esp32s3
+board = esp32s3-qio_qspi
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
@@ -220,7 +215,7 @@ lib_ignore =
[env:tasmota32s3cdc-safeboot]
extends = env:tasmota32s3-safeboot
-board = esp32s3cdc
+board = esp32s3cdc-qio_qspi
[env:tasmota32s3cdc]
extends = env:tasmota32s3
From 6b1deb5e5e2c6f90166ee42c674fe6cc2f71da56 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 17 Oct 2022 15:38:30 +0200
Subject: [PATCH 015/319] Revert "refac (#16845)" (#16846)
This reverts commit bc4fb77db0c91c6d9418b6ed700261a74f4fcf18.
---
boards/{esp32-fix.json => esp32-cam.json} | 8 +--
boards/esp32-m5core2.json | 38 ++++++++++++++
boards/esp32-odroid.json | 38 ++++++++++++++
boards/esp32_16M.json | 38 ++++++++++++++
boards/{esp32.json => esp32_4M.json} | 2 +-
boards/esp32_4M_FS.json | 46 +++++++++++++++++
boards/esp32_4M_Legacy.json | 38 ++++++++++++++
boards/esp32_8M.json | 38 ++++++++++++++
.../{esp32_solo1.json => esp32_solo1_4M.json} | 4 +-
boards/esp32c3.json | 2 +-
boards/esp32c3cdc.json | 2 +-
boards/esp32c3cdc_Legacy.json | 37 ++++++++++++++
boards/esp32s2.json | 2 +-
boards/esp32s2_Legacy.json | 35 +++++++++++++
boards/esp32s2cdc.json | 2 +-
.../{esp32s3-qio_qspi.json => esp32s3.json} | 2 +-
.../{esp32s3-qio_opi.json => esp32s3_8M.json} | 20 +++-----
boards/esp32s3cdc-box.json | 40 +++++++++++++++
boards/esp32s3cdc-cam.json | 49 +++++++++++++++++++
boards/esp32s3cdc-eye.json | 49 +++++++++++++++++++
...p32s3cdc-qio_qspi.json => esp32s3cdc.json} | 14 +-----
...dc-qio_opi.json => esp32s3cdc_Legacy.json} | 24 ++-------
boards/esp32s3cdc_LilyTDisp.json | 47 ++++++++++++++++++
.../esp32-camera/driver/include/esp_camera.h | 43 ++++------------
.../esp32-camera/driver/include/sensor.h | 18 +------
platformio_override_sample.ini | 17 ++++---
platformio_tasmota_cenv_sample.ini | 37 ++++----------
platformio_tasmota_env32.ini | 37 ++++++++------
28 files changed, 566 insertions(+), 161 deletions(-)
rename boards/{esp32-fix.json => esp32-cam.json} (67%)
create mode 100644 boards/esp32-m5core2.json
create mode 100644 boards/esp32-odroid.json
create mode 100644 boards/esp32_16M.json
rename boards/{esp32.json => esp32_4M.json} (92%)
create mode 100644 boards/esp32_4M_FS.json
create mode 100644 boards/esp32_4M_Legacy.json
create mode 100644 boards/esp32_8M.json
rename boards/{esp32_solo1.json => esp32_solo1_4M.json} (81%)
create mode 100644 boards/esp32c3cdc_Legacy.json
create mode 100644 boards/esp32s2_Legacy.json
rename boards/{esp32s3-qio_qspi.json => esp32s3.json} (92%)
rename boards/{esp32s3-qio_opi.json => esp32s3_8M.json} (63%)
create mode 100644 boards/esp32s3cdc-box.json
create mode 100644 boards/esp32s3cdc-cam.json
create mode 100644 boards/esp32s3cdc-eye.json
rename boards/{esp32s3cdc-qio_qspi.json => esp32s3cdc.json} (78%)
rename boards/{esp32s3cdc-qio_opi.json => esp32s3cdc_Legacy.json} (64%)
create mode 100644 boards/esp32s3cdc_LilyTDisp.json
diff --git a/boards/esp32-fix.json b/boards/esp32-cam.json
similarity index 67%
rename from boards/esp32-fix.json
rename to boards/esp32-cam.json
index 90132b94e..165b8ef58 100644
--- a/boards/esp32-fix.json
+++ b/boards/esp32-cam.json
@@ -4,7 +4,7 @@
"ldscript": "esp32_out.ld"
},
"core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
+ "extra_flags": "-DCAMERA_MODEL_AI_THINKER -DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 >= 4M Flash, PSRAM with fix, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "AI Thinker ESP32-CAM, 4M Flash 4MB PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
@@ -41,6 +41,6 @@
"require_upload_port": true,
"speed": 460800
},
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
+ "url": "https://wiki.ai-thinker.com/esp32-cam",
+ "vendor": "AI Thinker"
}
diff --git a/boards/esp32-m5core2.json b/boards/esp32-m5core2.json
new file mode 100644
index 000000000..7fc157edb
--- /dev/null
+++ b/boards/esp32-m5core2.json
@@ -0,0 +1,38 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_M5STACK_Core2 -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "qio",
+ "mcu": "esp32",
+ "variant": "m5stack_core2",
+ "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet",
+ "can"
+ ],
+ "debug": {
+ "openocd_target": "esp32.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "M5Stack Core2 16M Flash, 4MB PSRAM, Tasmota 2944k Code/OTA, 10M FS",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "speed": 2000000
+ },
+ "url": "http://www.m5stack.com",
+ "vendor": "M5Stack"
+}
diff --git a/boards/esp32-odroid.json b/boards/esp32-odroid.json
new file mode 100644
index 000000000..f7804af4e
--- /dev/null
+++ b/boards/esp32-odroid.json
@@ -0,0 +1,38 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_ODROID_ESP32 -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32",
+ "variant": "odroid_esp32",
+ "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet",
+ "can"
+ ],
+ "debug": {
+ "openocd_target": "esp32.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "ESP32 ODROID-GO 16M Flash, 4MB PSRAM, Tasmota 2944k Code/OTA, 10M FS",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "speed": 2000000
+ },
+ "url": "https://www.hardkernel.com/main/products/prdt_info.php?g_code=G152875062626",
+ "vendor": "Hardkernel"
+}
diff --git a/boards/esp32_16M.json b/boards/esp32_16M.json
new file mode 100644
index 000000000..c0956a642
--- /dev/null
+++ b/boards/esp32_16M.json
@@ -0,0 +1,38 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
+ "f_cpu": "80000000L",
+ "f_flash": "40000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32",
+ "variant": "esp32",
+ "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet",
+ "can"
+ ],
+ "debug": {
+ "openocd_target": "esp32.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "Espressif Generic ESP32 16M Flash, Tasmota 2944k Code/OTA, 10M FS",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "speed": 460800
+ },
+ "url": "https://en.wikipedia.org/wiki/ESP32",
+ "vendor": "Espressif"
+}
diff --git a/boards/esp32.json b/boards/esp32_4M.json
similarity index 92%
rename from boards/esp32.json
rename to boards/esp32_4M.json
index 0159ea555..d8e39873f 100644
--- a/boards/esp32.json
+++ b/boards/esp32_4M.json
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32_4M_FS.json b/boards/esp32_4M_FS.json
new file mode 100644
index 000000000..c2c7fb2ef
--- /dev/null
+++ b/boards/esp32_4M_FS.json
@@ -0,0 +1,46 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
+ "f_cpu": "80000000L",
+ "f_flash": "40000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32",
+ "variant": "esp32",
+ "partitions": "partitions/esp32_partition_app1856k_fs1344k.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet",
+ "can"
+ ],
+ "debug": {
+ "openocd_target": "esp32.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "upload": {
+ "arduino": {
+ "flash_extra_images": [
+ [
+ "0x10000",
+ "variants/tasmota/tasmota32-safeboot.bin"
+ ]
+ ]
+ },
+ "flash_size": "4MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 4194304,
+ "require_upload_port": true,
+ "speed": 460800
+ },
+ "url": "https://en.wikipedia.org/wiki/ESP32",
+ "vendor": "Espressif"
+ }
diff --git a/boards/esp32_4M_Legacy.json b/boards/esp32_4M_Legacy.json
new file mode 100644
index 000000000..fccad9d15
--- /dev/null
+++ b/boards/esp32_4M_Legacy.json
@@ -0,0 +1,38 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
+ "f_cpu": "80000000L",
+ "f_flash": "40000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32",
+ "variant": "esp32",
+ "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet",
+ "can"
+ ],
+ "debug": {
+ "openocd_target": "esp32.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "upload": {
+ "flash_size": "4MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 4194304,
+ "require_upload_port": true,
+ "speed": 460800
+ },
+ "url": "https://en.wikipedia.org/wiki/ESP32",
+ "vendor": "Espressif"
+ }
diff --git a/boards/esp32_8M.json b/boards/esp32_8M.json
new file mode 100644
index 000000000..e7a351a4d
--- /dev/null
+++ b/boards/esp32_8M.json
@@ -0,0 +1,38 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_8M",
+ "f_cpu": "80000000L",
+ "f_flash": "40000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32",
+ "variant": "esp32",
+ "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet",
+ "can"
+ ],
+ "debug": {
+ "openocd_target": "esp32.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "Espressif Generic ESP32 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
+ "upload": {
+ "flash_size": "8MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 8388608,
+ "require_upload_port": true,
+ "speed": 460800
+ },
+ "url": "https://en.wikipedia.org/wiki/ESP32",
+ "vendor": "Espressif"
+}
diff --git a/boards/esp32_solo1.json b/boards/esp32_solo1_4M.json
similarity index 81%
rename from boards/esp32_solo1.json
rename to boards/esp32_solo1_4M.json
index 3723e27b2..ebc5affe9 100644
--- a/boards/esp32_solo1.json
+++ b/boards/esp32_solo1_4M.json
@@ -4,7 +4,7 @@
"ldscript": "esp32_out.ld"
},
"core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
"f_cpu": "80000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3.json b/boards/esp32c3.json
index 74a740dee..955589dd3 100644
--- a/boards/esp32c3.json
+++ b/boards/esp32c3.json
@@ -23,7 +23,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3cdc.json b/boards/esp32c3cdc.json
index b29b2ca98..648fce5ec 100644
--- a/boards/esp32c3cdc.json
+++ b/boards/esp32c3cdc.json
@@ -23,7 +23,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3cdc_Legacy.json b/boards/esp32c3cdc_Legacy.json
new file mode 100644
index 000000000..8a5d88804
--- /dev/null
+++ b/boards/esp32c3cdc_Legacy.json
@@ -0,0 +1,37 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32c3_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3 -DUSE_USB_CDC_CONSOLE",
+ "f_cpu": "160000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32c3",
+ "variant": "esp32c3",
+ "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth"
+ ],
+ "debug": {
+ "openocd_target": "esp32c3.cfg"
+ },
+ "frameworks": [
+ "arduino",
+ "espidf"
+ ],
+ "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
+ "upload": {
+ "flash_size": "4MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 4194304,
+ "require_upload_port": true,
+ "before_reset": "usb_reset",
+ "speed": 460800
+ },
+ "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
+ "vendor": "Espressif"
+ }
diff --git a/boards/esp32s2.json b/boards/esp32s2.json
index e24ffd17d..1fd5f0768 100644
--- a/boards/esp32s2.json
+++ b/boards/esp32s2.json
@@ -22,7 +22,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s2_Legacy.json b/boards/esp32s2_Legacy.json
new file mode 100644
index 000000000..9bbae7b88
--- /dev/null
+++ b/boards/esp32s2_Legacy.json
@@ -0,0 +1,35 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32s2_out.ld"
+ },
+ "core": "esp32",
+ "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S2",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "dio",
+ "mcu": "esp32s2",
+ "variant": "esp32s2",
+ "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
+ },
+ "connectivity": [
+ "wifi"
+ ],
+ "debug": {
+ "openocd_target": "esp32s2.cfg"
+ },
+ "frameworks": [
+ "espidf",
+ "arduino"
+ ],
+ "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
+ "upload": {
+ "flash_size": "4MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 4194304,
+ "require_upload_port": true,
+ "speed": 460800
+ },
+ "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
+ "vendor": "Espressif"
+}
diff --git a/boards/esp32s2cdc.json b/boards/esp32s2cdc.json
index 03be3a6c0..e71bdbdf6 100644
--- a/boards/esp32s2cdc.json
+++ b/boards/esp32s2cdc.json
@@ -22,7 +22,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s3-qio_qspi.json b/boards/esp32s3.json
similarity index 92%
rename from boards/esp32s3-qio_qspi.json
rename to boards/esp32s3.json
index 64633ab50..df9527c2c 100644
--- a/boards/esp32s3-qio_qspi.json
+++ b/boards/esp32s3.json
@@ -25,7 +25,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s3-qio_opi.json b/boards/esp32s3_8M.json
similarity index 63%
rename from boards/esp32s3-qio_opi.json
rename to boards/esp32s3_8M.json
index 003053268..46dea18ba 100644
--- a/boards/esp32s3-qio_opi.json
+++ b/boards/esp32s3_8M.json
@@ -2,16 +2,16 @@
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
+ "memory_type": "qio_qspi"
},
"core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S3",
+ "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_8M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s3",
"variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
+ "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
},
"connectivity": [
"wifi",
@@ -25,19 +25,11 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
"upload": {
- "arduino": {
- "flash_extra_images": [
- [
- "0x10000",
- "variants/tasmota/tasmota32s3-safeboot.bin"
- ]
- ]
- },
- "flash_size": "4MB",
+ "flash_size": "8MB",
"maximum_ram_size": 327680,
- "maximum_size": 4194304,
+ "maximum_size": 8388608,
"require_upload_port": true,
"speed": 460800
},
diff --git a/boards/esp32s3cdc-box.json b/boards/esp32s3cdc-box.json
new file mode 100644
index 000000000..5388523be
--- /dev/null
+++ b/boards/esp32s3cdc-box.json
@@ -0,0 +1,40 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32s3_out.ld",
+ "memory_type": "qio_opi"
+ },
+ "core": "esp32",
+ "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32S3",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "qio",
+ "mcu": "esp32s3",
+ "variant": "esp32s3",
+ "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet"
+ ],
+ "debug": {
+ "openocd_target": "esp32s3.cfg"
+ },
+ "frameworks": [
+ "espidf",
+ "arduino"
+ ],
+ "name": "Espressif Generic ESP32-S3 16M Flash, Tasmota 2880k Code/OTA, 10M FS",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "before_reset": "usb_reset",
+ "speed": 460800
+ },
+ "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
+ "vendor": "Espressif"
+}
+
diff --git a/boards/esp32s3cdc-cam.json b/boards/esp32s3cdc-cam.json
new file mode 100644
index 000000000..761236e61
--- /dev/null
+++ b/boards/esp32s3cdc-cam.json
@@ -0,0 +1,49 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32s3_out.ld",
+ "memory_type": "qio_opi"
+ },
+ "core": "esp32",
+ "extra_flags": "-DCAMERA_MODEL_TTGO_T_CAM_SIM -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32S3",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
+ "mcu": "esp32s3",
+ "variant": "esp32s3",
+ "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet"
+ ],
+ "debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": [
+ "esp-builtin"
+ ],
+ "openocd_target": "esp32s3.cfg"
+ },
+ "frameworks": [
+ "espidf",
+ "arduino"
+ ],
+ "name": "LilyGo T-SIMCAM ESP32-S3 16M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 10M FS",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "before_reset": "usb_reset",
+ "speed": 460800
+ },
+ "url": "https://github.com/Xinyuan-LilyGO/LilyGo-Camera-Series",
+ "vendor": "LilyGo"
+}
diff --git a/boards/esp32s3cdc-eye.json b/boards/esp32s3cdc-eye.json
new file mode 100644
index 000000000..3254a45df
--- /dev/null
+++ b/boards/esp32s3cdc-eye.json
@@ -0,0 +1,49 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32s3_out.ld",
+ "memory_type": "qio_opi"
+ },
+ "core": "esp32",
+ "extra_flags": "-DCAMERA_MODEL_ESP32S3_EYE -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_8M -DESP32S3",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
+ "mcu": "esp32s3",
+ "variant": "esp32s3",
+ "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet"
+ ],
+ "debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": [
+ "esp-builtin"
+ ],
+ "openocd_target": "esp32s3.cfg"
+ },
+ "frameworks": [
+ "espidf",
+ "arduino"
+ ],
+ "name": "ESP32-S3-EYE 8M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 2M FS",
+ "upload": {
+ "flash_size": "8MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 8388608,
+ "require_upload_port": true,
+ "before_reset": "usb_reset",
+ "speed": 460800
+ },
+ "url": "https://github.com/espressif/esp-who/blob/master/docs/en/get-started/ESP32-S3-EYE_Getting_Started_Guide.md",
+ "vendor": "Espressif"
+}
diff --git a/boards/esp32s3cdc-qio_qspi.json b/boards/esp32s3cdc.json
similarity index 78%
rename from boards/esp32s3cdc-qio_qspi.json
rename to boards/esp32s3cdc.json
index 81ac63bd2..f4cb53cde 100644
--- a/boards/esp32s3cdc-qio_qspi.json
+++ b/boards/esp32s3cdc.json
@@ -9,12 +9,6 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
@@ -25,23 +19,19 @@
"ethernet"
],
"debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": [
- "esp-builtin"
- ],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
- "variants/tasmota/tasmota32s3-safeboot.bin"
+ "variants/tasmota/tasmota32s3cdc-safeboot.bin"
]
]
},
diff --git a/boards/esp32s3cdc-qio_opi.json b/boards/esp32s3cdc_Legacy.json
similarity index 64%
rename from boards/esp32s3cdc-qio_opi.json
rename to boards/esp32s3cdc_Legacy.json
index ad577df29..2fe80ff44 100644
--- a/boards/esp32s3cdc-qio_opi.json
+++ b/boards/esp32s3cdc_Legacy.json
@@ -2,22 +2,16 @@
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
+ "memory_type": "qio_qspi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
"mcu": "esp32s3",
"variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
+ "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
},
"connectivity": [
"wifi",
@@ -25,26 +19,14 @@
"ethernet"
],
"debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": [
- "esp-builtin"
- ],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
"upload": {
- "arduino": {
- "flash_extra_images": [
- [
- "0x10000",
- "variants/tasmota/tasmota32s3-safeboot.bin"
- ]
- ]
- },
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
diff --git a/boards/esp32s3cdc_LilyTDisp.json b/boards/esp32s3cdc_LilyTDisp.json
new file mode 100644
index 000000000..f9a7c0702
--- /dev/null
+++ b/boards/esp32s3cdc_LilyTDisp.json
@@ -0,0 +1,47 @@
+{
+ "build": {
+ "arduino":{
+ "ldscript": "esp32s3_out.ld",
+ "memory_type": "qio_opi"
+ },
+ "core": "esp32",
+ "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_8M -DESP32S3",
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
+ "mcu": "esp32s3",
+ "variant": "esp32s3",
+ "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "ethernet"
+ ],
+ "debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": "esp-builtin",
+ "openocd_target": "esp32s3.cfg"
+ },
+ "frameworks": [
+ "espidf",
+ "arduino"
+ ],
+ "name": "LilyGo T-Display-S3 16M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 10M FS",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "before_reset": "usb_reset",
+ "speed": 460800
+ },
+ "url": "https://github.com/Xinyuan-LilyGO/T-Display-S3",
+ "vendor": "LilyGo"
+ }
diff --git a/lib/libesp32/esp32-camera/driver/include/esp_camera.h b/lib/libesp32/esp32-camera/driver/include/esp_camera.h
index ee84b307b..e9981671f 100644
--- a/lib/libesp32/esp32-camera/driver/include/esp_camera.h
+++ b/lib/libesp32/esp32-camera/driver/include/esp_camera.h
@@ -18,8 +18,8 @@
.pin_pwdn = PIN_PWDN,
.pin_reset = PIN_RESET,
.pin_xclk = PIN_XCLK,
- .pin_sccb_sda = PIN_SIOD,
- .pin_sccb_scl = PIN_SIOC,
+ .pin_sscb_sda = PIN_SIOD,
+ .pin_sscb_scl = PIN_SIOC,
.pin_d7 = PIN_D7,
.pin_d6 = PIN_D6,
.pin_d5 = PIN_D5,
@@ -70,7 +70,6 @@
#include "driver/ledc.h"
#include "sensor.h"
#include "sys/time.h"
-#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
@@ -85,26 +84,13 @@ typedef enum {
} camera_grab_mode_t;
/**
- * @brief Camera frame buffer location
+ * @brief Camera frame buffer location
*/
typedef enum {
CAMERA_FB_IN_PSRAM, /*!< Frame buffer is placed in external PSRAM */
CAMERA_FB_IN_DRAM /*!< Frame buffer is placed in internal DRAM */
} camera_fb_location_t;
-#if CONFIG_CAMERA_CONVERTER_ENABLED
-/**
- * @brief Camera RGB\YUV conversion mode
- */
-typedef enum {
- CONV_DISABLE,
- RGB565_TO_YUV422,
-
- YUV422_TO_RGB565,
- YUV422_TO_YUV420
-} camera_conv_mode_t;
-#endif
-
/**
* @brief Configuration structure for camera initialization
*/
@@ -112,14 +98,8 @@ typedef struct {
int pin_pwdn; /*!< GPIO pin for camera power down line */
int pin_reset; /*!< GPIO pin for camera reset line */
int pin_xclk; /*!< GPIO pin for camera XCLK line */
- union {
- int pin_sccb_sda; /*!< GPIO pin for camera SDA line */
- int pin_sscb_sda __attribute__((deprecated("please use pin_sccb_sda instead"))); /*!< GPIO pin for camera SDA line (legacy name) */
- };
- union {
- int pin_sccb_scl; /*!< GPIO pin for camera SCL line */
- int pin_sscb_scl __attribute__((deprecated("please use pin_sccb_scl instead"))); /*!< GPIO pin for camera SCL line (legacy name) */
- };
+ int pin_sscb_sda; /*!< GPIO pin for camera SDA line */
+ int pin_sscb_scl; /*!< GPIO pin for camera SCL line */
int pin_d7; /*!< GPIO pin for camera D7 line */
int pin_d6; /*!< GPIO pin for camera D6 line */
int pin_d5; /*!< GPIO pin for camera D5 line */
@@ -144,11 +124,6 @@ typedef struct {
size_t fb_count; /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed) */
camera_fb_location_t fb_location; /*!< The location where the frame buffer will be allocated */
camera_grab_mode_t grab_mode; /*!< When buffers should be filled */
-#if CONFIG_CAMERA_CONVERTER_ENABLED
- camera_conv_mode_t conv_mode; /*!< RGB<->YUV Conversion mode */
-#endif
-
- int sccb_i2c_port; /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
} camera_config_t;
/**
@@ -219,15 +194,15 @@ sensor_t * esp_camera_sensor_get();
/**
* @brief Save camera settings to non-volatile-storage (NVS)
- *
- * @param key A unique nvs key name for the camera settings
+ *
+ * @param key A unique nvs key name for the camera settings
*/
esp_err_t esp_camera_save_to_nvs(const char *key);
/**
* @brief Load camera settings from non-volatile-storage (NVS)
- *
- * @param key A unique nvs key name for the camera settings
+ *
+ * @param key A unique nvs key name for the camera settings
*/
esp_err_t esp_camera_load_from_nvs(const char *key);
diff --git a/lib/libesp32/esp32-camera/driver/include/sensor.h b/lib/libesp32/esp32-camera/driver/include/sensor.h
index 6ab12a21a..1f99c1541 100644
--- a/lib/libesp32/esp32-camera/driver/include/sensor.h
+++ b/lib/libesp32/esp32-camera/driver/include/sensor.h
@@ -26,11 +26,6 @@ typedef enum {
GC2145_PID = 0x2145,
GC032A_PID = 0x232a,
GC0308_PID = 0x9b,
- BF3005_PID = 0x30,
- BF20A6_PID = 0x20a6,
- SC101IOT_PID = 0xda4a,
- SC030IOT_PID = 0x9a46,
- SC031GS_PID = 0x0031,
} camera_pid_t;
typedef enum {
@@ -43,11 +38,6 @@ typedef enum {
CAMERA_GC2145,
CAMERA_GC032A,
CAMERA_GC0308,
- CAMERA_BF3005,
- CAMERA_BF20A6,
- CAMERA_SC101IOT,
- CAMERA_SC030IOT,
- CAMERA_SC031GS,
CAMERA_MODEL_MAX,
CAMERA_NONE,
} camera_model_t;
@@ -62,17 +52,11 @@ typedef enum {
GC2145_SCCB_ADDR = 0x3C,// 0x78 >> 1
GC032A_SCCB_ADDR = 0x21,// 0x42 >> 1
GC0308_SCCB_ADDR = 0x21,// 0x42 >> 1
- BF3005_SCCB_ADDR = 0x6E,
- BF20A6_SCCB_ADDR = 0x6E,
- SC101IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
- SC030IOT_SCCB_ADDR = 0x68,// 0xd0 >> 1
- SC031GS_SCCB_ADDR = 0x30,
} camera_sccb_addr_t;
typedef enum {
PIXFORMAT_RGB565, // 2BPP/RGB565
PIXFORMAT_YUV422, // 2BPP/YUV422
- PIXFORMAT_YUV420, // 1.5BPP/YUV420
PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
PIXFORMAT_JPEG, // JPEG/COMPRESSED
PIXFORMAT_RGB888, // 3BPP/RGB888
@@ -212,7 +196,7 @@ typedef struct _sensor {
// Sensor function pointers
int (*init_status) (sensor_t *sensor);
- int (*reset) (sensor_t *sensor); // Reset the configuration of the sensor, and return ESP_OK if reset is successful
+ int (*reset) (sensor_t *sensor);
int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat);
int (*set_framesize) (sensor_t *sensor, framesize_t framesize);
int (*set_contrast) (sensor_t *sensor, int level);
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index 02a8f92e6..ad7937d1c 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -98,18 +98,19 @@ lib_extra_dirs = ${library.lib_extra_dirs}
; *** Uncomment next lines ";" to enable development Tasmota Arduino version ESP32
;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.1/platform-espressif32-2.0.5.1.zip
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1008/framework-arduinoespressif32-IDF_Arduino-d772747b2.zip
-; framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1014/framework-arduinoespressif32-solo1-IDF_Arduino-d772747b2.zip
-; framework-arduino-ITEAD @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1013/framework-arduinoespressif32-ITEAD-IDF_Arduino-d772747b2.zip
+; = framework-arduino-ITEAD @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1014/framework-arduinoespressif32-solo1-IDF_Arduino-d772747b2.zip
+; framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1013/framework-arduinoespressif32-ITEAD-IDF_Arduino-d772747b2.zip
;build_unflags = ${esp32_defaults.build_unflags}
;build_flags = ${esp32_defaults.build_flags}
-;board = esp32
+
+; Build variant ESP32 4M Flash, Tasmota 1856k Code/OTA, 1344k LITTLEFS (default)
+;board = esp32_4M
+; Build variant ESP32 8M Flash, Tasmota 2944k Code/OTA, 2112k LITTLEFS
+;board = esp32_8M
+; Build variant ESP32 16M Flash, Tasmota 2944k Code/OTA, 10M LITTLEFS
+;board = esp32_16M
;board_build.f_cpu = 240000000L
;board_build.f_flash = 40000000L
-;board_build.flash_mode = qio
-;board_build.flash_size = 8MB
-;board_upload.maximum_size = 8388608
-;board_upload.arduino.flash_extra_images =
-;board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv
monitor_speed = 115200
; *** Serial port used for erasing/flashing the ESP32
;upload_port = ${common.upload_port}
diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini
index 397ac0792..bb10ec1b1 100644
--- a/platformio_tasmota_cenv_sample.ini
+++ b/platformio_tasmota_cenv_sample.ini
@@ -14,29 +14,12 @@ build_flags = ${env:tasmota32_base.build_flags}
[env:tasmota32s3-file]
extends = env:tasmota32_base
-board = esp32s3-qio_qspi
-board_build.f_cpu = 240000000L
-board_build.f_flash = 80000000L
+board = esp32s3
build_flags = ${env:tasmota32_base.build_flags} -D FIRMWARE_TASMOTA32
-; !!! Real flash size needed, avoid autoresize since it is formating FS !!!
-board_upload.flash_size = 8MB
-board_upload.maximum_size = 8388608
-; Without autoresize a partition scheme is needed which does fit to flash size
-board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv
-; Dont use safeboot, not used in this partition scheme -> an empty entry needed to overwrite the default setting
-board_upload.arduino.flash_extra_images =
-; Example for custom file upload in Tasmota Filesystem
-custom_files_upload = ${env:tasmota32_base.custom_files_upload}
- tasmota/berry/modules/Partition_wizard.tapp
- https://github.com/tasmota/autoconf/raw/main/esp32s3/DevKitC-1.autoconf
-
-[env:tasmota32s3-qio_opi-all]
-extends = env:tasmota32_base
-board = esp32s3-qio_opi
-board_build.f_cpu = 240000000L
-board_build.f_flash = 80000000L
-build_flags = ${env:tasmota32_base.build_flags} -DUSE_WEBCAM -DUSE_BERRY_ULP -DFIRMWARE_LVGL -DUSE_LVGL_OPENHASP
-
+; example for custom file upload in Tasmota Filesystem
+; custom_files_upload = ${env:tasmota32_base.custom_files_upload}
+; tasmota/berry/modules/Partition_wizard.tapp
+; https://github.com/tasmota/autoconf/raw/main/esp32s3/DevKitC-1.autoconf
[env:tasmota32c3-bluetooth]
extends = env:tasmota32c3
@@ -81,7 +64,7 @@ lib_ignore = ESP8266Audio
TTGO TWatch Library
Micro-RTSP
epdiy
- esp32-camera
+ esp32-camera
[env:tasmota32s3-mi32-homebridge]
extends = env:tasmota32s3
@@ -125,7 +108,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32-ocd]
build_type = debug
extends = env:tasmota32_base
-board = esp32
+board = esp32_4M
debug_tool = esp-prog
upload_protocol = esp-prog
debug_init_break = tbreak setup
@@ -136,7 +119,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32solo1-ocd]
build_type = debug
extends = env:tasmota32solo1
-board = esp32_solo1
+board = esp32_solo1_4M
debug_tool = esp-prog
upload_protocol = esp-prog
debug_init_break = tbreak setup
@@ -160,7 +143,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32s3cdc-ocd]
build_type = debug
extends = env:tasmota32s3
-board = esp32s3cdc-qio_opi
+board = esp32s3cdc
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_init_break = tbreak setup
@@ -171,7 +154,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32c3cdc-ocd]
build_type = debug
extends = env:tasmota32c3
-board = esp32c3cdc-qio_opi
+board = esp32c3cdc
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_init_break = tbreak setup
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index c938bb876..154d5d42f 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -4,7 +4,7 @@ platform = ${core32.platform}
platform_packages = ${core32.platform_packages}
board_build.filesystem = ${common.board_build.filesystem}
custom_unpack_dir = ${common.custom_unpack_dir}
-board = esp32
+board = esp32_4M
monitor_speed = 115200
upload_port = ${common.upload_port}
upload_resetmethod = ${common.upload_resetmethod}
@@ -54,24 +54,29 @@ lib_ignore =
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
+[env:tasmota32_8M]
+extends = env:tasmota32_base
+board = esp32_8M
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
+
+[env:tasmota32_16M]
+extends = env:tasmota32_base
+board = esp32_16M
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
+
[env:tasmota32-webcam]
extends = env:tasmota32_base
-board = esp32-fix
-board_build.f_cpu = 240000000L
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM -DCAMERA_MODEL_AI_THINKER
+board = esp32-cam
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM
lib_extra_dirs = lib/lib_ssl, lib/libesp32
[env:tasmota32-odroidgo]
extends = env:tasmota32-lvgl
-board_build.f_cpu = 240000000L
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 -DARDUINO_ODROID_ESP32
-board = esp32-fix
+board = esp32-odroid
[env:tasmota32-core2]
extends = env:tasmota32-lvgl
-board_build.flash_mode = qio
-board_build.f_cpu = 240000000L
-board_build.f_flash = 80000000L
+board = esp32-m5core2
build_flags = ${env:tasmota32-lvgl.build_flags} -DUSE_I2S_SAY_TIME -DUSE_I2S_WEBRADIO -DUSE_SENDMAIL
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display, lib/lib_audio
@@ -88,7 +93,7 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_display, lib/lib_
[env:tasmota32-lvgl]
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_LVGL
-board_build.f_cpu = 240000000L
+board_build.f_cpu = 160000000L
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display
[env:tasmota32-ir]
@@ -98,11 +103,11 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl
[env:tasmota32solo1]
extends = env:tasmota32_base
-board = esp32_solo1
+board = esp32_solo1_4M
[env:tasmota32solo1-safeboot]
extends = env:tasmota32_base
-board = esp32_solo1
+board = esp32_solo1_4M
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
@@ -112,7 +117,7 @@ lib_ignore =
[env:tasmota32-zbbrdgpro]
extends = env:tasmota32_base
-board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
+board = esp32_4M_FS
build_flags = ${env:tasmota32_base.build_flags}
-DFIRMWARE_ZBBRDGPRO
-DFRAMEWORK_ARDUINO_ITEAD
@@ -196,7 +201,7 @@ board = esp32s2cdc
[env:tasmota32s3-safeboot]
extends = env:tasmota32_base
-board = esp32s3-qio_qspi
+board = esp32s3
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
@@ -215,7 +220,7 @@ lib_ignore =
[env:tasmota32s3cdc-safeboot]
extends = env:tasmota32s3-safeboot
-board = esp32s3cdc-qio_qspi
+board = esp32s3cdc
[env:tasmota32s3cdc]
extends = env:tasmota32s3
From f998a457db62f8c8f3b0ec9ae42ff6a62b448a7b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 17 Oct 2022 15:41:46 +0200
Subject: [PATCH 016/319] Disable SspmPowerOnState for v1.0.0 main
---
.../xdrv_86_esp32_sonoff_spm.ino | 110 ++++++++++--------
1 file changed, 62 insertions(+), 48 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino
index 4b568da3a..aa0d8ace2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino
@@ -128,7 +128,7 @@
// From ESP to ARM
#define SSPM_FUNC_FIND 0 // 0x00
-#define SSPM_FUNC_SET_OPS 3 // 0x03 - Overload Protection
+#define SSPM_FUNC_SET_OPS 3 // 0x03 - Overload Protection (OPS)
#define SSPM_FUNC_GET_OPS 4 // 0x04
#define SSPM_FUNC_SET_RELAY 8 // 0x08
#define SSPM_FUNC_GET_MODULE_STATE 9 // 0x09 - State of four channels
@@ -138,7 +138,7 @@
#define SSPM_FUNC_IAMHERE 13 // 0x0D
#define SSPM_FUNC_INIT_SCAN 16 // 0x10
#define SSPM_FUNC_UPLOAD_HEADER 20 // 0x14 - SPI Upload header
-#define SSPM_FUNC_UNITS 21 // 0x15
+#define SSPM_FUNC_GET_MAIN_VERSION 21 // 0x15 - Read main ARM firmware version
#define SSPM_FUNC_GET_ENERGY_TOTAL 22 // 0x16
#define SSPM_FUNC_GET_ENERGY 24 // 0x18
#define SSPM_FUNC_GET_LOG 26 // 0x1A
@@ -148,14 +148,14 @@
#define SSPM_FUNC_UPLOAD_DONE 33 // 0x21 - SPI Finish upload
#define SSPM_FUNC_34 34 // 0x22 - v1.2.0
#define SSPM_FUNC_GET_OPS_DEFAULTS 35 // 0x23 - v1.2.0 - Get Overload protection defaults
-#define SSPM_FUNC_SET_POS 36 // 0x24 - v1.2.0 - Save power on relay state
-#define SSPM_FUNC_GET_POS 37 // 0x25 - v1.2.0 - Read power on relay state
+#define SSPM_FUNC_SET_POS 36 // 0x24 - v1.2.0 - Save power on relay state (POS)
+#define SSPM_FUNC_GET_POS 37 // 0x25 - v1.2.0 - Read power on relay state (POS)
// From ARM to ESP
#define SSPM_FUNC_ENERGY_RESULT 6 // 0x06
#define SSPM_FUNC_KEY_PRESS 7 // 0x07
#define SSPM_FUNC_SCAN_START 15 // 0x0F
-#define SSPM_FUNC_SCAN_RESULT 19 // 0x13
+#define SSPM_FUNC_SCAN_RESULT 19 // 0x13 - Provide 4relay ARM firmware version, module type and OPS limits
#define SSPM_FUNC_SCAN_DONE 25 // 0x19
#define SSPM_FUNC_UPLOAD_DONE_ACK 30 // 0x1E - Restart ARM
@@ -177,26 +177,27 @@
#define SSPM_VERSION_1_0_0 0x00010000
#define SSPM_VERSION_1_2_0 0x00010200
+#define SSPM_VERSION_1_4_0 0x00010400
/*********************************************************************************************/
-#define SSPM_TOTAL_MODULES 32 // Max number of SPM-4RELAY units for a total of 128 relays
+#define SSPM_TOTAL_MODULES 32 // Max number of SPM-4RELAY units for a total of 128 relays
-enum SspmMachineStates { SPM_NONE, // Do nothing
- SPM_WAIT, // Wait 100ms
- SPM_RESET, // Toggle ARM reset pin
- SPM_POLL_ARM, // Wait for first acknowledge from ARM after reset
+enum SspmMachineStates { SPM_NONE, // Do nothing
+ SPM_WAIT, // Wait 100ms
+ SPM_RESET, // Toggle ARM reset pin
+ SPM_POLL_ARM, // Wait for first acknowledge from ARM after reset
// Removed to accomodate v1.2.0 too
-// SPM_POLL_ARM_SPI, // Wait for first acknowledge from ARM SPI after reset
-// SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset
-// SPM_POLL_ARM_3, // Wait for second acknowledge from ARM after reset
- SPM_SEND_FUNC_UNITS, // Get number of units
- SPM_START_SCAN, // Start module scan sequence
- SPM_WAIT_FOR_SCAN, // Wait for scan sequence to complete
- SPM_SCAN_COMPLETE, // Scan complete
- SPM_STALL_MIDNIGHT, // Stall energy totals around midnight
- SPM_GET_ENERGY_TOTALS, // Init available Energy totals registers
- SPM_UPDATE_CHANNELS // Update Energy for powered on channels
+// SPM_POLL_ARM_SPI, // Wait for first acknowledge from ARM SPI after reset
+// SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset
+// SPM_POLL_ARM_3, // Wait for second acknowledge from ARM after reset
+ SPM_SEND_FUNC_GET_MAIN_VERSION, // Get main ARM firmware version
+ SPM_START_SCAN, // Start module scan sequence
+ SPM_WAIT_FOR_SCAN, // Wait for scan sequence to complete
+ SPM_SCAN_COMPLETE, // Scan complete
+ SPM_STALL_MIDNIGHT, // Stall energy totals around midnight
+ SPM_GET_ENERGY_TOTALS, // Init available Energy totals registers
+ SPM_UPDATE_CHANNELS // Update Energy for powered on channels
};
enum SspmDisplayModes { SPM_DISPLAY_ROTATE, SPM_DISPLAY_ROTATE_POWERED_ON, SPM_DISPLAY_TABS, SPM_DISPLAY_MAX_OPTION };
@@ -1233,7 +1234,7 @@ void SSPMHandleReceivedData(void) {
AA 55 01 ff ff ff ff ff ff ff ff ff ff ff ff 80 10 00 01 00 02 e5 03
*/
break;
- case SSPM_FUNC_UNITS:
+ case SSPM_FUNC_GET_MAIN_VERSION:
/* 0x15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 15 00 04 00 01 00 00 01 81 b1
@@ -1479,8 +1480,10 @@ void SSPMHandleReceivedData(void) {
P4 - Relay4 power on state (0 = On, 1 = Off, 2 = Laststate)
*/
Sspm->module_selected--;
- for (uint32_t i = 0; i < 4; i++) {
- Sspm->poweron_state[Sspm->module_selected][i] = (!status && (expected_bytes >= 0x05)) ? SspmBuffer[20 +i] : 1;
+ if (!status && (expected_bytes >= 0x05)) {
+ for (uint32_t i = 0; i < 4; i++) {
+ Sspm->poweron_state[Sspm->module_selected][i] = SspmBuffer[20 +i];
+ }
}
if (Sspm->module_selected > 0) {
SSPMSendGetModuleState(Sspm->module_selected -1);
@@ -1617,10 +1620,12 @@ void SSPMHandleReceivedData(void) {
case SSPM_FUNC_SCAN_RESULT:
/* 0x13
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
- AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 6b 7e 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 8f cd
- AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8b 34 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 a0 6f
Marker | |Ac|Cm|Size |Module id |Ch| |Ty|FwVersio|Max I|Min I|Max U |Min U |Max P |Min P |Ix|Chksm|
+ AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 6b 7e 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 8f cd - v1.0.0
+ AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8b 34 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 a0 6f - v1.0.0
|130| 1.0.0|20.0A|0.10A| 240.00V| 0.10V|4400.00W| 0.10W|
+ AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8B 34 32 37 39 37 34 13 4B 35 36 37 04 00 00 00 82 01 02 00 14 00 00 0A 01 08 00 00 5A 00 12 C0 00 00 00 0A 02 6B 93 - v1.2.0
+ |130| 1.2.0|20.0A|0.10A| 264.00V| 90V|4800.00W| 0.10W|
Ty = Type of sub-device. 130: Four-channel sub-device
*/
if (0x24 == expected_bytes) {
@@ -1931,6 +1936,11 @@ void SSPMInit(void) {
#endif
#endif
+ for (uint32_t module = 0; module < Sspm->module_max; module++) {
+ for (uint32_t relay = 0; relay < 4; relay++) {
+ Sspm->poweron_state[module][relay] = 1; // Set default power on state to Off ( = Sonoff 1)
+ }
+ }
Sspm->relay_version = 0xFFFFFFFF; // Find lowest supported relay version
Sspm->overload_relay = 255; // Disable display overload settings
Sspm->history_relay = 255; // Disable display energy history
@@ -1964,7 +1974,7 @@ void SSPMEvery100ms(void) {
}
// Fix race condition if the ARM doesn't respond
- if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_UNITS)) {
+ if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_GET_MAIN_VERSION)) {
Sspm->counter++;
if (Sspm->counter > 30) {
Sspm->mstate = SPM_NONE;
@@ -2003,9 +2013,9 @@ void SSPMEvery100ms(void) {
// Wait for second acknowledge from ARM after reset
break;
*/
- case SPM_SEND_FUNC_UNITS:
- // Get number of units
- SSPMSendCmnd(SSPM_FUNC_UNITS);
+ case SPM_SEND_FUNC_GET_MAIN_VERSION:
+ // Get main version number
+ SSPMSendCmnd(SSPM_FUNC_GET_MAIN_VERSION);
break;
case SPM_START_SCAN:
// Start scan module sequence
@@ -2397,7 +2407,8 @@ void CmndSpmEnergyYesterday(void) {
void CmndSSPMOverload(void) {
// Get / Set overload
// SspmOverload 0 - Reset overload detection parameters
- // SspmOverload {"Delay":0,"Set":00000,"MinPower":0.10,"MaxPower":4400.00,"MinVoltage":0.10,"MaxVoltage":240.00,"MaxCurrent":20.00}
+ // SspmOverload {"Delay":0,"Set":00000,"MinPower":0.10,"MaxPower":4400.00,"MinVoltage":0.10,"MaxVoltage":240.00,"MaxCurrent":20.00} - v1.0.0
+ // SspmOverload {"Delay":0,"Set":00000,"MinPower":0.10,"MaxPower":4800.00,"MinVoltage":90,"MaxVoltage":264.00,"MaxCurrent":20.00} - v1.2.0
// SspmOverload ,,,,
// SspmOverload 10,0.10,4400.00,0.10,240.00,20.00
// SspmOverload 10 0.10 4400.00 0.10 240.00 20.00
@@ -2590,26 +2601,29 @@ void CmndSSPMSend(void) {
void CmndSSPMPowerOnState(void) {
// SspmPowerOnState2 0|1|2 - Set relay2 power on state (0 = Off, 1 = On, 2 = Saved)
- uint32_t max_index = Sspm->module_max *4;
- if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= max_index)) {
- uint32_t module = (XdrvMailbox.index -1) >>2;
- uint32_t relay = (XdrvMailbox.index -1) &3;
- if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) {
- if (XdrvMailbox.payload < 2) { XdrvMailbox.payload = !XdrvMailbox.payload; } // Swap Tasmota power off (0) with Sonoff (1)
- Sspm->poweron_state[module][relay] = XdrvMailbox.payload;
- SSPMSendSetPowerOnState(module);
- }
- Response_P(PSTR("{\"%s\":["), XdrvMailbox.command);
- bool more = false;
- for (uint32_t module = 0; module < Sspm->module_max; module++) {
- for (uint32_t relay = 0; relay < 4; relay++) {
- uint32_t poweron_state = Sspm->poweron_state[module][relay];
- if (poweron_state < 2) { poweron_state = !poweron_state; } // Swap Sonoff power off (1) with Tasmota (0)
- ResponseAppend_P(PSTR("%s%d"), (more)?",":"", poweron_state);
- more = true;
+ // Needs both main and 4relay at v1.2.0
+ if (Sspm->main_version > SSPM_VERSION_1_0_0) {
+ uint32_t max_index = Sspm->module_max *4;
+ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= max_index)) {
+ uint32_t module = (XdrvMailbox.index -1) >>2;
+ uint32_t relay = (XdrvMailbox.index -1) &3;
+ if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) {
+ if (XdrvMailbox.payload < 2) { XdrvMailbox.payload = !XdrvMailbox.payload; } // Swap Tasmota power off (0) with Sonoff (1)
+ Sspm->poweron_state[module][relay] = XdrvMailbox.payload;
+ SSPMSendSetPowerOnState(module);
}
+ Response_P(PSTR("{\"%s\":["), XdrvMailbox.command);
+ bool more = false;
+ for (uint32_t module = 0; module < Sspm->module_max; module++) {
+ for (uint32_t relay = 0; relay < 4; relay++) {
+ uint32_t poweron_state = Sspm->poweron_state[module][relay];
+ if (poweron_state < 2) { poweron_state = !poweron_state; } // Swap Sonoff power off (1) with Tasmota (0)
+ ResponseAppend_P(PSTR("%s%d"), (more)?",":"", poweron_state);
+ more = true;
+ }
+ }
+ ResponseAppend_P(PSTR("]}"));
}
- ResponseAppend_P(PSTR("]}"));
}
}
From 18fdc4a1766c5d5221dd35879479c7b8aa96e626 Mon Sep 17 00:00:00 2001
From: Leon Poon
Date: Sun, 16 Oct 2022 23:56:58 +0800
Subject: [PATCH 017/319] support nanos in rtc for sync from ntp
so that all tm1637 6-digit clocks tick simultaneously at real second boundary.
---
tasmota/tasmota.ino | 1 +
tasmota/tasmota_support/support_rtc.ino | 22 ++++++++++++++++---
tasmota/tasmota_support/support_wifi.ino | 14 +++++++++---
.../tasmota_xdsp_display/xdsp_15_tm1637.ino | 17 +++++++++-----
4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 4a820a229..d33d122f6 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -158,6 +158,7 @@ RTC_NOINIT_ATTR TRtcSettings RtcDataSettings;
#endif // ESP32
struct TIME_T {
+ uint32_t nanos;
uint8_t second;
uint8_t minute;
uint8_t hour;
diff --git a/tasmota/tasmota_support/support_rtc.ino b/tasmota/tasmota_support/support_rtc.ino
index 85efa6a84..1c10811fc 100644
--- a/tasmota/tasmota_support/support_rtc.ino
+++ b/tasmota/tasmota_support/support_rtc.ino
@@ -43,10 +43,12 @@ struct RTC {
uint32_t standard_time = 0;
uint32_t midnight = 0;
uint32_t restart_time = 0;
+ uint32_t nanos = 0;
uint32_t millis = 0;
// uint32_t last_sync = 0;
int32_t time_timezone = 0;
bool time_synced = false;
+ bool last_synced = false;
bool midnight_now = false;
bool user_time_entry = false; // Override NTP by user setting
} Rtc;
@@ -235,11 +237,14 @@ uint32_t RtcMillis(void) {
return (millis() - Rtc.millis) % 1000;
}
-void BreakTime(uint32_t time_input, TIME_T &tm) {
+void BreakNanoTime(uint32_t time_input, uint32_t time_nanos, TIME_T &tm) {
// break the given time_input into time components
// this is a more compact version of the C library localtime function
// note that year is offset from 1970 !!!
+ time_input += time_nanos / 1000000000U;
+ tm.nanos = time_nanos % 1000000000U;
+
uint8_t year;
uint8_t month;
uint8_t month_length;
@@ -290,6 +295,10 @@ void BreakTime(uint32_t time_input, TIME_T &tm) {
tm.valid = (time_input > START_VALID_TIME); // 2016-01-01
}
+void BreakTime(uint32_t time_input, TIME_T &tm) {
+ BreakNanoTime(time_input, 0, tm);
+}
+
uint32_t MakeTime(TIME_T &tm) {
// assemble time elements into time_t
// note year argument is offset from 1970
@@ -403,6 +412,7 @@ void RtcSecond(void) {
mutex = true;
Rtc.time_synced = false;
+ Rtc.last_synced = true;
last_sync = Rtc.utc_time;
if (Rtc.restart_time == 0) {
@@ -420,7 +430,13 @@ void RtcSecond(void) {
TasmotaGlobal.rules_flag.time_set = 1;
}
} else {
- Rtc.utc_time++; // Increment every second
+ if (Rtc.last_synced) {
+ Rtc.last_synced = false;
+ uint32_t nanos = Rtc.nanos + (millis() - Rtc.millis) * 1000000U;
+ Rtc.utc_time += nanos / 1000000000U;
+ Rtc.nanos = nanos % 1000000000U;
+ } else
+ Rtc.utc_time++; // Increment every second
}
Rtc.millis = millis();
@@ -442,7 +458,7 @@ void RtcSecond(void) {
}
}
- BreakTime(Rtc.local_time, RtcTime);
+ BreakNanoTime(Rtc.local_time, Rtc.nanos, RtcTime);
if (RtcTime.valid) {
if (!Rtc.midnight) {
Rtc.midnight = Rtc.local_time - (RtcTime.hour * 3600) - (RtcTime.minute * 60) - RtcTime.second;
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index 0700fcc2d..f202ff602 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -878,13 +878,15 @@ void WifiPollNtp() {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NTP: Sync time..."));
ntp_run_time = millis();
- uint32_t ntp_time = WifiGetNtp();
+ uint64_t ntp_nanos = WifiGetNtp();
+ uint32_t ntp_time = ntp_nanos / 1000000000;
ntp_run_time = (millis() - ntp_run_time) / 1000;
// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Runtime %d"), ntp_run_time);
if (ntp_run_time < 5) { ntp_run_time = 0; } // DNS timeout is around 10s
if (ntp_time > START_VALID_TIME) {
Rtc.utc_time = ntp_time;
+ Rtc.nanos = ntp_nanos % 1000000000;
ntp_sync_minute = 60; // Sync so block further requests
RtcSync("NTP");
} else {
@@ -893,7 +895,7 @@ void WifiPollNtp() {
}
}
-uint32_t WifiGetNtp(void) {
+uint64_t WifiGetNtp(void) {
static uint8_t ntp_server_id = 0;
// AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Start NTP Sync %d ..."), ntp_server_id);
@@ -983,7 +985,13 @@ uint32_t WifiGetNtp(void) {
ntp_server_id++; // Next server next time
return 0;
}
- return secs_since_1900 - 2208988800UL;
+
+ uint32_t highWord = word(packet_buffer[44], packet_buffer[45]);
+ uint32_t lowWord = word(packet_buffer[46], packet_buffer[47]);
+
+ uint32_t currentNano = (((uint64_t)(highWord << 16 | lowWord)) * 1000000000) >> 32;
+
+ return (((uint64_t) secs_since_1900) - 2208988800UL) * 1000000000 + currentNano;
}
delay(10);
}
diff --git a/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino b/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino
index a7daf61bf..144921527 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino
@@ -987,9 +987,12 @@ bool CmndTM1637Clock(void)
\*********************************************************************************************/
void TM1637ShowTime()
{
- uint8_t hr = RtcTime.hour;
- uint8_t mn = RtcTime.minute;
- uint8_t sc = RtcTime.second;
+ struct TIME_T t = RtcTime;
+ BreakNanoTime(Rtc.local_time, Rtc.nanos + (millis() - Rtc.millis) * 1000000, t);
+ uint8_t hr = t.hour;
+ uint8_t mn = t.minute;
+ uint8_t sc = t.second;
+ uint16_t ms = t.nanos / 1000000;
if (!TM1637Data.clock_24)
{
@@ -1009,12 +1012,14 @@ void TM1637ShowTime()
if (TM1637 == TM1637Data.display_type)
{
+ uint8_t colon = ms > 500? 0: 128;
uint8_t rawBytes[1];
- for (uint32_t i = 0; i < 4; i++)
+ uint8_t width = Settings->display_width >= 6? 6: 4;
+ for (uint32_t i = 0; i < width; i++)
{
rawBytes[0] = tm1637display->encode(tm[i]);
- if ((millis() % 1000) > 500 && (i == 1))
- rawBytes[0] = rawBytes[0] | 128;
+ if (i == 1 || (i == 3 && width > 4))
+ rawBytes[0] = rawBytes[0] | colon;
tm1637display->printRaw(rawBytes, 1, TM1637Data.digit_order[i]);
}
}
From 724b0342c706377b58e30b6ed22afe91a46ab183 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 17 Oct 2022 16:04:11 +0200
Subject: [PATCH 018/319] Reduce Boards manifests
## Description:
by using the 4MB default safeboot partition scheme layout. Tasmota will increase the FS partition with
the new Autoresize feature introduced with PR #16838 #16842
So it is possible to reduce the boards mainifest since it is no more needed to have different ones for boards with different flash sizes. Added generic S3 Flash / PSRAM boards variants. Removed all S3 boards specific variants. Configuration is done via Autoconfig. For a few special use cases maybe an [env] needs to be defined. Examples for are in file `platformio_tasmota_cenv_sample.ini`
@s-hadinger @arendst @staars please test. Since it is a major change how the firmwares are build, there is maybe something i overlooked. So i do not check all below.
## Checklist:
- [x] The pull request is done against the latest development branch
- [x] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
- [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9
- [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.5
- [x] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_
---
boards/{esp32-cam.json => esp32-fix.json} | 8 +--
boards/esp32-m5core2.json | 38 --------------
boards/esp32-odroid.json | 38 --------------
boards/{esp32_4M.json => esp32.json} | 2 +-
boards/esp32_16M.json | 38 --------------
boards/esp32_4M_FS.json | 46 -----------------
boards/esp32_4M_Legacy.json | 38 --------------
boards/esp32_8M.json | 38 --------------
.../{esp32_solo1_4M.json => esp32_solo1.json} | 4 +-
boards/esp32c3.json | 2 +-
boards/esp32c3cdc.json | 2 +-
boards/esp32c3cdc_Legacy.json | 37 --------------
boards/esp32s2.json | 2 +-
boards/esp32s2_Legacy.json | 35 -------------
boards/esp32s2cdc.json | 2 +-
.../{esp32s3_8M.json => esp32s3-qio_opi.json} | 20 +++++---
.../{esp32s3.json => esp32s3-qio_qspi.json} | 2 +-
boards/esp32s3cdc-box.json | 40 ---------------
boards/esp32s3cdc-cam.json | 49 -------------------
boards/esp32s3cdc-eye.json | 49 -------------------
...dc_Legacy.json => esp32s3cdc-qio_opi.json} | 24 +++++++--
...p32s3cdc.json => esp32s3cdc-qio_qspi.json} | 14 +++++-
boards/esp32s3cdc_LilyTDisp.json | 47 ------------------
platformio_override_sample.ini | 17 +++----
platformio_tasmota_cenv_sample.ini | 37 ++++++++++----
platformio_tasmota_env32.ini | 37 ++++++--------
26 files changed, 110 insertions(+), 556 deletions(-)
rename boards/{esp32-cam.json => esp32-fix.json} (67%)
delete mode 100644 boards/esp32-m5core2.json
delete mode 100644 boards/esp32-odroid.json
rename boards/{esp32_4M.json => esp32.json} (92%)
delete mode 100644 boards/esp32_16M.json
delete mode 100644 boards/esp32_4M_FS.json
delete mode 100644 boards/esp32_4M_Legacy.json
delete mode 100644 boards/esp32_8M.json
rename boards/{esp32_solo1_4M.json => esp32_solo1.json} (81%)
delete mode 100644 boards/esp32c3cdc_Legacy.json
delete mode 100644 boards/esp32s2_Legacy.json
rename boards/{esp32s3_8M.json => esp32s3-qio_opi.json} (63%)
rename boards/{esp32s3.json => esp32s3-qio_qspi.json} (92%)
delete mode 100644 boards/esp32s3cdc-box.json
delete mode 100644 boards/esp32s3cdc-cam.json
delete mode 100644 boards/esp32s3cdc-eye.json
rename boards/{esp32s3cdc_Legacy.json => esp32s3cdc-qio_opi.json} (64%)
rename boards/{esp32s3cdc.json => esp32s3cdc-qio_qspi.json} (78%)
delete mode 100644 boards/esp32s3cdc_LilyTDisp.json
diff --git a/boards/esp32-cam.json b/boards/esp32-fix.json
similarity index 67%
rename from boards/esp32-cam.json
rename to boards/esp32-fix.json
index 165b8ef58..90132b94e 100644
--- a/boards/esp32-cam.json
+++ b/boards/esp32-fix.json
@@ -4,7 +4,7 @@
"ldscript": "esp32_out.ld"
},
"core": "esp32",
- "extra_flags": "-DCAMERA_MODEL_AI_THINKER -DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "AI Thinker ESP32-CAM, 4M Flash 4MB PSRAM, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 >= 4M Flash, PSRAM with fix, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
@@ -41,6 +41,6 @@
"require_upload_port": true,
"speed": 460800
},
- "url": "https://wiki.ai-thinker.com/esp32-cam",
- "vendor": "AI Thinker"
+ "url": "https://en.wikipedia.org/wiki/ESP32",
+ "vendor": "Espressif"
}
diff --git a/boards/esp32-m5core2.json b/boards/esp32-m5core2.json
deleted file mode 100644
index 7fc157edb..000000000
--- a/boards/esp32-m5core2.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_M5STACK_Core2 -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "mcu": "esp32",
- "variant": "m5stack_core2",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "M5Stack Core2 16M Flash, 4MB PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 2000000
- },
- "url": "http://www.m5stack.com",
- "vendor": "M5Stack"
-}
diff --git a/boards/esp32-odroid.json b/boards/esp32-odroid.json
deleted file mode 100644
index f7804af4e..000000000
--- a/boards/esp32-odroid.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ODROID_ESP32 -DBOARD_HAS_PSRAM -DHAS_PSRAM_FIX -mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-strategy=memw -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "odroid_esp32",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "ESP32 ODROID-GO 16M Flash, 4MB PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 2000000
- },
- "url": "https://www.hardkernel.com/main/products/prdt_info.php?g_code=G152875062626",
- "vendor": "Hardkernel"
-}
diff --git a/boards/esp32_4M.json b/boards/esp32.json
similarity index 92%
rename from boards/esp32_4M.json
rename to boards/esp32.json
index d8e39873f..0159ea555 100644
--- a/boards/esp32_4M.json
+++ b/boards/esp32.json
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32_16M.json b/boards/esp32_16M.json
deleted file mode 100644
index c0956a642..000000000
--- a/boards/esp32_16M.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_16M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 16M Flash, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32_4M_FS.json b/boards/esp32_4M_FS.json
deleted file mode 100644
index c2c7fb2ef..000000000
--- a/boards/esp32_4M_FS.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app1856k_fs1344k.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
- "upload": {
- "arduino": {
- "flash_extra_images": [
- [
- "0x10000",
- "variants/tasmota/tasmota32-safeboot.bin"
- ]
- ]
- },
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
- }
diff --git a/boards/esp32_4M_Legacy.json b/boards/esp32_4M_Legacy.json
deleted file mode 100644
index fccad9d15..000000000
--- a/boards/esp32_4M_Legacy.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
- "upload": {
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
- }
diff --git a/boards/esp32_8M.json b/boards/esp32_8M.json
deleted file mode 100644
index e7a351a4d..000000000
--- a/boards/esp32_8M.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_8M",
- "f_cpu": "80000000L",
- "f_flash": "40000000L",
- "flash_mode": "dio",
- "mcu": "esp32",
- "variant": "esp32",
- "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "debug": {
- "openocd_target": "esp32.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
- "upload": {
- "flash_size": "8MB",
- "maximum_ram_size": 327680,
- "maximum_size": 8388608,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://en.wikipedia.org/wiki/ESP32",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32_solo1_4M.json b/boards/esp32_solo1.json
similarity index 81%
rename from boards/esp32_solo1_4M.json
rename to boards/esp32_solo1.json
index ebc5affe9..3723e27b2 100644
--- a/boards/esp32_solo1_4M.json
+++ b/boards/esp32_solo1.json
@@ -4,7 +4,7 @@
"ldscript": "esp32_out.ld"
},
"core": "esp32",
- "extra_flags": "-DARDUINO_ESP32_DEV -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
+ "extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
"f_cpu": "80000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
@@ -25,7 +25,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3.json b/boards/esp32c3.json
index 955589dd3..74a740dee 100644
--- a/boards/esp32c3.json
+++ b/boards/esp32c3.json
@@ -23,7 +23,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3cdc.json b/boards/esp32c3cdc.json
index 648fce5ec..b29b2ca98 100644
--- a/boards/esp32c3cdc.json
+++ b/boards/esp32c3cdc.json
@@ -23,7 +23,7 @@
"arduino",
"espidf"
],
- "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-C3 >= 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32c3cdc_Legacy.json b/boards/esp32c3cdc_Legacy.json
deleted file mode 100644
index 8a5d88804..000000000
--- a/boards/esp32c3cdc_Legacy.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32c3_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3 -DUSE_USB_CDC_CONSOLE",
- "f_cpu": "160000000L",
- "f_flash": "80000000L",
- "flash_mode": "dio",
- "mcu": "esp32c3",
- "variant": "esp32c3",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth"
- ],
- "debug": {
- "openocd_target": "esp32c3.cfg"
- },
- "frameworks": [
- "arduino",
- "espidf"
- ],
- "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
- "upload": {
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html",
- "vendor": "Espressif"
- }
diff --git a/boards/esp32s2.json b/boards/esp32s2.json
index 1fd5f0768..e24ffd17d 100644
--- a/boards/esp32s2.json
+++ b/boards/esp32s2.json
@@ -22,7 +22,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s2_Legacy.json b/boards/esp32s2_Legacy.json
deleted file mode 100644
index 9bbae7b88..000000000
--- a/boards/esp32s2_Legacy.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s2_out.ld"
- },
- "core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S2",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "dio",
- "mcu": "esp32s2",
- "variant": "esp32s2",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
- },
- "connectivity": [
- "wifi"
- ],
- "debug": {
- "openocd_target": "esp32s2.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
- "upload": {
- "flash_size": "4MB",
- "maximum_ram_size": 327680,
- "maximum_size": 4194304,
- "require_upload_port": true,
- "speed": 460800
- },
- "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32s2cdc.json b/boards/esp32s2cdc.json
index e71bdbdf6..03be3a6c0 100644
--- a/boards/esp32s2cdc.json
+++ b/boards/esp32s2cdc.json
@@ -22,7 +22,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S2 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s3_8M.json b/boards/esp32s3-qio_opi.json
similarity index 63%
rename from boards/esp32s3_8M.json
rename to boards/esp32s3-qio_opi.json
index 46dea18ba..003053268 100644
--- a/boards/esp32s3_8M.json
+++ b/boards/esp32s3-qio_opi.json
@@ -2,16 +2,16 @@
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
- "memory_type": "qio_qspi"
+ "memory_type": "qio_opi"
},
"core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_8M -DESP32S3",
+ "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s3",
"variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
+ "partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@@ -25,11 +25,19 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
- "flash_size": "8MB",
+ "arduino": {
+ "flash_extra_images": [
+ [
+ "0x10000",
+ "variants/tasmota/tasmota32s3-safeboot.bin"
+ ]
+ ]
+ },
+ "flash_size": "4MB",
"maximum_ram_size": 327680,
- "maximum_size": 8388608,
+ "maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
diff --git a/boards/esp32s3.json b/boards/esp32s3-qio_qspi.json
similarity index 92%
rename from boards/esp32s3.json
rename to boards/esp32s3-qio_qspi.json
index df9527c2c..64633ab50 100644
--- a/boards/esp32s3.json
+++ b/boards/esp32s3-qio_qspi.json
@@ -25,7 +25,7 @@
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
diff --git a/boards/esp32s3cdc-box.json b/boards/esp32s3cdc-box.json
deleted file mode 100644
index 5388523be..000000000
--- a/boards/esp32s3cdc-box.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "Espressif Generic ESP32-S3 16M Flash, Tasmota 2880k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
- "vendor": "Espressif"
-}
-
diff --git a/boards/esp32s3cdc-cam.json b/boards/esp32s3cdc-cam.json
deleted file mode 100644
index 761236e61..000000000
--- a/boards/esp32s3cdc-cam.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DCAMERA_MODEL_TTGO_T_CAM_SIM -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_16M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": [
- "esp-builtin"
- ],
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "LilyGo T-SIMCAM ESP32-S3 16M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://github.com/Xinyuan-LilyGO/LilyGo-Camera-Series",
- "vendor": "LilyGo"
-}
diff --git a/boards/esp32s3cdc-eye.json b/boards/esp32s3cdc-eye.json
deleted file mode 100644
index 3254a45df..000000000
--- a/boards/esp32s3cdc-eye.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DCAMERA_MODEL_ESP32S3_EYE -DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_8M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs2M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": [
- "esp-builtin"
- ],
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "ESP32-S3-EYE 8M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 2M FS",
- "upload": {
- "flash_size": "8MB",
- "maximum_ram_size": 327680,
- "maximum_size": 8388608,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://github.com/espressif/esp-who/blob/master/docs/en/get-started/ESP32-S3-EYE_Getting_Started_Guide.md",
- "vendor": "Espressif"
-}
diff --git a/boards/esp32s3cdc_Legacy.json b/boards/esp32s3cdc-qio_opi.json
similarity index 64%
rename from boards/esp32s3cdc_Legacy.json
rename to boards/esp32s3cdc-qio_opi.json
index 2fe80ff44..ad577df29 100644
--- a/boards/esp32s3cdc_Legacy.json
+++ b/boards/esp32s3cdc-qio_opi.json
@@ -2,16 +2,22 @@
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
- "memory_type": "qio_qspi"
+ "memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_4M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
"mcu": "esp32s3",
"variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app1856k_fs320k.csv"
+ "partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
},
"connectivity": [
"wifi",
@@ -19,14 +25,26 @@
"ethernet"
],
"debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": [
+ "esp-builtin"
+ ],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 1856k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash OPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
+ "arduino": {
+ "flash_extra_images": [
+ [
+ "0x10000",
+ "variants/tasmota/tasmota32s3-safeboot.bin"
+ ]
+ ]
+ },
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
diff --git a/boards/esp32s3cdc.json b/boards/esp32s3cdc-qio_qspi.json
similarity index 78%
rename from boards/esp32s3cdc.json
rename to boards/esp32s3cdc-qio_qspi.json
index f4cb53cde..81ac63bd2 100644
--- a/boards/esp32s3cdc.json
+++ b/boards/esp32s3cdc-qio_qspi.json
@@ -9,6 +9,12 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "partitions/esp32_partition_app2880k_fs320k.csv"
@@ -19,19 +25,23 @@
"ethernet"
],
"debug": {
+ "default_tool": "esp-builtin",
+ "onboard_tools": [
+ "esp-builtin"
+ ],
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
- "name": "Espressif Generic ESP32-S3 4M Flash, Tasmota 2880k Code/OTA, 320k FS",
+ "name": "Espressif Generic ESP32-S3 >= 4M Flash QSPI PSRAM, Tasmota 2880k Code/OTA, 320k FS",
"upload": {
"arduino": {
"flash_extra_images": [
[
"0x10000",
- "variants/tasmota/tasmota32s3cdc-safeboot.bin"
+ "variants/tasmota/tasmota32s3-safeboot.bin"
]
]
},
diff --git a/boards/esp32s3cdc_LilyTDisp.json b/boards/esp32s3cdc_LilyTDisp.json
deleted file mode 100644
index f9a7c0702..000000000
--- a/boards/esp32s3cdc_LilyTDisp.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "build": {
- "arduino":{
- "ldscript": "esp32s3_out.ld",
- "memory_type": "qio_opi"
- },
- "core": "esp32",
- "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DUSE_USB_CDC_CONSOLE -DESP32_8M -DESP32S3",
- "f_cpu": "240000000L",
- "f_flash": "80000000L",
- "flash_mode": "qio",
- "hwids": [
- [
- "0x303A",
- "0x1001"
- ]
- ],
- "mcu": "esp32s3",
- "variant": "esp32s3",
- "partitions": "partitions/esp32_partition_app2944k_fs10M.csv"
- },
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet"
- ],
- "debug": {
- "default_tool": "esp-builtin",
- "onboard_tools": "esp-builtin",
- "openocd_target": "esp32s3.cfg"
- },
- "frameworks": [
- "espidf",
- "arduino"
- ],
- "name": "LilyGo T-Display-S3 16M Flash 8MB OPI PSRAM, Tasmota 2944k Code/OTA, 10M FS",
- "upload": {
- "flash_size": "16MB",
- "maximum_ram_size": 327680,
- "maximum_size": 16777216,
- "require_upload_port": true,
- "before_reset": "usb_reset",
- "speed": 460800
- },
- "url": "https://github.com/Xinyuan-LilyGO/T-Display-S3",
- "vendor": "LilyGo"
- }
diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini
index ad7937d1c..02a8f92e6 100644
--- a/platformio_override_sample.ini
+++ b/platformio_override_sample.ini
@@ -98,19 +98,18 @@ lib_extra_dirs = ${library.lib_extra_dirs}
; *** Uncomment next lines ";" to enable development Tasmota Arduino version ESP32
;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.1/platform-espressif32-2.0.5.1.zip
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1008/framework-arduinoespressif32-IDF_Arduino-d772747b2.zip
-; = framework-arduino-ITEAD @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1014/framework-arduinoespressif32-solo1-IDF_Arduino-d772747b2.zip
-; framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1013/framework-arduinoespressif32-ITEAD-IDF_Arduino-d772747b2.zip
+; framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1014/framework-arduinoespressif32-solo1-IDF_Arduino-d772747b2.zip
+; framework-arduino-ITEAD @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1013/framework-arduinoespressif32-ITEAD-IDF_Arduino-d772747b2.zip
;build_unflags = ${esp32_defaults.build_unflags}
;build_flags = ${esp32_defaults.build_flags}
-
-; Build variant ESP32 4M Flash, Tasmota 1856k Code/OTA, 1344k LITTLEFS (default)
-;board = esp32_4M
-; Build variant ESP32 8M Flash, Tasmota 2944k Code/OTA, 2112k LITTLEFS
-;board = esp32_8M
-; Build variant ESP32 16M Flash, Tasmota 2944k Code/OTA, 10M LITTLEFS
-;board = esp32_16M
+;board = esp32
;board_build.f_cpu = 240000000L
;board_build.f_flash = 40000000L
+;board_build.flash_mode = qio
+;board_build.flash_size = 8MB
+;board_upload.maximum_size = 8388608
+;board_upload.arduino.flash_extra_images =
+;board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv
monitor_speed = 115200
; *** Serial port used for erasing/flashing the ESP32
;upload_port = ${common.upload_port}
diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini
index bb10ec1b1..397ac0792 100644
--- a/platformio_tasmota_cenv_sample.ini
+++ b/platformio_tasmota_cenv_sample.ini
@@ -14,12 +14,29 @@ build_flags = ${env:tasmota32_base.build_flags}
[env:tasmota32s3-file]
extends = env:tasmota32_base
-board = esp32s3
+board = esp32s3-qio_qspi
+board_build.f_cpu = 240000000L
+board_build.f_flash = 80000000L
build_flags = ${env:tasmota32_base.build_flags} -D FIRMWARE_TASMOTA32
-; example for custom file upload in Tasmota Filesystem
-; custom_files_upload = ${env:tasmota32_base.custom_files_upload}
-; tasmota/berry/modules/Partition_wizard.tapp
-; https://github.com/tasmota/autoconf/raw/main/esp32s3/DevKitC-1.autoconf
+; !!! Real flash size needed, avoid autoresize since it is formating FS !!!
+board_upload.flash_size = 8MB
+board_upload.maximum_size = 8388608
+; Without autoresize a partition scheme is needed which does fit to flash size
+board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv
+; Dont use safeboot, not used in this partition scheme -> an empty entry needed to overwrite the default setting
+board_upload.arduino.flash_extra_images =
+; Example for custom file upload in Tasmota Filesystem
+custom_files_upload = ${env:tasmota32_base.custom_files_upload}
+ tasmota/berry/modules/Partition_wizard.tapp
+ https://github.com/tasmota/autoconf/raw/main/esp32s3/DevKitC-1.autoconf
+
+[env:tasmota32s3-qio_opi-all]
+extends = env:tasmota32_base
+board = esp32s3-qio_opi
+board_build.f_cpu = 240000000L
+board_build.f_flash = 80000000L
+build_flags = ${env:tasmota32_base.build_flags} -DUSE_WEBCAM -DUSE_BERRY_ULP -DFIRMWARE_LVGL -DUSE_LVGL_OPENHASP
+
[env:tasmota32c3-bluetooth]
extends = env:tasmota32c3
@@ -64,7 +81,7 @@ lib_ignore = ESP8266Audio
TTGO TWatch Library
Micro-RTSP
epdiy
- esp32-camera
+ esp32-camera
[env:tasmota32s3-mi32-homebridge]
extends = env:tasmota32s3
@@ -108,7 +125,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32-ocd]
build_type = debug
extends = env:tasmota32_base
-board = esp32_4M
+board = esp32
debug_tool = esp-prog
upload_protocol = esp-prog
debug_init_break = tbreak setup
@@ -119,7 +136,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32solo1-ocd]
build_type = debug
extends = env:tasmota32solo1
-board = esp32_solo1_4M
+board = esp32_solo1
debug_tool = esp-prog
upload_protocol = esp-prog
debug_init_break = tbreak setup
@@ -143,7 +160,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32s3cdc-ocd]
build_type = debug
extends = env:tasmota32s3
-board = esp32s3cdc
+board = esp32s3cdc-qio_opi
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_init_break = tbreak setup
@@ -154,7 +171,7 @@ monitor_filters = esp32_exception_decoder
[env:tasmota32c3cdc-ocd]
build_type = debug
extends = env:tasmota32c3
-board = esp32c3cdc
+board = esp32c3cdc-qio_opi
debug_tool = esp-builtin
upload_protocol = esp-builtin
debug_init_break = tbreak setup
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index 154d5d42f..c938bb876 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -4,7 +4,7 @@ platform = ${core32.platform}
platform_packages = ${core32.platform_packages}
board_build.filesystem = ${common.board_build.filesystem}
custom_unpack_dir = ${common.custom_unpack_dir}
-board = esp32_4M
+board = esp32
monitor_speed = 115200
upload_port = ${common.upload_port}
upload_resetmethod = ${common.upload_resetmethod}
@@ -54,29 +54,24 @@ lib_ignore =
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
-[env:tasmota32_8M]
-extends = env:tasmota32_base
-board = esp32_8M
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
-
-[env:tasmota32_16M]
-extends = env:tasmota32_base
-board = esp32_16M
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
-
[env:tasmota32-webcam]
extends = env:tasmota32_base
-board = esp32-cam
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM
+board = esp32-fix
+board_build.f_cpu = 240000000L
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM -DCAMERA_MODEL_AI_THINKER
lib_extra_dirs = lib/lib_ssl, lib/libesp32
[env:tasmota32-odroidgo]
extends = env:tasmota32-lvgl
-board = esp32-odroid
+board_build.f_cpu = 240000000L
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 -DARDUINO_ODROID_ESP32
+board = esp32-fix
[env:tasmota32-core2]
extends = env:tasmota32-lvgl
-board = esp32-m5core2
+board_build.flash_mode = qio
+board_build.f_cpu = 240000000L
+board_build.f_flash = 80000000L
build_flags = ${env:tasmota32-lvgl.build_flags} -DUSE_I2S_SAY_TIME -DUSE_I2S_WEBRADIO -DUSE_SENDMAIL
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display, lib/lib_audio
@@ -93,7 +88,7 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_display, lib/lib_
[env:tasmota32-lvgl]
extends = env:tasmota32_base
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_LVGL
-board_build.f_cpu = 160000000L
+board_build.f_cpu = 240000000L
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display
[env:tasmota32-ir]
@@ -103,11 +98,11 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl
[env:tasmota32solo1]
extends = env:tasmota32_base
-board = esp32_solo1_4M
+board = esp32_solo1
[env:tasmota32solo1-safeboot]
extends = env:tasmota32_base
-board = esp32_solo1_4M
+board = esp32_solo1
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
@@ -117,7 +112,7 @@ lib_ignore =
[env:tasmota32-zbbrdgpro]
extends = env:tasmota32_base
-board = esp32_4M_FS
+board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv
build_flags = ${env:tasmota32_base.build_flags}
-DFIRMWARE_ZBBRDGPRO
-DFRAMEWORK_ARDUINO_ITEAD
@@ -201,7 +196,7 @@ board = esp32s2cdc
[env:tasmota32s3-safeboot]
extends = env:tasmota32_base
-board = esp32s3
+board = esp32s3-qio_qspi
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT
lib_extra_dirs = lib/lib_ssl, lib/libesp32
lib_ignore =
@@ -220,7 +215,7 @@ lib_ignore =
[env:tasmota32s3cdc-safeboot]
extends = env:tasmota32s3-safeboot
-board = esp32s3cdc
+board = esp32s3cdc-qio_qspi
[env:tasmota32s3cdc]
extends = env:tasmota32s3
From b8d594b868462bed2e574ddec49e4dbb2a4528f3 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 17 Oct 2022 16:12:18 +0200
Subject: [PATCH 019/319] fix [env:tasmota32s3cdc]
---
platformio_tasmota_env32.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index c938bb876..8de539460 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -219,7 +219,7 @@ board = esp32s3cdc-qio_qspi
[env:tasmota32s3cdc]
extends = env:tasmota32s3
-board = esp32s3cdc
+board = esp32s3cdc-qio_qspi
[env:tasmota32-AD]
extends = env:tasmota32_base
From c7a2d04972bf0f5474eb9074c081f54defa46e14 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 17 Oct 2022 16:15:27 +0200
Subject: [PATCH 020/319] fix [env:tasmota32s3]
---
platformio_tasmota_env32.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index 8de539460..8acfebe40 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -206,7 +206,7 @@ lib_ignore =
[env:tasmota32s3]
extends = env:tasmota32_base
-board = esp32s3
+board = esp32s3-qio_qspi
build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32
lib_ignore =
TTGO TWatch Library
From 9487465517df90b6062dcb2e1bd104e57172d22f Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 17 Oct 2022 16:49:55 +0200
Subject: [PATCH 021/319] s3cdc safeboot
---
boards/esp32s3cdc-qio_opi.json | 2 +-
boards/esp32s3cdc-qio_qspi.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/boards/esp32s3cdc-qio_opi.json b/boards/esp32s3cdc-qio_opi.json
index ad577df29..f01620ffc 100644
--- a/boards/esp32s3cdc-qio_opi.json
+++ b/boards/esp32s3cdc-qio_opi.json
@@ -41,7 +41,7 @@
"flash_extra_images": [
[
"0x10000",
- "variants/tasmota/tasmota32s3-safeboot.bin"
+ "variants/tasmota/tasmota32s3cdc-safeboot.bin"
]
]
},
diff --git a/boards/esp32s3cdc-qio_qspi.json b/boards/esp32s3cdc-qio_qspi.json
index 81ac63bd2..349cbe9ce 100644
--- a/boards/esp32s3cdc-qio_qspi.json
+++ b/boards/esp32s3cdc-qio_qspi.json
@@ -41,7 +41,7 @@
"flash_extra_images": [
[
"0x10000",
- "variants/tasmota/tasmota32s3-safeboot.bin"
+ "variants/tasmota/tasmota32s3cdc-safeboot.bin"
]
]
},
From a9ba035474ad51852988582ff1d989b8c24dcb3f Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 17 Oct 2022 17:59:18 +0200
Subject: [PATCH 022/319] refactor NTP fraction
---
tasmota/tasmota_support/support_wifi.ino | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index f202ff602..d06a35569 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -985,13 +985,12 @@ uint64_t WifiGetNtp(void) {
ntp_server_id++; // Next server next time
return 0;
}
-
- uint32_t highWord = word(packet_buffer[44], packet_buffer[45]);
- uint32_t lowWord = word(packet_buffer[46], packet_buffer[47]);
-
- uint32_t currentNano = (((uint64_t)(highWord << 16 | lowWord)) * 1000000000) >> 32;
-
- return (((uint64_t) secs_since_1900) - 2208988800UL) * 1000000000 + currentNano;
+ uint32_t tmp_fraction = (uint32_t)packet_buffer[44] << 24;
+ tmp_fraction |= (uint32_t)packet_buffer[45] << 16;
+ tmp_fraction |= (uint32_t)packet_buffer[46] << 8;
+ tmp_fraction |= (uint32_t)packet_buffer[47];
+ uint32_t fraction = (((uint64_t)tmp_fraction) * 1000000000) >> 32;
+ return (((uint64_t)secs_since_1900) - 2208988800UL) * 1000000000 + fraction;
}
delay(10);
}
From 4ba3b58ea8ecf2385c9a1bdec7823c0db298d05e Mon Sep 17 00:00:00 2001
From: Christian Karsch
Date: Mon, 17 Oct 2022 21:01:25 +0200
Subject: [PATCH 023/319] Added stop-condition before start-condition
Bp5758d does not support repeated-start-condition.
Therefore it overwrite the next register ('current range setup' of red-channel)
A stop-condition is always needed before next start-condition
---
tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino | 1 +
1 file changed, 1 insertion(+)
diff --git a/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino b/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino
index f0035180f..a0499bac8 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino
@@ -114,6 +114,7 @@ bool Bp5758dSetChannels(void) {
if (cur_col_10[0]==0 && cur_col_10[1]==0 && cur_col_10[2]==0 && cur_col_10[3]==0 && cur_col_10[4]==0) {
Bp5758dStart(BP5758D_ADDR_SETUP);
Bp5758dWrite(BP5758D_DISABLE_OUTPUTS_ALL);
+ Bp5758dStop();
Bp5758dStart(BP5758D_ADDR_SLEEP);
Bp5758dStop();
bIsSleeping = true;
From f87324f87488e15a6e961e1a0f1e791145e7be79 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 18 Oct 2022 09:55:08 +0200
Subject: [PATCH 024/319] LVGL fix get text
---
.../lv_binding_berry/generate/be_lv_c_mapping.h | 6 +++---
lib/libesp32_lvgl/lv_binding_berry/tools/convert.py | 2 +-
.../tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino | 4 +++-
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h
index 7c99171d3..5d7cb5ed9 100644
--- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h
+++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h
@@ -876,7 +876,7 @@ const be_ntv_func_def_t lv_dropdown_func[] = {
{ "get_options", { (const void*) &lv_dropdown_get_options, "s", "(lv.lv_obj)" } },
{ "get_selected", { (const void*) &lv_dropdown_get_selected, "i", "(lv.lv_obj)" } },
{ "get_selected_highlight", { (const void*) &lv_dropdown_get_selected_highlight, "b", "(lv.lv_obj)" } },
- { "get_selected_str", { (const void*) &lv_dropdown_get_selected_str, "", "(lv.lv_obj)ci" } },
+ { "get_selected_str", { (const void*) &lv_dropdown_get_selected_str, "", "(lv.lv_obj)si" } },
{ "get_symbol", { (const void*) &lv_dropdown_get_symbol, "s", "(lv.lv_obj)" } },
{ "get_text", { (const void*) &lv_dropdown_get_text, "s", "(lv.lv_obj)" } },
{ "is_open", { (const void*) &lv_dropdown_is_open, "b", "(lv.lv_obj)" } },
@@ -899,7 +899,7 @@ const be_ntv_func_def_t lv_label_func[] = {
{ "get_letter_pos", { (const void*) &lv_label_get_letter_pos, "", "(lv.lv_obj)i(lv.lv_point)" } },
{ "get_long_mode", { (const void*) &lv_label_get_long_mode, "i", "(lv.lv_obj)" } },
{ "get_recolor", { (const void*) &lv_label_get_recolor, "b", "(lv.lv_obj)" } },
- { "get_text", { (const void*) &lv_label_get_text, "c", "(lv.lv_obj)" } },
+ { "get_text", { (const void*) &lv_label_get_text, "s", "(lv.lv_obj)" } },
{ "get_text_selection_end", { (const void*) &lv_label_get_text_selection_end, "i", "(lv.lv_obj)" } },
{ "get_text_selection_start", { (const void*) &lv_label_get_text_selection_start, "i", "(lv.lv_obj)" } },
{ "ins_text", { (const void*) &lv_label_ins_text, "", "(lv.lv_obj)is" } },
@@ -929,7 +929,7 @@ const be_ntv_func_def_t lv_roller_func[] = {
{ "get_option_cnt", { (const void*) &lv_roller_get_option_cnt, "i", "(lv.lv_obj)" } },
{ "get_options", { (const void*) &lv_roller_get_options, "s", "(lv.lv_obj)" } },
{ "get_selected", { (const void*) &lv_roller_get_selected, "i", "(lv.lv_obj)" } },
- { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.lv_obj)ci" } },
+ { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.lv_obj)si" } },
{ "set_options", { (const void*) &lv_roller_set_options, "", "(lv.lv_obj)s(lv.lv_roller_mode)" } },
{ "set_selected", { (const void*) &lv_roller_set_selected, "", "(lv.lv_obj)ii" } },
{ "set_visible_row_count", { (const void*) &lv_roller_set_visible_row_count, "", "(lv.lv_obj)i" } },
diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py
index a8f4ba4ad..4890009c4 100644
--- a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py
+++ b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py
@@ -35,7 +35,7 @@ return_types = {
"int32_t": "i",
"void *": ".",
"const void *": ".",
- "char *": "c",
+ "char *": "s",
"uint8_t *": "c",
"const char *": "s",
"constchar *": "s", # special construct
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino
index 417bac186..854b3522c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota_global.ino
@@ -36,6 +36,7 @@ extern "C" {
4, /* number of elements */
nullptr,
(const be_ctypes_structure_item_t[4]) {
+ // Warning: fields below need to be in alphabetical order
{ "devices_present", offsetof(TasmotaGlobal_t, devices_present), 0, 0, ctypes_u8, 0 },
{ "fast_loop_enabled", offsetof(TasmotaGlobal_t, berry_fast_loop_enabled), 0, 0, ctypes_u8, 0 },
{ "restart_flag", offsetof(TasmotaGlobal_t, restart_flag), 0, 0, ctypes_u8, 0 },
@@ -47,10 +48,11 @@ extern "C" {
2, /* number of elements */
nullptr,
(const be_ctypes_structure_item_t[2]) {
+ // Warning: fields below need to be in alphabetical order
{ "bootcount", offsetof(TSettings, bootcount), 0, 0, ctypes_u16, 0 },
{ "sleep", offsetof(TSettings, sleep), 0, 0, ctypes_u8, 0 },
}};
}
-#endif // USE_BERRY
\ No newline at end of file
+#endif // USE_BERRY
From 1d34a80f65de0ce1d151228181b64ae6c6c4a5ce Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 18 Oct 2022 10:04:04 +0200
Subject: [PATCH 025/319] Fix only for returned string
---
lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h | 4 ++--
lib/libesp32_lvgl/lv_binding_berry/tools/convert.py | 4 +++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h
index 5d7cb5ed9..425bb7da1 100644
--- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h
+++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h
@@ -876,7 +876,7 @@ const be_ntv_func_def_t lv_dropdown_func[] = {
{ "get_options", { (const void*) &lv_dropdown_get_options, "s", "(lv.lv_obj)" } },
{ "get_selected", { (const void*) &lv_dropdown_get_selected, "i", "(lv.lv_obj)" } },
{ "get_selected_highlight", { (const void*) &lv_dropdown_get_selected_highlight, "b", "(lv.lv_obj)" } },
- { "get_selected_str", { (const void*) &lv_dropdown_get_selected_str, "", "(lv.lv_obj)si" } },
+ { "get_selected_str", { (const void*) &lv_dropdown_get_selected_str, "", "(lv.lv_obj)ci" } },
{ "get_symbol", { (const void*) &lv_dropdown_get_symbol, "s", "(lv.lv_obj)" } },
{ "get_text", { (const void*) &lv_dropdown_get_text, "s", "(lv.lv_obj)" } },
{ "is_open", { (const void*) &lv_dropdown_is_open, "b", "(lv.lv_obj)" } },
@@ -929,7 +929,7 @@ const be_ntv_func_def_t lv_roller_func[] = {
{ "get_option_cnt", { (const void*) &lv_roller_get_option_cnt, "i", "(lv.lv_obj)" } },
{ "get_options", { (const void*) &lv_roller_get_options, "s", "(lv.lv_obj)" } },
{ "get_selected", { (const void*) &lv_roller_get_selected, "i", "(lv.lv_obj)" } },
- { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.lv_obj)si" } },
+ { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.lv_obj)ci" } },
{ "set_options", { (const void*) &lv_roller_set_options, "", "(lv.lv_obj)s(lv.lv_roller_mode)" } },
{ "set_selected", { (const void*) &lv_roller_set_selected, "", "(lv.lv_obj)ii" } },
{ "set_visible_row_count", { (const void*) &lv_roller_set_visible_row_count, "", "(lv.lv_obj)i" } },
diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py
index 4890009c4..e3df18958 100644
--- a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py
+++ b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py
@@ -35,9 +35,10 @@ return_types = {
"int32_t": "i",
"void *": ".",
"const void *": ".",
- "char *": "s",
+ "char *": "c",
"uint8_t *": "c",
"const char *": "s",
+ "retchar *": "s",
"constchar *": "s", # special construct
"lv_obj_user_data_t": "i",
@@ -245,6 +246,7 @@ with open(lv_widgets_file) as f:
l_raw = re.sub('static ', '', l_raw)
l_raw = re.sub('inline ', '', l_raw)
l_raw = re.sub('const\s+char\s*\*', 'constchar *', l_raw)
+ l_raw = re.sub('^char\s*\*', 'retchar *', l_raw) # special case for returning a char*
l_raw = re.sub('const ', '', l_raw)
l_raw = re.sub('struct ', '', l_raw)
if (len(l_raw) == 0): continue
From 402a311d148d56ead764954e34cbe80c912a37f2 Mon Sep 17 00:00:00 2001
From: Jason2866
Date: Tue, 18 Oct 2022 11:53:50 +0000
Subject: [PATCH 026/319] rm not needed `*.h` files from lib
---
.../esp32-camera/driver/include/esp_camera.h | 214 ---------------
.../esp32-camera/driver/include/sensor.h | 245 ------------------
2 files changed, 459 deletions(-)
delete mode 100644 lib/libesp32/esp32-camera/driver/include/esp_camera.h
delete mode 100644 lib/libesp32/esp32-camera/driver/include/sensor.h
diff --git a/lib/libesp32/esp32-camera/driver/include/esp_camera.h b/lib/libesp32/esp32-camera/driver/include/esp_camera.h
deleted file mode 100644
index e9981671f..000000000
--- a/lib/libesp32/esp32-camera/driver/include/esp_camera.h
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-/*
- * Example Use
- *
- static camera_config_t camera_example_config = {
- .pin_pwdn = PIN_PWDN,
- .pin_reset = PIN_RESET,
- .pin_xclk = PIN_XCLK,
- .pin_sscb_sda = PIN_SIOD,
- .pin_sscb_scl = PIN_SIOC,
- .pin_d7 = PIN_D7,
- .pin_d6 = PIN_D6,
- .pin_d5 = PIN_D5,
- .pin_d4 = PIN_D4,
- .pin_d3 = PIN_D3,
- .pin_d2 = PIN_D2,
- .pin_d1 = PIN_D1,
- .pin_d0 = PIN_D0,
- .pin_vsync = PIN_VSYNC,
- .pin_href = PIN_HREF,
- .pin_pclk = PIN_PCLK,
-
- .xclk_freq_hz = 20000000,
- .ledc_timer = LEDC_TIMER_0,
- .ledc_channel = LEDC_CHANNEL_0,
- .pixel_format = PIXFORMAT_JPEG,
- .frame_size = FRAMESIZE_SVGA,
- .jpeg_quality = 10,
- .fb_count = 2,
- .grab_mode = CAMERA_GRAB_WHEN_EMPTY
- };
-
- esp_err_t camera_example_init(){
- return esp_camera_init(&camera_example_config);
- }
-
- esp_err_t camera_example_capture(){
- //capture a frame
- camera_fb_t * fb = esp_camera_fb_get();
- if (!fb) {
- ESP_LOGE(TAG, "Frame buffer could not be acquired");
- return ESP_FAIL;
- }
-
- //replace this with your own function
- display_image(fb->width, fb->height, fb->pixformat, fb->buf, fb->len);
-
- //return the frame buffer back to be reused
- esp_camera_fb_return(fb);
-
- return ESP_OK;
- }
-*/
-
-#pragma once
-
-#include "esp_err.h"
-#include "driver/ledc.h"
-#include "sensor.h"
-#include "sys/time.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Configuration structure for camera initialization
- */
-typedef enum {
- CAMERA_GRAB_WHEN_EMPTY, /*!< Fills buffers when they are empty. Less resources but first 'fb_count' frames might be old */
- CAMERA_GRAB_LATEST /*!< Except when 1 frame buffer is used, queue will always contain the last 'fb_count' frames */
-} camera_grab_mode_t;
-
-/**
- * @brief Camera frame buffer location
- */
-typedef enum {
- CAMERA_FB_IN_PSRAM, /*!< Frame buffer is placed in external PSRAM */
- CAMERA_FB_IN_DRAM /*!< Frame buffer is placed in internal DRAM */
-} camera_fb_location_t;
-
-/**
- * @brief Configuration structure for camera initialization
- */
-typedef struct {
- int pin_pwdn; /*!< GPIO pin for camera power down line */
- int pin_reset; /*!< GPIO pin for camera reset line */
- int pin_xclk; /*!< GPIO pin for camera XCLK line */
- int pin_sscb_sda; /*!< GPIO pin for camera SDA line */
- int pin_sscb_scl; /*!< GPIO pin for camera SCL line */
- int pin_d7; /*!< GPIO pin for camera D7 line */
- int pin_d6; /*!< GPIO pin for camera D6 line */
- int pin_d5; /*!< GPIO pin for camera D5 line */
- int pin_d4; /*!< GPIO pin for camera D4 line */
- int pin_d3; /*!< GPIO pin for camera D3 line */
- int pin_d2; /*!< GPIO pin for camera D2 line */
- int pin_d1; /*!< GPIO pin for camera D1 line */
- int pin_d0; /*!< GPIO pin for camera D0 line */
- int pin_vsync; /*!< GPIO pin for camera VSYNC line */
- int pin_href; /*!< GPIO pin for camera HREF line */
- int pin_pclk; /*!< GPIO pin for camera PCLK line */
-
- int xclk_freq_hz; /*!< Frequency of XCLK signal, in Hz. EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode */
-
- ledc_timer_t ledc_timer; /*!< LEDC timer to be used for generating XCLK */
- ledc_channel_t ledc_channel; /*!< LEDC channel to be used for generating XCLK */
-
- pixformat_t pixel_format; /*!< Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG */
- framesize_t frame_size; /*!< Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA */
-
- int jpeg_quality; /*!< Quality of JPEG output. 0-63 lower means higher quality */
- size_t fb_count; /*!< Number of frame buffers to be allocated. If more than one, then each frame will be acquired (double speed) */
- camera_fb_location_t fb_location; /*!< The location where the frame buffer will be allocated */
- camera_grab_mode_t grab_mode; /*!< When buffers should be filled */
-} camera_config_t;
-
-/**
- * @brief Data structure of camera frame buffer
- */
-typedef struct {
- uint8_t * buf; /*!< Pointer to the pixel data */
- size_t len; /*!< Length of the buffer in bytes */
- size_t width; /*!< Width of the buffer in pixels */
- size_t height; /*!< Height of the buffer in pixels */
- pixformat_t format; /*!< Format of the pixel data */
- struct timeval timestamp; /*!< Timestamp since boot of the first DMA buffer of the frame */
-} camera_fb_t;
-
-#define ESP_ERR_CAMERA_BASE 0x20000
-#define ESP_ERR_CAMERA_NOT_DETECTED (ESP_ERR_CAMERA_BASE + 1)
-#define ESP_ERR_CAMERA_FAILED_TO_SET_FRAME_SIZE (ESP_ERR_CAMERA_BASE + 2)
-#define ESP_ERR_CAMERA_FAILED_TO_SET_OUT_FORMAT (ESP_ERR_CAMERA_BASE + 3)
-#define ESP_ERR_CAMERA_NOT_SUPPORTED (ESP_ERR_CAMERA_BASE + 4)
-
-/**
- * @brief Initialize the camera driver
- *
- * @note call camera_probe before calling this function
- *
- * This function detects and configures camera over I2C interface,
- * allocates framebuffer and DMA buffers,
- * initializes parallel I2S input, and sets up DMA descriptors.
- *
- * Currently this function can only be called once and there is
- * no way to de-initialize this module.
- *
- * @param config Camera configuration parameters
- *
- * @return ESP_OK on success
- */
-esp_err_t esp_camera_init(const camera_config_t* config);
-
-/**
- * @brief Deinitialize the camera driver
- *
- * @return
- * - ESP_OK on success
- * - ESP_ERR_INVALID_STATE if the driver hasn't been initialized yet
- */
-esp_err_t esp_camera_deinit();
-
-/**
- * @brief Obtain pointer to a frame buffer.
- *
- * @return pointer to the frame buffer
- */
-camera_fb_t* esp_camera_fb_get();
-
-/**
- * @brief Return the frame buffer to be reused again.
- *
- * @param fb Pointer to the frame buffer
- */
-void esp_camera_fb_return(camera_fb_t * fb);
-
-/**
- * @brief Get a pointer to the image sensor control structure
- *
- * @return pointer to the sensor
- */
-sensor_t * esp_camera_sensor_get();
-
-/**
- * @brief Save camera settings to non-volatile-storage (NVS)
- *
- * @param key A unique nvs key name for the camera settings
- */
-esp_err_t esp_camera_save_to_nvs(const char *key);
-
-/**
- * @brief Load camera settings from non-volatile-storage (NVS)
- *
- * @param key A unique nvs key name for the camera settings
- */
-esp_err_t esp_camera_load_from_nvs(const char *key);
-
-#ifdef __cplusplus
-}
-#endif
-
-#include "img_converters.h"
-
diff --git a/lib/libesp32/esp32-camera/driver/include/sensor.h b/lib/libesp32/esp32-camera/driver/include/sensor.h
deleted file mode 100644
index 1f99c1541..000000000
--- a/lib/libesp32/esp32-camera/driver/include/sensor.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * This file is part of the OpenMV project.
- * Copyright (c) 2013/2014 Ibrahim Abdelkader
- * This work is licensed under the MIT license, see the file LICENSE for details.
- *
- * Sensor abstraction layer.
- *
- */
-#ifndef __SENSOR_H__
-#define __SENSOR_H__
-#include
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- OV9650_PID = 0x96,
- OV7725_PID = 0x77,
- OV2640_PID = 0x26,
- OV3660_PID = 0x3660,
- OV5640_PID = 0x5640,
- OV7670_PID = 0x76,
- NT99141_PID = 0x1410,
- GC2145_PID = 0x2145,
- GC032A_PID = 0x232a,
- GC0308_PID = 0x9b,
-} camera_pid_t;
-
-typedef enum {
- CAMERA_OV7725,
- CAMERA_OV2640,
- CAMERA_OV3660,
- CAMERA_OV5640,
- CAMERA_OV7670,
- CAMERA_NT99141,
- CAMERA_GC2145,
- CAMERA_GC032A,
- CAMERA_GC0308,
- CAMERA_MODEL_MAX,
- CAMERA_NONE,
-} camera_model_t;
-
-typedef enum {
- OV2640_SCCB_ADDR = 0x30,// 0x60 >> 1
- OV5640_SCCB_ADDR = 0x3C,// 0x78 >> 1
- OV3660_SCCB_ADDR = 0x3C,// 0x78 >> 1
- OV7725_SCCB_ADDR = 0x21,// 0x42 >> 1
- OV7670_SCCB_ADDR = 0x21,// 0x42 >> 1
- NT99141_SCCB_ADDR = 0x2A,// 0x54 >> 1
- GC2145_SCCB_ADDR = 0x3C,// 0x78 >> 1
- GC032A_SCCB_ADDR = 0x21,// 0x42 >> 1
- GC0308_SCCB_ADDR = 0x21,// 0x42 >> 1
-} camera_sccb_addr_t;
-
-typedef enum {
- PIXFORMAT_RGB565, // 2BPP/RGB565
- PIXFORMAT_YUV422, // 2BPP/YUV422
- PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
- PIXFORMAT_JPEG, // JPEG/COMPRESSED
- PIXFORMAT_RGB888, // 3BPP/RGB888
- PIXFORMAT_RAW, // RAW
- PIXFORMAT_RGB444, // 3BP2P/RGB444
- PIXFORMAT_RGB555, // 3BP2P/RGB555
-} pixformat_t;
-
-typedef enum {
- FRAMESIZE_96X96, // 96x96
- FRAMESIZE_QQVGA, // 160x120
- FRAMESIZE_QCIF, // 176x144
- FRAMESIZE_HQVGA, // 240x176
- FRAMESIZE_240X240, // 240x240
- FRAMESIZE_QVGA, // 320x240
- FRAMESIZE_CIF, // 400x296
- FRAMESIZE_HVGA, // 480x320
- FRAMESIZE_VGA, // 640x480
- FRAMESIZE_SVGA, // 800x600
- FRAMESIZE_XGA, // 1024x768
- FRAMESIZE_HD, // 1280x720
- FRAMESIZE_SXGA, // 1280x1024
- FRAMESIZE_UXGA, // 1600x1200
- // 3MP Sensors
- FRAMESIZE_FHD, // 1920x1080
- FRAMESIZE_P_HD, // 720x1280
- FRAMESIZE_P_3MP, // 864x1536
- FRAMESIZE_QXGA, // 2048x1536
- // 5MP Sensors
- FRAMESIZE_QHD, // 2560x1440
- FRAMESIZE_WQXGA, // 2560x1600
- FRAMESIZE_P_FHD, // 1080x1920
- FRAMESIZE_QSXGA, // 2560x1920
- FRAMESIZE_INVALID
-} framesize_t;
-
-typedef struct {
- const camera_model_t model;
- const char *name;
- const camera_sccb_addr_t sccb_addr;
- const camera_pid_t pid;
- const framesize_t max_size;
- const bool support_jpeg;
-} camera_sensor_info_t;
-
-typedef enum {
- ASPECT_RATIO_4X3,
- ASPECT_RATIO_3X2,
- ASPECT_RATIO_16X10,
- ASPECT_RATIO_5X3,
- ASPECT_RATIO_16X9,
- ASPECT_RATIO_21X9,
- ASPECT_RATIO_5X4,
- ASPECT_RATIO_1X1,
- ASPECT_RATIO_9X16
-} aspect_ratio_t;
-
-typedef enum {
- GAINCEILING_2X,
- GAINCEILING_4X,
- GAINCEILING_8X,
- GAINCEILING_16X,
- GAINCEILING_32X,
- GAINCEILING_64X,
- GAINCEILING_128X,
-} gainceiling_t;
-
-typedef struct {
- uint16_t max_width;
- uint16_t max_height;
- uint16_t start_x;
- uint16_t start_y;
- uint16_t end_x;
- uint16_t end_y;
- uint16_t offset_x;
- uint16_t offset_y;
- uint16_t total_x;
- uint16_t total_y;
-} ratio_settings_t;
-
-typedef struct {
- const uint16_t width;
- const uint16_t height;
- const aspect_ratio_t aspect_ratio;
-} resolution_info_t;
-
-// Resolution table (in sensor.c)
-extern const resolution_info_t resolution[];
-// camera sensor table (in sensor.c)
-extern const camera_sensor_info_t camera_sensor[];
-
-typedef struct {
- uint8_t MIDH;
- uint8_t MIDL;
- uint16_t PID;
- uint8_t VER;
-} sensor_id_t;
-
-typedef struct {
- framesize_t framesize;//0 - 10
- bool scale;
- bool binning;
- uint8_t quality;//0 - 63
- int8_t brightness;//-2 - 2
- int8_t contrast;//-2 - 2
- int8_t saturation;//-2 - 2
- int8_t sharpness;//-2 - 2
- uint8_t denoise;
- uint8_t special_effect;//0 - 6
- uint8_t wb_mode;//0 - 4
- uint8_t awb;
- uint8_t awb_gain;
- uint8_t aec;
- uint8_t aec2;
- int8_t ae_level;//-2 - 2
- uint16_t aec_value;//0 - 1200
- uint8_t agc;
- uint8_t agc_gain;//0 - 30
- uint8_t gainceiling;//0 - 6
- uint8_t bpc;
- uint8_t wpc;
- uint8_t raw_gma;
- uint8_t lenc;
- uint8_t hmirror;
- uint8_t vflip;
- uint8_t dcw;
- uint8_t colorbar;
-} camera_status_t;
-
-typedef struct _sensor sensor_t;
-typedef struct _sensor {
- sensor_id_t id; // Sensor ID.
- uint8_t slv_addr; // Sensor I2C slave address.
- pixformat_t pixformat;
- camera_status_t status;
- int xclk_freq_hz;
-
- // Sensor function pointers
- int (*init_status) (sensor_t *sensor);
- int (*reset) (sensor_t *sensor);
- int (*set_pixformat) (sensor_t *sensor, pixformat_t pixformat);
- int (*set_framesize) (sensor_t *sensor, framesize_t framesize);
- int (*set_contrast) (sensor_t *sensor, int level);
- int (*set_brightness) (sensor_t *sensor, int level);
- int (*set_saturation) (sensor_t *sensor, int level);
- int (*set_sharpness) (sensor_t *sensor, int level);
- int (*set_denoise) (sensor_t *sensor, int level);
- int (*set_gainceiling) (sensor_t *sensor, gainceiling_t gainceiling);
- int (*set_quality) (sensor_t *sensor, int quality);
- int (*set_colorbar) (sensor_t *sensor, int enable);
- int (*set_whitebal) (sensor_t *sensor, int enable);
- int (*set_gain_ctrl) (sensor_t *sensor, int enable);
- int (*set_exposure_ctrl) (sensor_t *sensor, int enable);
- int (*set_hmirror) (sensor_t *sensor, int enable);
- int (*set_vflip) (sensor_t *sensor, int enable);
-
- int (*set_aec2) (sensor_t *sensor, int enable);
- int (*set_awb_gain) (sensor_t *sensor, int enable);
- int (*set_agc_gain) (sensor_t *sensor, int gain);
- int (*set_aec_value) (sensor_t *sensor, int gain);
-
- int (*set_special_effect) (sensor_t *sensor, int effect);
- int (*set_wb_mode) (sensor_t *sensor, int mode);
- int (*set_ae_level) (sensor_t *sensor, int level);
-
- int (*set_dcw) (sensor_t *sensor, int enable);
- int (*set_bpc) (sensor_t *sensor, int enable);
- int (*set_wpc) (sensor_t *sensor, int enable);
-
- int (*set_raw_gma) (sensor_t *sensor, int enable);
- int (*set_lenc) (sensor_t *sensor, int enable);
-
- int (*get_reg) (sensor_t *sensor, int reg, int mask);
- int (*set_reg) (sensor_t *sensor, int reg, int mask, int value);
- int (*set_res_raw) (sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning);
- int (*set_pll) (sensor_t *sensor, int bypass, int mul, int sys, int root, int pre, int seld5, int pclken, int pclk);
- int (*set_xclk) (sensor_t *sensor, int timer, int xclk);
-} sensor_t;
-
-camera_sensor_info_t *esp_camera_sensor_get_info(sensor_id_t *id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SENSOR_H__ */
From 7b6f724685df1ff67c558fabc3c13024735a7e41 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 18 Oct 2022 15:34:07 +0200
Subject: [PATCH 027/319] Update changelogs
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d475bd835..8ef28286b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
### Changed
### Fixed
+- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
### Removed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 9884f96f3..842982221 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -115,5 +115,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Changed
### Fixed
+- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
### Removed
From 2104256b748239ac1e6168e2b1def3e7761b23eb Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 18 Oct 2022 16:36:45 +0200
Subject: [PATCH 028/319] Add DS18x20 support on up to four GPIOs
Add DS18x20 support on up to four GPIOs by md5sum-as (#16833)
---
CHANGELOG.md | 2 +
RELEASENOTES.md | 2 +
tasmota/include/tasmota.h | 2 -
tasmota/include/tasmota_template.h | 19 +--
tasmota/my_user_config.h | 1 -
.../tasmota_xsns_sensor/xsns_05_ds18x20.ino | 140 +++++++-----------
.../xsns_05_esp32_ds18x20.ino | 110 ++++++--------
7 files changed, 109 insertions(+), 167 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ef28286b..2bd97b23a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,10 +5,12 @@ All notable changes to this project will be documented in this file.
## [12.2.0.1]
### Added
+- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
### Breaking Changed
### Changed
+- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 842982221..a0ca79df2 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,10 +109,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.1
### Added
+- DS18x20 support on up to four GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
### Breaking Changed
### Changed
+- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index 3e696ba18..5383ba276 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -304,8 +304,6 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
#define XPT2046_MINY 346
#define XPT2046_MAXY 3870
-// Max number GPIO for DS18x20_MULTI_GPIOs
-#define MAX_DSB 4
/*********************************************************************************************\
* Enumeration
\*********************************************************************************************/
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 35d928b31..34a1e9642 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -446,6 +446,7 @@ const char kSensorNames[] PROGMEM =
const char kSensorNamesFixed[] PROGMEM =
D_SENSOR_USER;
+// Max number of GPIOs
#define MAX_MAX31865S 6
#define MAX_FLOWRATEMETER 2
#define MAX_A4988_MSS 3
@@ -453,6 +454,7 @@ const char kSensorNamesFixed[] PROGMEM =
#define MAX_WEBCAM_HSD 3
#define MAX_SM2135_DAT 10
#define MAX_SM2335_DAT 16
+#define MAX_DSB 4
const uint16_t kGpioNiceList[] PROGMEM = {
GPIO_NONE, // Not used
@@ -661,18 +663,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321
#endif
#ifdef USE_DS18x20
-#ifdef DS18x20_MULTI_GPIOs
- AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20
-#ifdef ESP8266 // ESP32 don't support dual pin mode
- AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20
-#endif
-#else
- AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20
-#ifdef ESP8266 // ESP32 don't support dual pin mode
- AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20
-#endif
-#endif //DS18x20_MULTI_GPIOs
-#endif
+ AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20
+#ifdef ESP8266
+ AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20
+#endif // ESP8266
+#endif // USE_DS18x20
#ifdef USE_LMT01
AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO
#endif
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 31eb5d345..51ea0d677 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -580,7 +580,6 @@
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
// #define W1_PARASITE_POWER // Optimize for parasite powered sensors
// #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
-// #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
// -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index bbc71b1a5..8c5ae975e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -1,8 +1,8 @@
/*
xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Tasmota
- Copyright (C) 2021 Theo Arends
-
+ Copyright (C) 2021 Theo Arends and md5sum-as (https://github.com/md5sum-as)
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -15,8 +15,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-
- Updated by md5sum-as (https://github.com/md5sum-as)
*/
#ifdef ESP8266
@@ -28,8 +26,8 @@
#define XSNS_05 5
//#define USE_DS18x20_RECONFIGURE // When sensor is lost keep retrying or re-configure
-//#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors
-
+//#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors
+
/* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h
* Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255
* Result in JSON: "DS18Sens_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2)
@@ -47,7 +45,7 @@
#define W1_WRITE_SCRATCHPAD 0x4E
#define W1_READ_SCRATCHPAD 0xBE
-#ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h
+#ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h
#define DS18X20_MAX_SENSORS 8
#endif
@@ -62,22 +60,17 @@ struct {
uint8_t address[8];
uint8_t index;
uint8_t valid;
+ int8_t pins_id;
#ifdef DS18x20_USE_ID_ALIAS
uint8_t alias;
-#endif //DS18x20_USE_ID_ALIAS
-#ifdef DS18x20_MULTI_GPIOs
- int8_t pins_id = 0;
-#endif //DS18x20_MULTI_GPIOs
+#endif // DS18x20_USE_ID_ALIAS
} ds18x20_sensor[DS18X20_MAX_SENSORS];
-#ifdef DS18x20_MULTI_GPIOs
struct {
int8_t pin = 0; // Shelly GPIO3 input only
int8_t pin_out = 0; // Shelly GPIO00 output only
bool dual_mode = false; // Single pin mode
} ds18x20_gpios[MAX_DSB];
-uint8_t ds18x20_ngpio = 0; // Count of GPIO found
-#endif
struct {
#ifdef W1_PARASITE_POWER
@@ -85,7 +78,8 @@ struct {
uint8_t current_sensor = 0;
#endif
char name[17];
- uint8_t sensors = 0;
+ uint8_t sensors;
+ uint8_t gpios; // Count of GPIO found
uint8_t input_mode = 0; // INPUT or INPUT_PULLUP (=2)
int8_t pin = 0; // Shelly GPIO3 input only
int8_t pin_out = 0; // Shelly GPIO00 output only
@@ -315,27 +309,24 @@ bool OneWireCrc8(uint8_t *addr) {
/********************************************************************************************/
void Ds18x20Init(void) {
- DS18X20Data.input_mode = Settings->flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT; // SetOption74 - Enable internal pullup for single DS18x20 sensor
-
- uint64_t ids[DS18X20_MAX_SENSORS];
- DS18X20Data.sensors = 0;
-
-#ifdef DS18x20_MULTI_GPIOs
- ds18x20_ngpio=0;
-uint8_t pins;
- for (pins = 0; pins < MAX_DSB; pins++) {
+ DS18X20Data.gpios = 0;
+ for (uint32_t pins = 0; pins < MAX_DSB; pins++) {
if (PinUsed(GPIO_DSB, pins)) {
- ds18x20_gpios[pins].pin = Pin(GPIO_DSB, pins);
+ ds18x20_gpios[pins].pin = Pin(GPIO_DSB, pins);
if (PinUsed(GPIO_DSB_OUT, pins)) {
ds18x20_gpios[pins].dual_mode = true;
ds18x20_gpios[pins].pin_out = Pin(GPIO_DSB_OUT, pins);
}
- ds18x20_ngpio++;
+ DS18X20Data.gpios++;
}
}
- for (pins = 0; pins < ds18x20_ngpio; pins++) {
+ uint64_t ids[DS18X20_MAX_SENSORS];
+ DS18X20Data.sensors = 0;
+ DS18X20Data.input_mode = Settings->flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT; // SetOption74 - Enable internal pullup for single DS18x20 sensor
+
+ for (uint32_t pins = 0; pins < DS18X20Data.gpios; pins++) {
DS18X20Data.pin = ds18x20_gpios[pins].pin;
DS18X20Data.dual_mode = ds18x20_gpios[pins].dual_mode;
if (ds18x20_gpios[pins].dual_mode) {
@@ -343,52 +334,37 @@ uint8_t pins;
pinMode(DS18X20Data.pin_out, OUTPUT);
pinMode(DS18X20Data.pin, DS18X20Data.input_mode);
}
-#else
- DS18X20Data.pin = Pin(GPIO_DSB);
- if (PinUsed(GPIO_DSB_OUT)) {
- DS18X20Data.pin_out = Pin(GPIO_DSB_OUT);
- DS18X20Data.dual_mode = true; // Dual pins mode as used by Shelly
- pinMode(DS18X20Data.pin_out, OUTPUT);
- pinMode(DS18X20Data.pin, DS18X20Data.input_mode);
- }
-#endif //DS18x20_MULTI_GPIOs
-
- onewire_last_discrepancy = 0;
- onewire_last_device_flag = false;
- onewire_last_family_discrepancy = 0;
- for (uint32_t i = 0; i < 8; i++) {
- onewire_rom_id[i] = 0;
- }
-
- while (DS18X20Data.sensors < DS18X20_MAX_SENSORS) {
- if (!OneWireSearch(ds18x20_sensor[DS18X20Data.sensors].address)) {
- break;
+ onewire_last_discrepancy = 0;
+ onewire_last_device_flag = false;
+ onewire_last_family_discrepancy = 0;
+ for (uint32_t i = 0; i < 8; i++) {
+ onewire_rom_id[i] = 0;
}
- if (OneWireCrc8(ds18x20_sensor[DS18X20Data.sensors].address) &&
- ((ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18S20_CHIPID) ||
- (ds18x20_sensor[DS18X20Data.sensors].address[0] == DS1822_CHIPID) ||
- (ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18B20_CHIPID) ||
- (ds18x20_sensor[DS18X20Data.sensors].address[0] == MAX31850_CHIPID))) {
- ds18x20_sensor[DS18X20Data.sensors].index = DS18X20Data.sensors;
- ids[DS18X20Data.sensors] = ds18x20_sensor[DS18X20Data.sensors].address[0]; // Chip id
- for (uint32_t j = 6; j > 0; j--) {
- ids[DS18X20Data.sensors] = ids[DS18X20Data.sensors] << 8 | ds18x20_sensor[DS18X20Data.sensors].address[j];
+
+ while (DS18X20Data.sensors < DS18X20_MAX_SENSORS) {
+ if (!OneWireSearch(ds18x20_sensor[DS18X20Data.sensors].address)) {
+ break;
}
-#ifdef DS18x20_USE_ID_ALIAS
- ds18x20_sensor[DS18X20Data.sensors].alias=0;
+ if (OneWireCrc8(ds18x20_sensor[DS18X20Data.sensors].address) &&
+ ((ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18S20_CHIPID) ||
+ (ds18x20_sensor[DS18X20Data.sensors].address[0] == DS1822_CHIPID) ||
+ (ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18B20_CHIPID) ||
+ (ds18x20_sensor[DS18X20Data.sensors].address[0] == MAX31850_CHIPID))) {
+ ds18x20_sensor[DS18X20Data.sensors].index = DS18X20Data.sensors;
+ ids[DS18X20Data.sensors] = ds18x20_sensor[DS18X20Data.sensors].address[0]; // Chip id
+ for (uint32_t j = 6; j > 0; j--) {
+ ids[DS18X20Data.sensors] = ids[DS18X20Data.sensors] << 8 | ds18x20_sensor[DS18X20Data.sensors].address[j];
+ }
+#ifdef DS18x20_USE_ID_ALIAS
+ ds18x20_sensor[DS18X20Data.sensors].alias=0;
#endif
-#ifdef DS18x20_MULTI_GPIOs
- ds18x20_sensor[DS18X20Data.sensors].pins_id = pins;
-#endif //DS18x20_MULTI_GPIOs
- DS18X20Data.sensors++;
+ ds18x20_sensor[DS18X20Data.sensors].pins_id = pins;
+ DS18X20Data.sensors++;
+ }
}
}
-#ifdef DS18x20_MULTI_GPIOs
- }
-#endif //DS18x20_MULTI_GPIOs
-//#ifndef DS18x20_MULTI_GPIOs
for (uint32_t i = 0; i < DS18X20Data.sensors; i++) {
for (uint32_t j = i + 1; j < DS18X20Data.sensors; j++) {
if (ids[ds18x20_sensor[i].index] > ids[ds18x20_sensor[j].index]) { // Sort ascending
@@ -396,31 +372,27 @@ uint8_t pins;
}
}
}
-//#endif
+
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors);
}
void Ds18x20Convert(void) {
-#ifdef DS18x20_MULTI_GPIOs
- for (uint8_t i = 0; i < ds18x20_ngpio; i++) {
+ for (uint8_t i = 0; i < DS18X20Data.gpios; i++) {
DS18X20Data.pin = ds18x20_gpios[i].pin;
DS18X20Data.dual_mode = ds18x20_gpios[i].dual_mode;
DS18X20Data.pin_out = ds18x20_gpios[i].pin_out;
-#endif
- OneWireReset();
+ OneWireReset();
#ifdef W1_PARASITE_POWER
- // With parasite power address one sensor at a time
- if (++DS18X20Data.current_sensor >= DS18X20Data.sensors)
- DS18X20Data.current_sensor = 0;
- OneWireSelect(ds18x20_sensor[DS18X20Data.current_sensor].address);
+ // With parasite power address one sensor at a time
+ if (++DS18X20Data.current_sensor >= DS18X20Data.sensors)
+ DS18X20Data.current_sensor = 0;
+ OneWireSelect(ds18x20_sensor[DS18X20Data.current_sensor].address);
#else
- OneWireWrite(W1_SKIP_ROM); // Address all Sensors on Bus
+ OneWireWrite(W1_SKIP_ROM); // Address all Sensors on Bus
#endif
- OneWireWrite(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
-// delay(750); // 750ms should be enough for 12bit conv
-#ifdef DS18x20_MULTI_GPIOs
+ OneWireWrite(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
+// delay(750); // 750ms should be enough for 12bit conv
}
-#endif
}
bool Ds18x20Read(uint8_t sensor) {
@@ -429,11 +401,9 @@ bool Ds18x20Read(uint8_t sensor) {
int8_t sign = 1;
uint8_t index = ds18x20_sensor[sensor].index;
-#ifdef DS18x20_MULTI_GPIOs
DS18X20Data.pin = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin;
DS18X20Data.pin_out = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin_out;
DS18X20Data.dual_mode = ds18x20_gpios[ds18x20_sensor[index].pins_id].dual_mode;
-#endif
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
for (uint32_t retry = 0; retry < 3; retry++) {
OneWireReset();
@@ -608,7 +578,7 @@ void CmndDSAlias(void) {
uint8_t sensor=255;
char argument[XdrvMailbox.data_len];
char address[17];
-
+
if (ArgC()==2) {
tmp=atoi(ArgV(argument, 2));
ArgV(argument,1);
@@ -643,8 +613,8 @@ void CmndDSAlias(void) {
bool Xsns05(uint8_t function) {
bool result = false;
-
- if (PinUsed(GPIO_DSB,GPIO_ANY)) {
+
+ if (PinUsed(GPIO_DSB, GPIO_ANY)) {
switch (function) {
case FUNC_INIT:
Ds18x20Init();
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
index b37639c7a..2346cbe96 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
@@ -1,8 +1,8 @@
/*
xsns_05_esp32_ds18x20.ino - DS18x20 temperature sensor support for ESP32 Tasmota
- Copyright (C) 2021 Heiko Krupp and Theo Arends
-
+ Copyright (C) 2021 Heiko Krupp, Theo Arends and md5sum-as (https://github.com/md5sum-as)
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -15,8 +15,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-
- Updated by md5sum-as (https://github.com/md5sum-as)
*/
#ifdef ESP32
@@ -27,7 +25,7 @@
#define XSNS_05 5
-//#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors
+//#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors
/* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h
* Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255
@@ -44,7 +42,7 @@
#define W1_CONVERT_TEMP 0x44
#define W1_READ_SCRATCHPAD 0xBE
-#ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h
+#ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h
#define DS18X20_MAX_SENSORS 8
#endif
@@ -58,78 +56,62 @@ struct {
uint8_t address[8];
uint8_t index;
uint8_t valid;
+ int8_t pins_id;
#ifdef DS18x20_USE_ID_ALIAS
uint8_t alias;
#endif //DS18x20_USE_ID_ALIAS
-#ifdef DS18x20_MULTI_GPIOs
- int8_t pins_id = 0;
-#endif //DS18x20_MULTI_GPIOs
} ds18x20_sensor[DS18X20_MAX_SENSORS];
#include
-
-#ifdef DS18x20_MULTI_GPIOs
+OneWire *ds = nullptr;
OneWire *ds18x20_gpios[MAX_DSB];
-uint8_t ds18x20_ngpio = 0; // Count of GPIO found
-#endif
struct {
char name[17];
- uint8_t sensors = 0;
+ uint8_t sensors;
+ uint8_t gpios; // Count of GPIO found
} DS18X20Data;
/********************************************************************************************/
-OneWire *ds = nullptr;
-
void Ds18x20Init(void) {
-
-#ifdef DS18x20_MULTI_GPIOs
- for (uint8_t pins = 0; pins < MAX_DSB; pins++) {
- if (PinUsed(GPIO_DSB, pins)) {
- ds18x20_gpios[pins] = new OneWire(Pin(GPIO_DSB,pins));
- ds18x20_ngpio++;
+ DS18X20Data.gpios = 0;
+ for (uint32_t pins = 0; pins < MAX_DSB; pins++) {
+ if (PinUsed(GPIO_DSB, pins)) {
+ ds18x20_gpios[pins] = new OneWire(Pin(GPIO_DSB, pins));
+ DS18X20Data.gpios++;
}
}
-#else
- ds = new OneWire(Pin(GPIO_DSB));
-#endif
Ds18x20Search();
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors);
}
void Ds18x20Search(void) {
- uint8_t num_sensors=0;
+ uint8_t num_sensors = 0;
uint8_t sensor = 0;
-#ifdef DS18x20_MULTI_GPIOs
- for (uint8_t pins=0; pins < ds18x20_ngpio; pins++) {
- ds=ds18x20_gpios[pins];
+ for (uint8_t pins = 0; pins < DS18X20Data.gpios; pins++) {
+ ds = ds18x20_gpios[pins];
+ ds->reset_search();
+ for (num_sensors; num_sensors < DS18X20_MAX_SENSORS; num_sensors) {
+ if (!ds->search(ds18x20_sensor[num_sensors].address)) {
+ ds->reset_search();
+ break;
+ }
+ // If CRC Ok and Type DS18S20, DS1822, DS18B20 or MAX31850
+ if ((OneWire::crc8(ds18x20_sensor[num_sensors].address, 7) == ds18x20_sensor[num_sensors].address[7]) &&
+ ((ds18x20_sensor[num_sensors].address[0] == DS18S20_CHIPID) ||
+ (ds18x20_sensor[num_sensors].address[0] == DS1822_CHIPID) ||
+ (ds18x20_sensor[num_sensors].address[0] == DS18B20_CHIPID) ||
+ (ds18x20_sensor[num_sensors].address[0] == MAX31850_CHIPID))) {
+#ifdef DS18x20_USE_ID_ALIAS
+ ds18x20_sensor[num_sensors].alias=0;
#endif
- ds->reset_search();
- for (num_sensors; num_sensors < DS18X20_MAX_SENSORS; num_sensors) {
- if (!ds->search(ds18x20_sensor[num_sensors].address)) {
- ds->reset_search();
- break;
- }
- // If CRC Ok and Type DS18S20, DS1822, DS18B20 or MAX31850
- if ((OneWire::crc8(ds18x20_sensor[num_sensors].address, 7) == ds18x20_sensor[num_sensors].address[7]) &&
- ((ds18x20_sensor[num_sensors].address[0] == DS18S20_CHIPID) ||
- (ds18x20_sensor[num_sensors].address[0] == DS1822_CHIPID) ||
- (ds18x20_sensor[num_sensors].address[0] == DS18B20_CHIPID) ||
- (ds18x20_sensor[num_sensors].address[0] == MAX31850_CHIPID))) {
-#ifdef DS18x20_USE_ID_ALIAS
- ds18x20_sensor[num_sensors].alias=0;
-#endif
-#ifdef DS18x20_MULTI_GPIOs
- ds18x20_sensor[num_sensors].pins_id = pins;
-#endif //DS18x20_MULTI_GPIOs
- num_sensors++;
+ ds18x20_sensor[num_sensors].pins_id = pins;
+ num_sensors++;
+ }
}
}
-#ifdef DS18x20_MULTI_GPIOs
- }
-#endif //DS18x20_MULTI_GPIOs
for (uint32_t i = 0; i < num_sensors; i++) {
ds18x20_sensor[i].index = i;
@@ -145,17 +127,13 @@ void Ds18x20Search(void) {
}
void Ds18x20Convert(void) {
-#ifdef DS18x20_MULTI_GPIOs
- for (uint8_t i = 0; i < ds18x20_ngpio; i++) {
- ds=ds18x20_gpios[i];
-#endif
- ds->reset();
- ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
- ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
-// delay(750); // 750ms should be enough for 12bit conv
-#ifdef DS18x20_MULTI_GPIOs
- }
-#endif
+ for (uint32_t i = 0; i < DS18X20Data.gpios; i++) {
+ ds = ds18x20_gpios[i];
+ ds->reset();
+ ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
+ ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
+// delay(750); // 750ms should be enough for 12bit conv
+ }
}
bool Ds18x20Read(uint8_t sensor, float &t) {
@@ -166,9 +144,7 @@ bool Ds18x20Read(uint8_t sensor, float &t) {
uint8_t index = ds18x20_sensor[sensor].index;
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
-#ifdef DS18x20_MULTI_GPIOs
- ds=ds18x20_gpios[ds18x20_sensor[index].pins_id];
-#endif
+ ds = ds18x20_gpios[ds18x20_sensor[index].pins_id];
ds->reset();
ds->select(ds18x20_sensor[index].address);
ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad
@@ -316,7 +292,7 @@ void CmndDSAlias(void) {
uint8_t sensor=255;
char argument[XdrvMailbox.data_len];
char address[17];
-
+
if (ArgC()==2) {
tmp=atoi(ArgV(argument, 2));
ArgV(argument,1);
@@ -352,7 +328,7 @@ void CmndDSAlias(void) {
bool Xsns05(uint8_t function) {
bool result = false;
- if (PinUsed(GPIO_DSB,GPIO_ANY)) {
+ if (PinUsed(GPIO_DSB, GPIO_ANY)) {
switch (function) {
case FUNC_INIT:
Ds18x20Init();
From f77a5c96f61e8f97480e9fcbd08e23741d1f8357 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 18 Oct 2022 17:30:39 +0200
Subject: [PATCH 029/319] remove webcam lib
---
.../include => default/headers}/cam_hal.h | 0
.../include => default/headers}/camera_pins.h | 0
lib/libesp32/esp32-camera/LICENSE | 202 ----------
lib/libesp32/esp32-camera/README.md | 368 ------------------
.../esp32-camera/driver/include/xclk.h | 9 -
lib/libesp32/esp32-camera/library.json | 20 -
platformio_tasmota_cenv_sample.ini | 3 -
7 files changed, 602 deletions(-)
rename lib/{libesp32/esp32-camera/driver/include => default/headers}/cam_hal.h (100%)
rename lib/{libesp32/esp32-camera/driver/include => default/headers}/camera_pins.h (100%)
delete mode 100644 lib/libesp32/esp32-camera/LICENSE
delete mode 100644 lib/libesp32/esp32-camera/README.md
delete mode 100644 lib/libesp32/esp32-camera/driver/include/xclk.h
delete mode 100644 lib/libesp32/esp32-camera/library.json
diff --git a/lib/libesp32/esp32-camera/driver/include/cam_hal.h b/lib/default/headers/cam_hal.h
similarity index 100%
rename from lib/libesp32/esp32-camera/driver/include/cam_hal.h
rename to lib/default/headers/cam_hal.h
diff --git a/lib/libesp32/esp32-camera/driver/include/camera_pins.h b/lib/default/headers/camera_pins.h
similarity index 100%
rename from lib/libesp32/esp32-camera/driver/include/camera_pins.h
rename to lib/default/headers/camera_pins.h
diff --git a/lib/libesp32/esp32-camera/LICENSE b/lib/libesp32/esp32-camera/LICENSE
deleted file mode 100644
index d64569567..000000000
--- a/lib/libesp32/esp32-camera/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/lib/libesp32/esp32-camera/README.md b/lib/libesp32/esp32-camera/README.md
deleted file mode 100644
index e93d5cdba..000000000
--- a/lib/libesp32/esp32-camera/README.md
+++ /dev/null
@@ -1,368 +0,0 @@
-# ESP32 Camera Driver
-
-[](https://github.com/espressif/esp32-camera/actions/workflows/build.yml)
-## General Information
-
-This repository hosts ESP32 series Soc compatible driver for image sensors. Additionally it provides a few tools, which allow converting the captured frame data to the more common BMP and JPEG formats.
-
-### Supported Soc
-
-- ESP32
-- ESP32-S2
-- ESP32-S3
-
-### Supported Sensor
-
-| model | max resolution | color type | output format | Len Size |
-| ------- | -------------- | ---------- | ------------------------------------------------------------ | -------- |
-| OV2640 | 1600 x 1200 | color | YUV(422/420)/YCbCr422
RGB565/555
8-bit compressed data
8/10-bit Raw RGB data | 1/4" |
-| OV3660 | 2048 x 1536 | color | raw RGB data
RGB565/555/444
CCIR656
YCbCr422
compression | 1/5" |
-| OV5640 | 2592 x 1944 | color | RAW RGB
RGB565/555/444
CCIR656
YUV422/420
YCbCr422
compression | 1/4" |
-| OV7670 | 640 x 480 | color | Raw Bayer RGB
Processed Bayer RGB
YUV/YCbCr422
GRB422
RGB565/555 | 1/6" |
-| OV7725 | 640 x 480 | color | Raw RGB
GRB 422
RGB565/555/444
YCbCr 422 | 1/4" |
-| NT99141 | 1280 x 720 | color | YCbCr 422
RGB565/555/444
Raw
CCIR656
JPEG compression | 1/4" |
-| GC032A | 640 x 480 | color | YUV/YCbCr422
RAW Bayer
RGB565 | 1/10" |
-| GC0308 | 640 x 480 | color | YUV/YCbCr422
RAW Bayer
RGB565 | 1/6.5" |
-| GC2145 | 1600 x 1200 | color | YUV/YCbCr422
RAW Bayer
RGB565 | 1/5" |
-
-## Important to Remember
-
-- Except when using CIF or lower resolution with JPEG, the driver requires PSRAM to be installed and activated.
-- Using YUV or RGB puts a lot of strain on the chip because writing to PSRAM is not particularly fast. The result is that image data might be missing. This is particularly true if WiFi is enabled. If you need RGB data, it is recommended that JPEG is captured and then turned into RGB using `fmt2rgb888` or `fmt2bmp`/`frame2bmp`.
-- When 1 frame buffer is used, the driver will wait for the current frame to finish (VSYNC) and start I2S DMA. After the frame is acquired, I2S will be stopped and the frame buffer returned to the application. This approach gives more control over the system, but results in longer time to get the frame.
-- When 2 or more frame bufers are used, I2S is running in continuous mode and each frame is pushed to a queue that the application can access. This approach puts more strain on the CPU/Memory, but allows for double the frame rate. Please use only with JPEG.
-
-## Installation Instructions
-
-
-### Using esp-idf
-
-- Clone or download and extract the repository to the components folder of your ESP-IDF project
-- Enable PSRAM in `menuconfig` (also set Flash and PSRAM frequiencies to 80MHz)
-- Include `esp_camera.h` in your code
-
-### Using PlatformIO
-
-The easy way -- on the `env` section of `platformio.ini`, add the following:
-
-```ini
-[env]
-lib_deps =
- esp32-camera
-```
-
-Now the `esp_camera.h` is available to be included:
-
-```c
-#include "esp_camera.h"
-```
-
-Enable PSRAM on `menuconfig` or type it direclty on `sdkconfig`. Check the [official doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/kconfig.html#config-esp32-spiram-support) for more info.
-
-```
-CONFIG_ESP32_SPIRAM_SUPPORT=y
-```
-
-***Arduino*** The easy-way (content above) only seems to work if you're using `framework=arduino` which seems to take a bunch of the guesswork out (thanks Arduino!) but also suck up a lot more memory and flash, almost crippling the performance. If you plan to use the `framework=espidf` then read the sections below carefully!!
-
-## Platform.io lib/submodule (for framework=espidf)
-
-It's probably easier to just skip the platform.io library registry version and link the git repo as a submodule. (i.e. using code outside the platform.io library management). In this example we will install this as a submodule inside the platform.io $project/lib folder:
-```
-cd $project\lib
-git submodule add -b master https://github.com/espressif/esp32-camera.git
-```
-
-Then in `platformio.ini` file
-```
-build_flags =
- -I../lib/esp32-camera
-```
-After that `#include "esp_camera.h"` statement will be available. Now the module is included, and you're hopefully back to the same place as the easy-Arduino way.
-
-**Warning about platform.io/espidf and fresh (not initialized) git repos**
-There is a sharp-edge on you'll discover in the platform.io build process (in espidf v3.3 & 4.0.1) where a project which has only had `git init` but nothing committed will crash platform.io build process with highly non-useful output. The cause is due to lack of a version (making you think you did something wrong, when you didn't at all) - the output is horribly non-descript. Solution: the devs want you to create a file called version.txt with a number in it, or simply commit any file to the projects git repo and use git. This happens because platform.io build process tries to be too clever and determine the build version number from the git repo - it's a sharp edge you'll only encounter if you're experimenting on a new project with no commits .. like wtf is my camera not working let's try a 'clean project'?!
-
-## Platform.io Kconfig
-Kconfig is used by the platform.io menuconfig (accessed by running: `pio run -t menuconfig`) to interactively manage the various #ifdef statements throughout the espidf and supporting libraries (i.e. this repo: esp32-camera and arduino-esp32.git). The menuconfig process generates the `sdkconfig` file which is ultimately used behind the scenes by espidf compile+build process.
-
-**Make sure to append or symlink** [this `Kconfig`](./Kconfig) content into the `Kconfig` of your project.
-
-You symlink (or copy) the included Kconfig into your platform.io projects src directory. The file should be named `Kconfig.projbuild` in your projects src\ directory or you could also add the library path to a CMakefile.txt and hope the `Kconfig` (or `Kconfig.projbuild`) gets discovered by the menuconfig process, though this unpredictable for me.
-
-The unpredictable wonky behavior in platform.io build process around Kconfig naming (Kconfig vs. Kconfig.projbuild) occurs between espidf versions 3.3 and 4.0 - but if you don't see "Camera configuration" in your `pio run -t menuconfig` then there is no point trying to test camera code (it may compile, but it probably won't work!) and it seems the platform.io devs (when they built their wrapper around the espidf menuconfig) didn't implement it properly. You've probably already figured out you can't use the espidf build tools since the files are in totally different locations and also different versions with sometimes different syntax. This is one of those times you might consider changing the `platformio.ini` from `platform=espressif32` to `platform=https://github.com/platformio/platform-espressif32.git#develop` to get a more recent version of the espidf 4.0 tools.
-
-However with a bit of patience and experimenting you'll figure the Kconfig out. Once Kconfig (or Kconfig.projbuild) is working then you will be able to choose the configurations according to your setup or the camera libraries will be compiled. Although you might also need to delete your .pio/build directory before the options appear .. again, the `pio run -t menuconfig` doens't always notice the new Kconfig files!
-
-If you miss-skip-ignore this critical step the camera module will compile but camera logic inside the library will be 'empty' because the Kconfig sets the proper #ifdef statements during the build process to initialize the selected cameras. It's very not optional!
-
-
-## Examples
-
-### Initialization
-
-```c
-#include "esp_camera.h"
-
-//WROVER-KIT PIN Map
-#define CAM_PIN_PWDN -1 //power down is not used
-#define CAM_PIN_RESET -1 //software reset will be performed
-#define CAM_PIN_XCLK 21
-#define CAM_PIN_SIOD 26
-#define CAM_PIN_SIOC 27
-
-#define CAM_PIN_D7 35
-#define CAM_PIN_D6 34
-#define CAM_PIN_D5 39
-#define CAM_PIN_D4 36
-#define CAM_PIN_D3 19
-#define CAM_PIN_D2 18
-#define CAM_PIN_D1 5
-#define CAM_PIN_D0 4
-#define CAM_PIN_VSYNC 25
-#define CAM_PIN_HREF 23
-#define CAM_PIN_PCLK 22
-
-static camera_config_t camera_config = {
- .pin_pwdn = CAM_PIN_PWDN,
- .pin_reset = CAM_PIN_RESET,
- .pin_xclk = CAM_PIN_XCLK,
- .pin_sscb_sda = CAM_PIN_SIOD,
- .pin_sscb_scl = CAM_PIN_SIOC,
-
- .pin_d7 = CAM_PIN_D7,
- .pin_d6 = CAM_PIN_D6,
- .pin_d5 = CAM_PIN_D5,
- .pin_d4 = CAM_PIN_D4,
- .pin_d3 = CAM_PIN_D3,
- .pin_d2 = CAM_PIN_D2,
- .pin_d1 = CAM_PIN_D1,
- .pin_d0 = CAM_PIN_D0,
- .pin_vsync = CAM_PIN_VSYNC,
- .pin_href = CAM_PIN_HREF,
- .pin_pclk = CAM_PIN_PCLK,
-
- .xclk_freq_hz = 20000000,//EXPERIMENTAL: Set to 16MHz on ESP32-S2 or ESP32-S3 to enable EDMA mode
- .ledc_timer = LEDC_TIMER_0,
- .ledc_channel = LEDC_CHANNEL_0,
-
- .pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG
- .frame_size = FRAMESIZE_UXGA,//QQVGA-QXGA Do not use sizes above QVGA when not JPEG
-
- .jpeg_quality = 12, //0-63 lower number means higher quality
- .fb_count = 1, //if more than one, i2s runs in continuous mode. Use only with JPEG
- .grab_mode = CAMERA_GRAB_WHEN_EMPTY//CAMERA_GRAB_LATEST. Sets when buffers should be filled
-};
-
-esp_err_t camera_init(){
- //power up the camera if PWDN pin is defined
- if(CAM_PIN_PWDN != -1){
- pinMode(CAM_PIN_PWDN, OUTPUT);
- digitalWrite(CAM_PIN_PWDN, LOW);
- }
-
- //initialize the camera
- esp_err_t err = esp_camera_init(&camera_config);
- if (err != ESP_OK) {
- ESP_LOGE(TAG, "Camera Init Failed");
- return err;
- }
-
- return ESP_OK;
-}
-
-esp_err_t camera_capture(){
- //acquire a frame
- camera_fb_t * fb = esp_camera_fb_get();
- if (!fb) {
- ESP_LOGE(TAG, "Camera Capture Failed");
- return ESP_FAIL;
- }
- //replace this with your own function
- process_image(fb->width, fb->height, fb->format, fb->buf, fb->len);
-
- //return the frame buffer back to the driver for reuse
- esp_camera_fb_return(fb);
- return ESP_OK;
-}
-```
-
-### JPEG HTTP Capture
-
-```c
-#include "esp_camera.h"
-#include "esp_http_server.h"
-#include "esp_timer.h"
-
-typedef struct {
- httpd_req_t *req;
- size_t len;
-} jpg_chunking_t;
-
-static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){
- jpg_chunking_t *j = (jpg_chunking_t *)arg;
- if(!index){
- j->len = 0;
- }
- if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){
- return 0;
- }
- j->len += len;
- return len;
-}
-
-esp_err_t jpg_httpd_handler(httpd_req_t *req){
- camera_fb_t * fb = NULL;
- esp_err_t res = ESP_OK;
- size_t fb_len = 0;
- int64_t fr_start = esp_timer_get_time();
-
- fb = esp_camera_fb_get();
- if (!fb) {
- ESP_LOGE(TAG, "Camera capture failed");
- httpd_resp_send_500(req);
- return ESP_FAIL;
- }
- res = httpd_resp_set_type(req, "image/jpeg");
- if(res == ESP_OK){
- res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
- }
-
- if(res == ESP_OK){
- if(fb->format == PIXFORMAT_JPEG){
- fb_len = fb->len;
- res = httpd_resp_send(req, (const char *)fb->buf, fb->len);
- } else {
- jpg_chunking_t jchunk = {req, 0};
- res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL;
- httpd_resp_send_chunk(req, NULL, 0);
- fb_len = jchunk.len;
- }
- }
- esp_camera_fb_return(fb);
- int64_t fr_end = esp_timer_get_time();
- ESP_LOGI(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000));
- return res;
-}
-```
-
-### JPEG HTTP Stream
-
-```c
-#include "esp_camera.h"
-#include "esp_http_server.h"
-#include "esp_timer.h"
-
-#define PART_BOUNDARY "123456789000000000000987654321"
-static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
-static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
-static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
-
-esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){
- camera_fb_t * fb = NULL;
- esp_err_t res = ESP_OK;
- size_t _jpg_buf_len;
- uint8_t * _jpg_buf;
- char * part_buf[64];
- static int64_t last_frame = 0;
- if(!last_frame) {
- last_frame = esp_timer_get_time();
- }
-
- res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
- if(res != ESP_OK){
- return res;
- }
-
- while(true){
- fb = esp_camera_fb_get();
- if (!fb) {
- ESP_LOGE(TAG, "Camera capture failed");
- res = ESP_FAIL;
- break;
- }
- if(fb->format != PIXFORMAT_JPEG){
- bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
- if(!jpeg_converted){
- ESP_LOGE(TAG, "JPEG compression failed");
- esp_camera_fb_return(fb);
- res = ESP_FAIL;
- }
- } else {
- _jpg_buf_len = fb->len;
- _jpg_buf = fb->buf;
- }
-
- if(res == ESP_OK){
- res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
- }
- if(res == ESP_OK){
- size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
-
- res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
- }
- if(res == ESP_OK){
- res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
- }
- if(fb->format != PIXFORMAT_JPEG){
- free(_jpg_buf);
- }
- esp_camera_fb_return(fb);
- if(res != ESP_OK){
- break;
- }
- int64_t fr_end = esp_timer_get_time();
- int64_t frame_time = fr_end - last_frame;
- last_frame = fr_end;
- frame_time /= 1000;
- ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)",
- (uint32_t)(_jpg_buf_len/1024),
- (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time);
- }
-
- last_frame = 0;
- return res;
-}
-```
-
-### BMP HTTP Capture
-
-```c
-#include "esp_camera.h"
-#include "esp_http_server.h"
-#include "esp_timer.h"
-
-esp_err_t bmp_httpd_handler(httpd_req_t *req){
- camera_fb_t * fb = NULL;
- esp_err_t res = ESP_OK;
- int64_t fr_start = esp_timer_get_time();
-
- fb = esp_camera_fb_get();
- if (!fb) {
- ESP_LOGE(TAG, "Camera capture failed");
- httpd_resp_send_500(req);
- return ESP_FAIL;
- }
-
- uint8_t * buf = NULL;
- size_t buf_len = 0;
- bool converted = frame2bmp(fb, &buf, &buf_len);
- esp_camera_fb_return(fb);
- if(!converted){
- ESP_LOGE(TAG, "BMP conversion failed");
- httpd_resp_send_500(req);
- return ESP_FAIL;
- }
-
- res = httpd_resp_set_type(req, "image/x-windows-bmp")
- || httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.bmp")
- || httpd_resp_send(req, (const char *)buf, buf_len);
- free(buf);
- int64_t fr_end = esp_timer_get_time();
- ESP_LOGI(TAG, "BMP: %uKB %ums", (uint32_t)(buf_len/1024), (uint32_t)((fr_end - fr_start)/1000));
- return res;
-}
-```
-
-
-
diff --git a/lib/libesp32/esp32-camera/driver/include/xclk.h b/lib/libesp32/esp32-camera/driver/include/xclk.h
deleted file mode 100644
index 3d721a613..000000000
--- a/lib/libesp32/esp32-camera/driver/include/xclk.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "esp_system.h"
-
-esp_err_t xclk_timer_conf(int ledc_timer, int xclk_freq_hz);
-
-esp_err_t camera_enable_out_clock();
-
-void camera_disable_out_clock();
diff --git a/lib/libesp32/esp32-camera/library.json b/lib/libesp32/esp32-camera/library.json
deleted file mode 100644
index bb542c0bf..000000000
--- a/lib/libesp32/esp32-camera/library.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "esp32-camera-header",
- "version": "1.0.0",
- "keywords": "esp32, camera, espressif, esp32-cam",
- "description": "ESP32 camera header files",
- "repository": {
- "type": "git",
- "url": "https://github.com/espressif/esp32-camera"
- },
- "frameworks": "arduino",
- "platforms": "espressif32",
- "build": {
- "flags": [
- "-Idriver/include"
- ],
- "includeDir": ".",
- "srcDir": ".",
- "srcFilter": ["-<*>", "+"]
- }
-}
diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini
index bb10ec1b1..12ebcf47f 100644
--- a/platformio_tasmota_cenv_sample.ini
+++ b/platformio_tasmota_cenv_sample.ini
@@ -50,7 +50,6 @@ lib_ignore = ESP8266Audio
TTGO TWatch Library
Micro-RTSP
epdiy
- esp32-camera
[env:tasmota32c3-mi32-homebridge]
extends = env:tasmota32c3
@@ -64,7 +63,6 @@ lib_ignore = ESP8266Audio
TTGO TWatch Library
Micro-RTSP
epdiy
- esp32-camera
[env:tasmota32s3-mi32-homebridge]
extends = env:tasmota32s3
@@ -78,7 +76,6 @@ lib_ignore = ESP8266Audio
TTGO TWatch Library
Micro-RTSP
epdiy
- esp32-camera
; *** Debug version used for PlatformIO Home Project Inspection
[env:tasmota-debug]
From 970f85037b62fe2f523370ed29d093f14ad31bc3 Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Tue, 18 Oct 2022 19:27:24 +0200
Subject: [PATCH 030/319] add webcam widget to dashboard
---
tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
index 035e5a354..145ce7dc4 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
@@ -1910,6 +1910,14 @@ void MI32sendEnergyWidget(){
}
}
#endif //USE_MI_ESP32_ENERGY
+#ifdef USE_WEBCAM
+void MI32sendCamWidget(){
+ if (Wc.CamServer && Wc.up) {
+ WSContentSend_P(PSTR("
"),
+ (uint32_t)WiFi.localIP());
+ }
+}
+#endif //USE_WEBCAM
void MI32sendWidget(uint32_t slot){
auto _sensor = MIBLEsensors[slot];
@@ -2044,6 +2052,9 @@ void MI32InitGUI(void){
#ifdef USE_MI_ESP32_ENERGY
MI32sendEnergyWidget();
#endif //USE_MI_ESP32_ENERGY
+#ifdef USE_WEBCAM
+ MI32sendCamWidget();
+#endif //USE_WEBCAM
WSContentSend_P(PSTR(""));
WSContentSpaceButton(BUTTON_MAIN);
WSContentStop();
From 753f4bee31eb8601e7fa635d746f8b986345fa1e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 19 Oct 2022 10:21:31 +0200
Subject: [PATCH 031/319] Change compiling with reduced boards manifests
Change compiling with reduced boards manifests in favour of Autoconfig (#16848)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
2 files changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2bd97b23a..e79f335eb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
+- Compiling with reduced boards manifests in favour of Autoconfig (#16848)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a0ca79df2..c377bd73d 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -115,6 +115,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
+- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
From 100e95f2cf6fcc8e983e0919c4c81a13206b0566 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 19 Oct 2022 10:44:08 +0200
Subject: [PATCH 032/319] Update xdrv_02_9_mqtt.ino
---
.../tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
index 1d328d447..a4b8b08e2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
@@ -522,11 +522,30 @@ bool MqttPublishLib(const char* topic, const uint8_t* payload, unsigned int plen
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Connection lost or message too large"));
return false;
}
+
uint32_t written = MqttClient.write(payload, plength);
if (written != plength) {
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Message too large"));
return false;
}
+/*
+ // Solves #6525??
+ const uint8_t* write_buf = payload;
+ uint32_t bytes_remaining = plength;
+ uint32_t bytes_to_write;
+ uint32_t written;
+ while (bytes_remaining > 0) {
+ bytes_to_write = (bytes_remaining > 256) ? 256 : bytes_remaining;
+ written = MqttClient.write(write_buf, bytes_to_write);
+ if (written != bytes_to_write) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Message too large"));
+ return false;
+ }
+ write_buf += written;
+ bytes_remaining -= written;
+ }
+*/
+
MqttClient.endPublish();
yield(); // #3313
From 1e2f2385b89dd6fcd5fc193bc4aab1939cae3e09 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sat, 9 Apr 2022 18:33:45 +0200
Subject: [PATCH 033/319] Add filtration toggle
---
tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
index e2171bcfb..09e71b77c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
@@ -732,8 +732,11 @@ const char HTTP_SNS_NEOPOOL_STATUS_ACTIVE[] PROGMEM = "filter:invert(1)";
* Commands
*
* NPFiltration { {speed}}
- * get/set manual filtration (state = 0|1, speed = 1..3)
+ * get/set manual filtration (state = 0..2, speed = 1..3)
* get filtration state if is omitted, otherwise set new state
+ * 0 - switch filtration pump off
+ * 1 - switch filtration pump on
+ * 2 - toggle filtration pump
* for non-standard filtration types additional speed control is possible
*
* NPFiltrationMode {}
@@ -2129,12 +2132,19 @@ void CmndNeopoolFiltration(void)
return;
}
}
- if (value[0] >= 0 && value[0] <= 1) {
+ if (value[0] >= 0 && value[0] <= 2) {
// Set MBF_PAR_FILT_MODE
if (NEOPOOL_MODBUS_OK != NeoPoolWriteRegisterWord(MBF_PAR_FILT_MODE, MBV_PAR_FILT_MANUAL)) {
NeopoolResponseError();
return;
}
+ if (2 == value[0]) {
+ if (NEOPOOL_MODBUS_OK != NeoPoolReadRegister(MBF_PAR_FILTRATION_STATE, &data, 1)) {
+ NeopoolResponseError();
+ return;
+ }
+ value[0] = data ? 0 : 1;
+ }
// Set filtration mode to manual
if (NEOPOOL_MODBUS_OK != NeoPoolWriteRegisterWord(MBF_PAR_FILT_MANUAL_STATE, value[0])) {
NeopoolResponseError();
From 720b3f7c9b27b4b688c94330ecd4c491a321bfd0 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Tue, 12 Apr 2022 08:36:02 +0200
Subject: [PATCH 034/319] Change json unlocalized
---
.../tasmota_xsns_sensor/xsns_83_neopool.ino | 103 ++++++++++--------
1 file changed, 59 insertions(+), 44 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
index 09e71b77c..93c67abbb 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
@@ -654,6 +654,55 @@ NeoPoolResMBitfield neopool_resolution {
#define D_NEOPOOL_NAME "NeoPool"
+#define D_NEOPOOL_JSON_FILTRATION_NONE ""
+#define D_NEOPOOL_JSON_FILTRATION_MANUAL "Manual"
+#define D_NEOPOOL_JSON_FILTRATION_AUTO "Auto"
+#define D_NEOPOOL_JSON_FILTRATION_HEATING "Heating"
+#define D_NEOPOOL_JSON_FILTRATION_SMART "Smart"
+#define D_NEOPOOL_JSON_FILTRATION_INTELLIGENT "Intelligent"
+#define D_NEOPOOL_JSON_FILTRATION_BACKWASH "Backwash"
+#define D_NEOPOOL_JSON_MODULES "Modules"
+#define D_NEOPOOL_JSON_CHLORINE "Chlorine"
+#define D_NEOPOOL_JSON_CONDUCTIVITY "Conductivity"
+#define D_NEOPOOL_JSON_FILTRATION "Filtration"
+#define D_NEOPOOL_JSON_FILTRATION_MODE "Mode"
+#define D_NEOPOOL_JSON_FILTRATION_SPEED "Speed"
+#define D_NEOPOOL_JSON_HYDROLYSIS "Hydrolysis"
+#define D_NEOPOOL_JSON_CELL_RUNTIME "Runtime"
+#define D_NEOPOOL_JSON_CELL_RUNTIME_TOTAL "Total"
+#define D_NEOPOOL_JSON_CELL_RUNTIME_PART "Part"
+#define D_NEOPOOL_JSON_CELL_RUNTIME_POL1 "Pol1"
+#define D_NEOPOOL_JSON_CELL_RUNTIME_POL2 "Pol2"
+#define D_NEOPOOL_JSON_CELL_RUNTIME_CHANGES "Changes"
+#define D_NEOPOOL_JSON_IONIZATION "Ionization"
+#define D_NEOPOOL_JSON_LIGHT "Light"
+#define D_NEOPOOL_JSON_LIGHT_MODE "Mode"
+#define D_NEOPOOL_JSON_REDOX "Redox"
+#define D_NEOPOOL_JSON_RELAY "Relay"
+#define D_NEOPOOL_JSON_RELAY_PH_ACID "Acid"
+#define D_NEOPOOL_JSON_RELAY_PH_BASE "Base"
+#define D_NEOPOOL_JSON_RELAY_RX "Redox"
+#define D_NEOPOOL_JSON_RELAY_CL "Chlorine"
+#define D_NEOPOOL_JSON_RELAY_CD "Conductivity"
+#define D_NEOPOOL_JSON_RELAY_HEATING "Heating"
+#define D_NEOPOOL_JSON_RELAY_UV "UV"
+#define D_NEOPOOL_JSON_RELAY_FILTVALVE "Valve"
+#define D_NEOPOOL_JSON_AUX "Aux"
+#define D_NEOPOOL_JSON_STATE "State"
+#define D_NEOPOOL_JSON_TYPE "Type"
+#define D_NEOPOOL_JSON_UNIT "Unit"
+#define D_NEOPOOL_JSON_COVER "Cover"
+#define D_NEOPOOL_JSON_SHOCK "Boost"
+#define D_NEOPOOL_JSON_LOW "Low"
+#define D_NEOPOOL_JSON_SETPOINT "Setpoint"
+#define D_NEOPOOL_JSON_MIN "Min"
+#define D_NEOPOOL_JSON_MAX "Max"
+#define D_NEOPOOL_JSON_PHPUMP "Pump"
+#define D_NEOPOOL_JSON_FLOW1 "FL1"
+#define D_NEOPOOL_JSON_TANK "Tank"
+#define D_NEOPOOL_JSON_BIT "Bit"
+#define D_NEOPOOL_JSON_NODE_ID "NodeID"
+
const char kNeoPoolMachineNames[] PROGMEM =
D_NEOPOOL_MACH_NONE "|"
D_NEOPOOL_MACH_HIDROLIFE "|"
@@ -677,6 +726,14 @@ const char kNeoPoolFiltrationMode[] PROGMEM =
D_NEOPOOL_FILTRATION_INTELLIGENT "|"
D_NEOPOOL_FILTRATION_BACKWASH
;
+const char kNeoPoolFiltrationModeCmnd[] PROGMEM =
+ D_NEOPOOL_JSON_FILTRATION_MANUAL "|"
+ D_NEOPOOL_JSON_FILTRATION_AUTO "|"
+ D_NEOPOOL_JSON_FILTRATION_HEATING "|"
+ D_NEOPOOL_JSON_FILTRATION_SMART "|"
+ D_NEOPOOL_JSON_FILTRATION_INTELLIGENT "|"
+ D_NEOPOOL_JSON_FILTRATION_BACKWASH
+ ;
const uint8_t sNeoPoolFiltrationMode[] PROGMEM = {
MBV_PAR_FILT_MANUAL,
MBV_PAR_FILT_AUTO,
@@ -1420,48 +1477,6 @@ bool NeoPoolIsIonization(void)
/*********************************************************************************************/
-#define D_NEOPOOL_JSON_MODULES "Modules"
-#define D_NEOPOOL_JSON_CHLORINE "Chlorine"
-#define D_NEOPOOL_JSON_CONDUCTIVITY "Conductivity"
-#define D_NEOPOOL_JSON_FILTRATION "Filtration"
-#define D_NEOPOOL_JSON_FILTRATION_MODE "Mode"
-#define D_NEOPOOL_JSON_FILTRATION_SPEED "Speed"
-#define D_NEOPOOL_JSON_HYDROLYSIS "Hydrolysis"
-#define D_NEOPOOL_JSON_CELL_RUNTIME "Runtime"
-#define D_NEOPOOL_JSON_CELL_RUNTIME_TOTAL "Total"
-#define D_NEOPOOL_JSON_CELL_RUNTIME_PART "Part"
-#define D_NEOPOOL_JSON_CELL_RUNTIME_POL1 "Pol1"
-#define D_NEOPOOL_JSON_CELL_RUNTIME_POL2 "Pol2"
-#define D_NEOPOOL_JSON_CELL_RUNTIME_CHANGES "Changes"
-#define D_NEOPOOL_JSON_IONIZATION "Ionization"
-#define D_NEOPOOL_JSON_LIGHT "Light"
-#define D_NEOPOOL_JSON_LIGHT_MODE "Mode"
-#define D_NEOPOOL_JSON_REDOX "Redox"
-#define D_NEOPOOL_JSON_RELAY "Relay"
-#define D_NEOPOOL_JSON_RELAY_PH_ACID "Acid"
-#define D_NEOPOOL_JSON_RELAY_PH_BASE "Base"
-#define D_NEOPOOL_JSON_RELAY_RX "Redox"
-#define D_NEOPOOL_JSON_RELAY_CL "Chlorine"
-#define D_NEOPOOL_JSON_RELAY_CD "Conductivity"
-#define D_NEOPOOL_JSON_RELAY_HEATING "Heating"
-#define D_NEOPOOL_JSON_RELAY_UV "UV"
-#define D_NEOPOOL_JSON_RELAY_FILTVALVE "Valve"
-#define D_NEOPOOL_JSON_AUX "Aux"
-#define D_NEOPOOL_JSON_STATE "State"
-#define D_NEOPOOL_JSON_TYPE "Type"
-#define D_NEOPOOL_JSON_UNIT "Unit"
-#define D_NEOPOOL_JSON_COVER "Cover"
-#define D_NEOPOOL_JSON_SHOCK "Boost"
-#define D_NEOPOOL_JSON_LOW "Low"
-#define D_NEOPOOL_JSON_SETPOINT "Setpoint"
-#define D_NEOPOOL_JSON_MIN "Min"
-#define D_NEOPOOL_JSON_MAX "Max"
-#define D_NEOPOOL_JSON_PHPUMP "Pump"
-#define D_NEOPOOL_JSON_FLOW1 "FL1"
-#define D_NEOPOOL_JSON_TANK "Tank"
-#define D_NEOPOOL_JSON_BIT "Bit"
-#define D_NEOPOOL_JSON_NODE_ID "NodeID"
-
void NeoPoolAppendModules(void)
{
ResponseAppend_P(PSTR("\"" D_NEOPOOL_JSON_MODULES "\":"));
@@ -2179,7 +2194,7 @@ void CmndNeopoolFiltrationMode(void)
if (XdrvMailbox.data_len) {
char command[CMDSZ];
- int mode = GetCommandCode(command, sizeof(command), XdrvMailbox.data, kNeoPoolFiltrationMode);
+ int mode = GetCommandCode(command, sizeof(command), XdrvMailbox.data, kNeoPoolFiltrationModeCmnd);
if (mode >= 0) {
XdrvMailbox.payload = pgm_read_byte(sNeoPoolFiltrationMode + mode);
}
@@ -2199,7 +2214,7 @@ void CmndNeopoolFiltrationMode(void)
NeopoolResponseError();
return;
}
- ResponseCmndChar(GetTextIndexed(stemp, sizeof(stemp), data < MBV_PAR_FILT_INTELLIGENT ? data : nitems(kNeoPoolFiltrationMode)-1, kNeoPoolFiltrationMode));
+ ResponseCmndChar(GetTextIndexed(stemp, sizeof(stemp), data < MBV_PAR_FILT_INTELLIGENT ? data : nitems(kNeoPoolFiltrationModeCmnd)-1, kNeoPoolFiltrationMode));
}
From 3fb19a633afa4806509fb28a7d704953cc8b9796 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Tue, 12 Apr 2022 10:30:22 +0200
Subject: [PATCH 035/319] Rework register const
---
.../tasmota_xsns_sensor/xsns_83_neopool.ino | 47 +++++++------------
1 file changed, 18 insertions(+), 29 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
index 93c67abbb..b06b6bb1e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
@@ -117,7 +117,7 @@ enum NeoPoolRegister {
MBF_CELL_RUNTIME_HIGH, // 0x0207* undocumented - cell runtime (32 bit) - high word
MBF_CELL_RUNTIME_PART_LOW, // 0x0208* undocumented - cell part runtime (32 bit) - low word
MBF_CELL_RUNTIME_PART_HIGH, // 0x0209* undocumented - cell part runtime (32 bit) - high word
- MBF_CELL_BOOST = 0x020C, // 0x020C* undocumented - 0x0000 = Boost Off, 0x05A0 = Boost with redox ctrl, 0x85A0 = Boost without redox ctrl
+ MBF_CELL_BOOST = 0x020C, // 0x020C* mask undocumented - 0x0000 = Boost Off, 0x05A0 = Boost with redox ctrl, 0x85A0 = Boost without redox ctrl
MBF_CELL_RUNTIME_POLA_LOW = 0x0214, // 0x0214* undocumented - cell runtime polarity A (32 bit) - low word
MBF_CELL_RUNTIME_POLA_HIGH, // 0x0215* undocumented - cell runtime polarity A (32 bit) - high word
MBF_CELL_RUNTIME_POLB_LOW, // 0x0216* undocumented - cell runtime polarity B (32 bit) - low word
@@ -278,28 +278,12 @@ enum NeoPoolConstAndBitMask {
MBMSK_PH_STATUS_ALARM = 0x000F, // PH alarm. The possible alarm values are depending on the regulation model:
// Valid alarm values for pH regulation with acid and base:
MBV_PH_ACID_BASE_ALARM0 = 0, // no alarm
- MBV_PH_ACID_BASE_ALARM1 = 1, // pH too high; the pH value is 0.8 points higher than the setpoint value set in PH1
- MBV_PH_ACID_BASE_ALARM2 = 2, // pH too low: the pH value is 0.8 points lower than the set point value set in PH2
- MBV_PH_ACID_BASE_ALARM3 = 3, // pH pump (acid or base, it does not matter) has exceeded the working time set by the MBF_PAR_RELAY_PH_MAX_TIME parameter and has stopped.
- MBV_PH_ACID_BASE_ALARM4 = 4, // pH higher than the set point indicated in PH1
- MBV_PH_ACID_BASE_ALARM5 = 5, // pH lower than the set point indicated in PH2
- MBV_PH_ACID_BASE_ALARM6 = 6, // undocumented - acid tank level alarm
- // Valid alarm values for pH regulation with acid only:
- MBV_PH_ACID_ALARM0 = 0, // no alarm
- MBV_PH_ACID_ALARM1 = 1, // pH too high; the pH value is 0.8 points higher than the setpoint value set in PH1
- MBV_PH_ACID_ALARM2 = 2, // pH too low: the pH value is 0.8 points lower than the setpoint value set in PH1
- MBV_PH_ACID_ALARM3 = 3, // pH pump acid has exceeded the working time set by the MBF_PAR_RELAY_PH_MAX_TIME parameter and has stopped.
- MBV_PH_ACID_ALARM4 = 4, // pH higher than the setpoint indicated in PH1 by 0.1
- MBV_PH_ACID_ALARM5 = 5, // pH lower than the set point indicated in PH1 by 0.3
- MBV_PH_ACID_ALARM6 = 6, // undocumented - acid tank level alarm
- // Valid alarm values for pH regulation with base only:
- MBV_PH_BASE_ALARM0 = 0, // no alarm
- MBV_PH_BASE_ALARM1 = 1, // pH too high; the pH value is 0.8 points higher than the set point value set in PH2
- MBV_PH_BASE_ALARM2 = 2, // pH too low: the pH value is 0.8 points lower than the set point value set in PH2
- MBV_PH_BASE_ALARM3 = 3, // pH pump has exceeded the working time set by the MBF_PAR_RELAY_PH_MAX_TIME parameter and has stopped.
- MBV_PH_BASE_ALARM4 = 4, // pH higher than the set point indicated in PH2 by 0.1
- MBV_PH_BASE_ALARM5 = 5, // pH lower than the set point indicated in PH2 by 0.3
- MBV_PH_BASE_ALARM6 = 6, // undocumented - acid tank level alarm
+ MBV_PH_ACID_BASE_ALARM1 = 1, // pH too high; the pH value is 0.8 points higher than the setpoint (PH1 on acid systems, PH2 on base systems, PH1 on acid+base systems)
+ MBV_PH_ACID_BASE_ALARM2 = 2, // pH too low: the pH value is 0.8 points lower than the set point value set in (PH1 on acid systems, PH2 on base systems, PH2 on acid+base systems)
+ MBV_PH_ACID_BASE_ALARM3 = 3, // pH pump has exceeded the working time set by the MBF_PAR_RELAY_PH_MAX_TIME parameter and has stopped.
+ MBV_PH_ACID_BASE_ALARM4 = 4, // pH higher than the set point (PH1 + 0.1 on acid systems, PH2 + 0.1 on base systems, PH1 on acid+base systems)
+ MBV_PH_ACID_BASE_ALARM5 = 5, // pH lower than the set point (PH1 - 0.3 on acid systems, PH2 - 0.3 on base systems, PH2 on acid+base systems)
+ MBV_PH_ACID_BASE_ALARM6 = 6, // undocumented - tank level alarm
MBMSK_PH_STATUS_CTRL_BY_FL = 0x0400, // 10 Control status of the pH module by flow detection (if enabled by MBF_PAR_HIDRO_ION_CAUDAL)
MBMSK_PH_STATUS_ACID_PUMP_ACTIVE = 0x0800, // 11 Acid pH pump relay on (pump on)
@@ -374,6 +358,11 @@ enum NeoPoolConstAndBitMask {
MBMSK_NOTIF_USER_CHANGED = 0x0010, // 4 User page changed
MBMSK_NOTIF_MISC_CHANGED = 0x0020, // 5 Misc page changed
+ // MBF_CELL_BOOST
+ MBMSK_CELL_BOOST_REDOX_CTL = 0x8000, // undocumented - Disable redox ctrl
+ MBMSK_CELL_BOOST_STATE = 0x0500, // undocumented - Boost
+ MBMSK_CELL_BOOST_START = 0x00A0, // undocumented - Start boost
+
// MBF_PAR_MODEL
MBMSK_MODEL_ION = 0x0001, // 0 The equipment includes ionization control
MBMSK_MODEL_HIDRO = 0x0002, // 1 The equipment includes hydrolysis or electrolysis
@@ -1658,7 +1647,7 @@ void NeoPoolShow(bool json)
// S2
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_COVER "\":%d"), (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_COVER) ? 1 : 0 );
// S3
- ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_SHOCK "\":%d"), (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED) ? ((NeoPoolGetData(MBF_CELL_BOOST) & 0x8000) ? 1 : 2) : 0 );
+ ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_SHOCK "\":%d"), (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED) ? ((NeoPoolGetData(MBF_CELL_BOOST) & MBMSK_CELL_BOOST_REDOX_CTL) ? 1 : 2) : 0 );
// S4
ResponseAppend_P(PSTR(",\"" D_NEOPOOL_JSON_LOW "\":%d"), (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_LOW) ? 1 : 0 );
@@ -1782,7 +1771,7 @@ void NeoPoolShow(bool json)
WSContentSend_PD(PSTR(" "));
// S3
if (NeoPoolGetData(MBF_HIDRO_STATUS) & MBMSK_HIDRO_STATUS_SHOCK_ENABLED) {
- if ((NeoPoolGetData(MBF_CELL_BOOST) & 0x8000) == 0) {
+ if ((NeoPoolGetData(MBF_CELL_BOOST) & MBMSK_CELL_BOOST_REDOX_CTL) == 0) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_SHOCK "+" D_NEOPOOL_REDOX));
} else {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_SHOCK));
@@ -1825,7 +1814,7 @@ void NeoPoolShow(bool json)
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_STATUS_TANK));
} else if (NeoPoolGetData(MBF_PH_STATUS) & (MBMSK_PH_STATUS_ACID_PUMP_ACTIVE | MBMSK_PH_STATUS_BASE_PUMP_ACTIVE)) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_ACTIVE, PSTR(D_NEOPOOL_STATUS_ON));
- } else if (MBV_PH_ACID_ALARM0 != (NeoPoolGetData(MBF_PH_STATUS) & MBMSK_PH_STATUS_ALARM)) {
+ } else if (MBV_PH_ACID_BASE_ALARM0 != (NeoPoolGetData(MBF_PH_STATUS) & MBMSK_PH_STATUS_ALARM)) {
WSContentSend_PD(HTTP_SNS_NEOPOOL_STATUS, bg_color, HTTP_SNS_NEOPOOL_STATUS_NORMAL, PSTR(D_NEOPOOL_STATUS_WAIT));
}
} else {
@@ -1870,9 +1859,9 @@ void NeoPoolShow(bool json)
// Ionization
if (NeoPoolIsIonization()) {
char spol[100];
- snprintf_P(spol, sizeof(spol), PSTR(" " D_NEOPOOL_POLARIZATION "%d"), (NeoPoolGetData(MBF_ION_STATUS) & 0x6000) >> 13);
+ snprintf_P(spol, sizeof(spol), PSTR(" " D_NEOPOOL_POLARIZATION "%d"), (NeoPoolGetData(MBF_ION_STATUS) & (MBMSK_ION_STATUS_POL1 | MBMSK_ION_STATUS_POL2)) >> 13);
snprintf_P(stemp, sizeof(stemp), PSTR("%s%s%s"),
- (NeoPoolGetData(MBF_ION_STATUS) & 0x6000) >> 13 ? spol : PSTR(""),
+ (NeoPoolGetData(MBF_ION_STATUS) & (MBMSK_ION_STATUS_POL1 | MBMSK_ION_STATUS_POL2)) ? spol : PSTR(""),
NeoPoolGetData(MBF_ION_STATUS) & MBMSK_ION_STATUS_ON_TARGET ? PSTR(" " D_NEOPOOL_SETPOINT_OK) : PSTR(""),
NeoPoolGetData(MBF_ION_STATUS) & MBMSK_ION_STATUS_PROGTIME_EXCEEDED ? PSTR(" " D_NEOPOOL_PR_OFF) : PSTR("")
);
@@ -1880,7 +1869,7 @@ void NeoPoolShow(bool json)
WSContentSend_PD(HTTP_SNS_NEOPOOL_IONIZATION, neopool_type,
neopool_resolution.ion, &fvalue,
stemp,
- NeoPoolGetData(MBF_ION_STATUS)&0x0002?PSTR(" " D_NEOPOOL_LOW):PSTR("")
+ NeoPoolGetData(MBF_ION_STATUS) & MBMSK_ION_STATUS_LOW ? PSTR(" " D_NEOPOOL_LOW) : PSTR("")
);
}
From 2fa0a6edf35b84e33fcd52000c9a3901b1b89f39 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Tue, 19 Jul 2022 16:57:49 +0200
Subject: [PATCH 036/319] Add MBV_TIMER_OFFMB_TIMER_ENABLE countdown keys
---
tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
index b06b6bb1e..c4acec94a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
@@ -501,7 +501,9 @@ enum NeoPoolConstAndBitMask {
MBV_PAR_CTIMER_ENABLED_LINKED = 2, // Timer enabled and linked to relay from timer 0
MBV_PAR_CTIMER_ALWAYS_ON = 3, // Relay assigned to this timer always on
MBV_PAR_CTIMER_ALWAYS_OFF = 4, // Relay assigned to this timer always off
- MBV_PAR_CTIMER_COUNTDOWN = 5, // Timer in countdown mode
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_PLUS = 0x0105, // Timer in countdown mode using + key
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_MINUS = 0x0205, // Timer in countdown mode using - key
+
// MBV_TIMER_OFFMB_TIMER_FUNCTION codes:
MBV_PAR_CTIMER_FCT_FILTRATION = 0x0001, // Filtration function of the system
MBV_PAR_CTIMER_FCT_LIGHTING = 0x0002, // Lighting function of the system
From b4dfd87912745909fe7ceb3943b53f6bf03a06de Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 9 Oct 2022 15:34:22 +0200
Subject: [PATCH 037/319] Update NeoPool register desc
---
.../tasmota_xsns_sensor/xsns_83_neopool.ino | 25 +++++++++++++------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
index c4acec94a..6865f38cb 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
@@ -126,7 +126,9 @@ enum NeoPoolRegister {
MBF_CELL_RUNTIME_POL_CHANGES_HIGH, // 0x0219* undocumented - cell runtime polarity changes (32 bit) - high word
MBF_HIDRO_MODULE_VERSION = 0x0280, // 0x0280 undocumented - Hydrolysis module version
MBF_HIDRO_MODULE_CONNECTIVITY = 0x0281, // 0x0281 undocumented - Hydrolysis module connection quality (in myriad: 0..10000)
- MBF_SET_MANUAL_CTRL = 0x0289, // 0x0289 undocumented - write a 1 before manual control MBF_RELAY_STATE, after done write 0 and do MBF_EXEC
+ MBF_SET_COUNTDOWN_KEY_AUX_OFF = 0x0287, // 0x0287 mask undocumented - switch AUX1-4 OFF - only for AUX which is assigned as AUX and set to MBV_PAR_CTIMER_COUNTDOWN_KEY_* mode - see MBV_PAR_CTIMER_COUNTDOWN_KEY_AUX*
+ MBF_SET_COUNTDOWN_KEY_AUX_ON, // 0x0288 mask undocumented - switch AUX1-4 ON - only for AUX which is assigned as AUX and set to MBV_PAR_CTIMER_COUNTDOWN_KEY_* mode - see MBV_PAR_CTIMER_COUNTDOWN_KEY_AUX*
+ MBF_SET_MANUAL_CTRL, // 0x0289 undocumented - write a 1 before manual control MBF_RELAY_STATE, after done write 0 and do MBF_EXEC
MBF_ESCAPE = 0x0297, // 0x0297 undocumented - A write operation to this register is the same as using the ESC button on main screen - clears error
MBF_SAVE_TO_EEPROM = 0x02F0, // 0x02F0 A write operation to this register starts a EEPROM storage operation immediately. During the EEPROM storage procedure, the system may be unresponsive to MODBUS requests. The operation will last always less than 1 second.
MBF_EXEC = 0x02F5, // 0x02F5 undocumented - immediately take over settings - a write operation to this register take over the previous written data
@@ -503,18 +505,25 @@ enum NeoPoolConstAndBitMask {
MBV_PAR_CTIMER_ALWAYS_OFF = 4, // Relay assigned to this timer always off
MBV_PAR_CTIMER_COUNTDOWN_KEY_PLUS = 0x0105, // Timer in countdown mode using + key
MBV_PAR_CTIMER_COUNTDOWN_KEY_MINUS = 0x0205, // Timer in countdown mode using - key
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_ARROWDOWN = 0x0405, // Timer in countdown mode using arrow-down key
+
+ // MBF_SET_COUNTDOWN_KEY_AUX_* mask:
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_AUX1 = 0x0100, // Aux1 ON/OFF, when MBV_TIMER_OFFMB_TIMER_ENABLE is set to MBV_PAR_CTIMER_COUNTDOWN_KEY_*
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_AUX2 = 0x0200, // Aux2 ON/OFF, when MBV_TIMER_OFFMB_TIMER_ENABLE is set to MBV_PAR_CTIMER_COUNTDOWN_KEY_*
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_AUX3 = 0x0400, // Aux3 ON/OFF, when MBV_TIMER_OFFMB_TIMER_ENABLE is set to MBV_PAR_CTIMER_COUNTDOWN_KEY_*
+ MBV_PAR_CTIMER_COUNTDOWN_KEY_AUX4 = 0x0800, // Aux4 ON/OFF, when MBV_TIMER_OFFMB_TIMER_ENABLE is set to MBV_PAR_CTIMER_COUNTDOWN_KEY_*
// MBV_TIMER_OFFMB_TIMER_FUNCTION codes:
MBV_PAR_CTIMER_FCT_FILTRATION = 0x0001, // Filtration function of the system
MBV_PAR_CTIMER_FCT_LIGHTING = 0x0002, // Lighting function of the system
MBV_PAR_CTIMER_FCT_HEATING = 0x0004, // Heating function of the system
- MBV_PAR_CTIMER_FCT_AUXREL1 = 0x0100, // Auxiliary function assigned to relay 1
- MBV_PAR_CTIMER_FCT_AUXREL2 = 0x0200, // Auxiliary function assigned to relay 2
- MBV_PAR_CTIMER_FCT_AUXREL3 = 0x0400, // Auxiliary function assigned to relay 3
- MBV_PAR_CTIMER_FCT_AUXREL4 = 0x0800, // Auxiliary function assigned to relay 4
- MBV_PAR_CTIMER_FCT_AUXREL5 = 0x1000, // Auxiliary function assigned to relay 5
- MBV_PAR_CTIMER_FCT_AUXREL6 = 0x2000, // Auxiliary function assigned to relay 6
- MBV_PAR_CTIMER_FCT_AUXREL7 = 0x4000, // Auxiliary function assigned to relay 7
+ MBV_PAR_CTIMER_FCT_AUXREL1 = 0x0100, // Function assigned to relay 1 (Filtration)
+ MBV_PAR_CTIMER_FCT_AUXREL2 = 0x0200, // Function assigned to relay 2 (Light)
+ MBV_PAR_CTIMER_FCT_AUXREL3 = 0x0400, // Function assigned to relay 3 (Heating)
+ MBV_PAR_CTIMER_FCT_AUXREL4 = 0x0800, // Function assigned to relay 4 (AUX1)
+ MBV_PAR_CTIMER_FCT_AUXREL5 = 0x1000, // Function assigned to relay 5 (AUX2)
+ MBV_PAR_CTIMER_FCT_AUXREL6 = 0x2000, // Function assigned to relay 6 (AUX3)
+ MBV_PAR_CTIMER_FCT_AUXREL7 = 0x4000, // Function assigned to relay 7 (AUX4)
// MBF_PAR_UICFG_SOUND
MBMSK_PAR_SOUND_CLICK = 0x0001, // 0 Click sounds every time a key is pressed
From bee7c0909862669b138afdba0bf2a31f6a988b08 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Wed, 19 Oct 2022 13:56:07 +0200
Subject: [PATCH 038/319] Update CHANGELOG.md
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e79f335eb..b0bd29541 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
- Compiling with reduced boards manifests in favour of Autoconfig (#16848)
+- Add NeoPool ``NPFiltration 2`` toggle cmnd (#16859)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
From 549e6d9c18926b76bcf67cfcd884085c15b9f5bd Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 21 Oct 2022 13:40:01 +0200
Subject: [PATCH 039/319] Add USE_SHIFT595 to tasmota32.bin
---
tasmota/include/tasmota_configurations_ESP32.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index e5bd679c9..d6a691003 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -706,6 +706,9 @@
#define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram)
#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code)
//#define USE_WIEGAND // Add support for 24/26/32/34 bit RFID Wiegand interface (D0/D1) (+1k7 code)
+#define USE_SHIFT595 // Add support for 74xx595 8-bit shift registers (+0k7 code)
+// #define SHIFT595_INVERT_OUTPUTS false // [SetOption133] Don't invert outputs of 74x595 shift register
+// #define SHIFT595_DEVICE_COUNT 1 // [Shift595DeviceCount] Set the number of connected 74x595 shift registers
#define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code)
#define USE_HX711 // Add support for HX711 load cell (+1k5 code)
//#define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code)
From 47456a54eeb4e2967af395db103b93800ce97509 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 21 Oct 2022 15:06:52 +0200
Subject: [PATCH 040/319] Prep ADE7953 using SPI
---
tasmota/include/tasmota_template.h | 13 ++++++++++---
tasmota/language/af_AF.h | 1 +
tasmota/language/bg_BG.h | 1 +
tasmota/language/ca_AD.h | 1 +
tasmota/language/cs_CZ.h | 1 +
tasmota/language/de_DE.h | 1 +
tasmota/language/el_GR.h | 1 +
tasmota/language/en_GB.h | 1 +
tasmota/language/es_ES.h | 1 +
tasmota/language/fr_FR.h | 1 +
tasmota/language/fy_NL.h | 1 +
tasmota/language/he_HE.h | 1 +
tasmota/language/hu_HU.h | 1 +
tasmota/language/it_IT.h | 1 +
tasmota/language/ko_KO.h | 1 +
tasmota/language/nl_NL.h | 1 +
tasmota/language/pl_PL.h | 1 +
tasmota/language/pt_BR.h | 1 +
tasmota/language/pt_PT.h | 1 +
tasmota/language/ro_RO.h | 1 +
tasmota/language/ru_RU.h | 1 +
tasmota/language/sk_SK.h | 1 +
tasmota/language/sv_SE.h | 1 +
tasmota/language/tr_TR.h | 1 +
tasmota/language/uk_UA.h | 1 +
tasmota/language/vi_VN.h | 1 +
tasmota/language/zh_CN.h | 1 +
tasmota/language/zh_TW.h | 1 +
28 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 34a1e9642..9fb8e8e87 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -197,6 +197,7 @@ enum UserSelectablePins {
GPIO_MBR_TX, GPIO_MBR_RX, // Modbus Bridge Serial interface
GPIO_ADE7953_RST, // ADE7953 Reset
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
+ GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -441,6 +442,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_MBR_TX "|" D_SENSOR_MBR_RX "|"
D_SENSOR_ADE7953_RST "|"
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
+ D_SENSOR_ADE7953_CS "|"
;
const char kSensorNamesFixed[] PROGMEM =
@@ -776,10 +778,15 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#if defined(USE_I2C) && defined(USE_ADE7880)
AGPIO(GPIO_ADE7880_IRQ) + 2, // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2)
#endif
-#if defined(USE_I2C) && defined(USE_ADE7953)
- AGPIO(GPIO_ADE7953_IRQ) + 3, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM)
+#ifdef USE_ADE7953
+#if defined(USE_I2C) || defined(USE_SPI)
+ AGPIO(GPIO_ADE7953_IRQ) + 5, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM)
AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset
-#endif
+#ifdef USE_SPI
+ AGPIO(GPIO_ADE7953_CS), // ADE7953 SPI Chip Select
+#endif // USE_SPI
+#endif // USE_I2C or USE_SPI
+#endif // USE_ADE7953
#ifdef USE_CSE7761
AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3)
AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3)
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 51431cb18..58b48a17a 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Gonser"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index a184ee348..968746cd4 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Зумер"
#define D_SENSOR_DISP_RESET "Нулиране дисплей"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index dc9e953c9..26bafafd8 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Brunzidor"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index f970244f0..2d32dcc9a 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 62237ae3d..05f940706 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index 8a93f5e95..d7cdbfe65 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index 2fdfd1a71..ea85e0861 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index d52cd714c..fa8dd2b67 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 9de3e227c..3364ff482 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "ZigBee TX"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 2054bd5f8..1e1a25927 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Zoemer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 81da7bfa0..4db4cc9ff 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index 368de4c26..d90312b00 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index fd2a0c33b..99301cc0e 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -764,6 +764,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 - IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 - IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 - RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 - CS"
#define D_SENSOR_BUZZER "Cicalino"
#define D_SENSOR_DISP_RESET "Display - RESET"
#define D_SENSOR_ZIGBEE_TXD "Zigbee - TX"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 669a803d9..5554f07a0 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 975f6da08..960a8fcf2 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Zoemer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 56b45c3a1..1157da535 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Dzwonek"
#define D_SENSOR_DISP_RESET "Reset Display"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index 6658540c7..fe96b16b8 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 45a9cf352..3607f8252 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 189b782f5..f51f0d07a 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 1e9bdb7cb..d45530605 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index d4e10bfd2..945bd72c1 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index f00257d5d..ffc3e2764 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index b33bbd15a..a19995a43 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index e499efe8c..8e832b9d8 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Зуммер"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index aae3a48f3..f87ba1029 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 884b26b63..348718091 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 66ffdd1aa..50c8c5dfb 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -766,6 +766,7 @@
#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ"
#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ"
#define D_SENSOR_ADE7953_RST "ADE7953 RST"
+#define D_SENSOR_ADE7953_CS "ADE7953 CS"
#define D_SENSOR_BUZZER "Buzzer"
#define D_SENSOR_DISP_RESET "Display Rst"
#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx"
From e347665148ef0c6d64f90416db0649ff1902950a Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 21 Oct 2022 15:10:21 +0200
Subject: [PATCH 041/319] Add 2 CSs
---
tasmota/include/tasmota_template.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 9fb8e8e87..d37ffd6a3 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -783,7 +783,7 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_ADE7953_IRQ) + 5, // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM)
AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset
#ifdef USE_SPI
- AGPIO(GPIO_ADE7953_CS), // ADE7953 SPI Chip Select
+ AGPIO(GPIO_ADE7953_CS) + 2, // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM))
#endif // USE_SPI
#endif // USE_I2C or USE_SPI
#endif // USE_ADE7953
From 90eb8e0c70ced1f91146fbaa64b36a1e4d4aab37 Mon Sep 17 00:00:00 2001
From: barbudor
Date: Fri, 21 Oct 2022 21:25:57 +0200
Subject: [PATCH 042/319] allow DHT_MAX_SENSORS to be overridden
---
tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino | 2 ++
tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino | 2 ++
tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino | 2 ++
3 files changed, 6 insertions(+)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino
index bfcda401e..62a7d84ae 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino
@@ -35,7 +35,9 @@
#define XSNS_06 6
+#ifndef DHT_MAX_SENSORS
#define DHT_MAX_SENSORS 4
+#endif
#define DHT_MAX_RETRY 8
uint8_t dht_data[5];
diff --git a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino
index 45f3c361a..a2bf67350 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino
@@ -26,7 +26,9 @@
#define XSNS_06 6
+#ifndef DHT_MAX_SENSORS
#define DHT_MAX_SENSORS 4
+#endif
#define DHT_MAX_RETRY 8
uint32_t dht_maxcycles;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino b/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino
index 66ee0f782..1472b7b53 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino
@@ -31,7 +31,9 @@
#define XSNS_06 6
+#ifndef DHT_MAX_SENSORS
#define DHT_MAX_SENSORS 4
+#endif
#define DHT_MAX_RETRY 8
#include
From a982c560dc3c26924c19a94b20238a3aea6f16fd Mon Sep 17 00:00:00 2001
From: Charles
Date: Sat, 22 Oct 2022 15:51:12 +0200
Subject: [PATCH 043/319] fix contract in standard mode
---
tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
index 86d74d9d4..d9ab9e85e 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
@@ -409,13 +409,22 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s'"), me->value);
}
- // Contract subscribed (Power)
- else if (ilabel == LABEL_ISOUSC || ilabel == LABEL_PREF)
+ // Contract subscribed (I Max)
+ else if (ilabel == LABEL_ISOUSC)
{
isousc = atoi( me->value);
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc);
}
+ // Contract subscribed (Power in KVA)
+ else if (ilabel == LABEL_PREF)
+ {
+ // Convert KVA to A
+ isousc = atoi( me->value) * 5 ;
+
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc);
+ }
+
// Serial Number of device
else if (ilabel == LABEL_ADCO || ilabel == LABEL_ADSC)
{
From cd44b262b820d4e3d8a7b7a980cbc43998f7d6e4 Mon Sep 17 00:00:00 2001
From: Charles
Date: Sat, 22 Oct 2022 16:04:47 +0200
Subject: [PATCH 044/319] fix current tariff display in standard mode
---
tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
index d9ab9e85e..04afe6af4 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
@@ -886,7 +886,7 @@ const char HTTP_ENERGY_ID_TELEINFO[] PROGMEM = "{s}ID{m}%s{e}" ;
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
//const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "%s{m}%d " D_UNIT_AMPERE "{e}" ;
-const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}Heures %s{e}" ;
+const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s%s{e}" ;
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}" D_CONTRACT "{m}%s %d" D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}" D_POWER_LOAD "{m}%d" D_UNIT_PERCENT "{e}" ;
const char HTTP_ENERGY_IMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d" D_UNIT_AMPERE "{e}" ;
@@ -976,7 +976,11 @@ void TInfoShow(bool json)
if (tarif) {
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, name);
+ if (tinfo_mode==TINFO_MODE_STANDARD ) {
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "", name);
+ } else {
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "Heures ", name);
+ }
}
if (contrat && isousc) {
int percent = (int) ((Energy.current[0]*100.0f) / isousc) ;
From 9192e529a673951a07357a986d68606962fddda8 Mon Sep 17 00:00:00 2001
From: Norbert <48217146+Noschvie@users.noreply.github.com>
Date: Sun, 23 Oct 2022 18:21:12 +0200
Subject: [PATCH 045/319] Fix typo
---
tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
index c4abc1154..33a3b81bc 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
@@ -104,7 +104,7 @@
*
* Restrictions:
* - Supports Modbus floating point registers
- * - Max number of uer defined registers is defined by one rule buffer (511 characters uncompressed, around 800 characters compressed)
+ * - Max number of user defined registers is defined by one rule buffer (511 characters uncompressed, around 800 characters compressed)
*
* To do:
* - Support all three rule slots
From 2692ef448682570f5c41befb414951d97b85f1e6 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 23 Oct 2022 18:47:04 +0200
Subject: [PATCH 046/319] Fix DisplayCalibrate
---
tasmota/berry/modules/DisplayCalibrate.tapp | Bin 12140 -> 12211 bytes
.../modules/ts_calibrate/ts_calibrate.be | 7 +++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/tasmota/berry/modules/DisplayCalibrate.tapp b/tasmota/berry/modules/DisplayCalibrate.tapp
index 7a8b80e7209e97f092b8672646ed2d9f95dd8ad3..0c75a7042306c0e26a3a1e2adc99217d0fc0affe 100644
GIT binary patch
delta 297
zcmaD8w>h3Sz?+$civa{Y=k-qHRTPTi4NuZaS)Wu|!Og(P@`I6qVWY!pMytZ9;i0@o
zW)+^*VPF7Zeg+walH&N}#GK5eqQsI^y`*3KnF}_)7RGlxd5S^MFi-!0B=SnIcA7EQCu=P
aQD0LNWG99ORyL5Qn1FB@klvsN;sF3m_Cloq
diff --git a/tasmota/berry/modules/ts_calibrate/ts_calibrate.be b/tasmota/berry/modules/ts_calibrate/ts_calibrate.be
index 8435c2199..04cddf69c 100644
--- a/tasmota/berry/modules/ts_calibrate/ts_calibrate.be
+++ b/tasmota/berry/modules/ts_calibrate/ts_calibrate.be
@@ -1,4 +1,7 @@
# TouchScreen calibration
+#
+# rm DisplayCalibrate.tapp; zip -j -0 DisplayCalibrate.tapp ts_calibrate/*
+#
var ts_calibrate = module("ts_calibrate")
ts_calibrate.init = def (m)
@@ -104,8 +107,8 @@ ts_calibrate.init = def (m)
end
# draw cross
- def draw_cross(x, y, size)
- var sz2 = size / 2
+ def draw_cross(x, y, sz)
+ var sz2 = sz / 2
self.p1.x = x - sz2
self.p1.y = y
self.p2.x = x + sz2
From 2ef866e3b82b66cbca231e5b7ba416e64b16a920 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 23 Oct 2022 19:43:40 +0200
Subject: [PATCH 047/319] Berry add `bytes().setbytes()`
---
CHANGELOG.md | 1 +
lib/libesp32/berry/src/be_byteslib.c | 46 ++++++++++++++++++++++++++++
lib/libesp32/berry/tests/bytes.be | 23 ++++++++++++++
3 files changed, 70 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0bd29541..6bb8656d7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
## [12.2.0.1]
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
+- Berry add `bytes().setbytes()`
### Breaking Changed
diff --git a/lib/libesp32/berry/src/be_byteslib.c b/lib/libesp32/berry/src/be_byteslib.c
index 299cc2fcd..b2dc9856a 100644
--- a/lib/libesp32/berry/src/be_byteslib.c
+++ b/lib/libesp32/berry/src/be_byteslib.c
@@ -949,6 +949,50 @@ static int m_setfloat(bvm *vm)
be_return_nil(vm);
}
+/*
+ * Fills a buffer with another buffer.
+ *
+ * This is meant to be very flexible and avoid loops
+ *
+ * `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
+ *
+ */
+#include
+static int m_setbytes(bvm *vm)
+{
+ int argc = be_top(vm);
+ buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
+ check_ptr(vm, &attr);
+ if (argc >=3 && be_isint(vm, 2) && (be_isbytes(vm, 3))) {
+ int32_t idx = be_toint(vm, 2);
+ size_t from_len_total;
+ const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
+ if (idx < 0) { idx = 0; }
+ if ((size_t)idx >= attr.len) { idx = attr.len; }
+
+ int32_t from_byte = 0;
+ if (argc >= 4 && be_isint(vm, 4)) {
+ from_byte = be_toint(vm, 4);
+ if (from_byte < 0) { from_byte = 0; }
+ if ((size_t)from_byte >= from_len_total) { from_byte = from_len_total; }
+ }
+
+ int32_t from_len = from_len_total - from_byte;
+ if (argc >= 5 && be_isint(vm, 5)) {
+ from_len = be_toint(vm, 5);
+ if (from_len < 0) { from_len = 0; }
+ if (from_len >= from_len_total) { from_len = from_len_total; }
+ }
+ if ((size_t) idx + (size_t)from_len >= attr.len) { from_len = attr.len - idx; }
+
+ // all parameters ok
+ if (from_len > 0) {
+ memmove(attr.bufptr + idx, buf_ptr + from_byte, from_len);
+ }
+ }
+ be_return_nil(vm);
+}
+
static int m_setitem(bvm *vm)
{
int argc = be_top(vm);
@@ -1575,6 +1619,7 @@ void be_load_byteslib(bvm *vm)
{ "geti", m_geti },
{ "set", m_set },
{ "seti", m_set }, // setters for signed and unsigned are identical
+ { "setbytes", m_setbytes },
{ "getfloat", m_getfloat },
{ "setfloat", m_setfloat },
{ "item", m_item },
@@ -1621,6 +1666,7 @@ class be_class_bytes (scope: global, name: bytes) {
setfloat, func(m_setfloat)
set, func(m_set)
seti, func(m_set)
+ setbytes, func(m_setbytes)
item, func(m_item)
setitem, func(m_setitem)
size, func(m_size)
diff --git a/lib/libesp32/berry/tests/bytes.be b/lib/libesp32/berry/tests/bytes.be
index d7b1bbdf8..44d3f56aa 100644
--- a/lib/libesp32/berry/tests/bytes.be
+++ b/lib/libesp32/berry/tests/bytes.be
@@ -202,3 +202,26 @@ assert(b == bytes())
b = bytes("FFFEAABBCC")
assert(b.tohex() == "FFFEAABBCC")
assert(bytes().tohex() == "")
+
+# assign buffer to bytes
+var a0 = bytes("112233445566778899")
+b = bytes("aabbccddeeff")
+
+a = a0.copy()
+a.setbytes(0, b) # assign from start
+assert(a == bytes('AABBCCDDEEFF778899'))
+a = a0.copy()
+a.setbytes(0, b, 0, 0) # zero len
+assert(a == a0)
+a = a0.copy()
+a.setbytes(100, b) # index out of range
+assert(a == a0)
+a = a0.copy()
+a.setbytes(6, b) # entire buffer not fitting
+assert(a == bytes('112233445566AABBCC'))
+a = a0.copy()
+a.setbytes(6, b, 2, 2)
+assert(a == bytes('112233445566CCDD99'))
+a = b.copy()
+a.setbytes(0, a0)
+assert(a == bytes('112233445566'))
From 646e2006ec1884e168364947cd11814a0fc9c1a8 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 24 Oct 2022 10:56:42 +0200
Subject: [PATCH 048/319] NimBLE v1.4.1
---
lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md | 19 +++++++++++++++++++
lib/libesp32_div/NimBLE-Arduino/docs/Doxyfile | 6 +++---
.../NimBLE-Arduino/library.properties | 2 +-
.../NimBLE-Arduino/src/NimBLEClient.cpp | 5 ++++-
.../NimBLE-Arduino/src/NimBLEDevice.cpp | 9 +++++++++
.../NimBLE-Arduino/src/NimBLEDevice.h | 4 +++-
.../NimBLE-Arduino/src/NimBLEHIDDevice.cpp | 6 +++---
.../NimBLE-Arduino/src/NimBLEHIDDevice.h | 2 +-
.../src/NimBLERemoteCharacteristic.cpp | 1 -
.../src/NimBLERemoteCharacteristic.h | 4 ++--
.../NimBLE-Arduino/src/NimBLEServer.h | 3 ++-
11 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md b/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md
index 5d1d2d409..43fbc62cf 100644
--- a/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md
+++ b/lib/libesp32_div/NimBLE-Arduino/CHANGELOG.md
@@ -2,6 +2,22 @@
All notable changes to this project will be documented in this file.
+## [1.4.1] - 2022-10-23
+
+### Fixed
+ - Compile warning removed for esp32c3
+ - NimBLEDevice::getPower incorrect value when power level is -3db.
+ - Failed pairing when already in progress.
+
+### Changed
+ - Revert previous change that forced writing with response when subscribing in favor of allowing the application to decide.
+
+### Added
+ - Added NimBLEHIDDevice::batteryLevel.
+ - Added NimBLEDevice::setDeviceName allowing for changing the device name while the BLE stack is active.
+ - CI build tests.
+ - Missing items in CHANGELOG that were not recorded correctly
+
## [1.4.0] - 2022-07-10
### Fixed
@@ -11,6 +27,9 @@ All notable changes to this project will be documented in this file.
### Changed
- Updated NimBLE core to use the v1.4.0 branch of esp-nimble.
- AD flags are no longer set in the advertisements of non-connectable beacons, freeing up 3 bytes of advertisement room.
+- Config option CONFIG_BT_NIMBLE_DEBUG replaced with CONFIG_BT_NIMBLE_LOG_LEVEL (see src/nimconfig.h for usage)
+- Config option CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT renamed to CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT
+- Config option CONFIG_BT_NIMBLE_TASK_STACK_SIZE renamed to CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE
### Added
- Preliminary support for non-esp devices, NRF51 and NRF52 devices supported with [n-able arduino core](https://github.com/h2zero/n-able-Arduino)
diff --git a/lib/libesp32_div/NimBLE-Arduino/docs/Doxyfile b/lib/libesp32_div/NimBLE-Arduino/docs/Doxyfile
index 54129a191..d9c430338 100644
--- a/lib/libesp32_div/NimBLE-Arduino/docs/Doxyfile
+++ b/lib/libesp32_div/NimBLE-Arduino/docs/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = NimBLE-Arduino
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.4.0
+PROJECT_NUMBER = 1.4.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
-OUTPUT_DIRECTORY = docs
+OUTPUT_DIRECTORY = doxydocs
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -836,7 +836,7 @@ WARN_NO_PARAMDOC = NO
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
-WARN_AS_ERROR = FAIL_ON_WARNINGS
+WARN_AS_ERROR = YES
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
diff --git a/lib/libesp32_div/NimBLE-Arduino/library.properties b/lib/libesp32_div/NimBLE-Arduino/library.properties
index 16ddf82b5..d1b32b9cf 100644
--- a/lib/libesp32_div/NimBLE-Arduino/library.properties
+++ b/lib/libesp32_div/NimBLE-Arduino/library.properties
@@ -1,5 +1,5 @@
name=NimBLE-Arduino
-version=1.4.0
+version=1.4.1
author=h2zero
maintainer=h2zero
sentence=Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE.
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp
index d923e6a0a..a83e23b4a 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEClient.cpp
@@ -336,6 +336,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttributes)
* @return True on success.
*/
bool NimBLEClient::secureConnection() {
+ NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
@@ -345,7 +346,7 @@ bool NimBLEClient::secureConnection() {
m_pTaskData = &taskData;
int rc = NimBLEDevice::startSecurity(m_conn_id);
- if(rc != 0){
+ if(rc != 0 && rc != BLE_HS_EALREADY){
m_lastErr = rc;
m_pTaskData = nullptr;
return false;
@@ -360,9 +361,11 @@ bool NimBLEClient::secureConnection() {
if(taskData.rc != 0){
m_lastErr = taskData.rc;
+ NIMBLE_LOGE(LOG_TAG, "secureConnection: failed rc=%d", taskData.rc);
return false;
}
+ NIMBLE_LOGD(LOG_TAG, "<< secureConnection: success");
return true;
} // secureConnection
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp
index 6ae9a7745..43ba21909 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.cpp
@@ -971,6 +971,15 @@ void NimBLEDevice::deinit(bool clearAll) {
}
} // deinit
+/**
+ * @brief Set the BLEDevice's name
+ * @param [in] deviceName The device name of the device.
+ */
+/* STATIC */
+void NimBLEDevice::setDeviceName(const std::string &deviceName) {
+ ble_svc_gap_device_name_set(deviceName.c_str());
+} // setDeviceName
+
/**
* @brief Check if the initialization is complete.
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h
index b7e804b8f..8d4d849e4 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEDevice.h
@@ -97,6 +97,7 @@ class NimBLEDevice {
public:
static void init(const std::string &deviceName);
static void deinit(bool clearAll = false);
+ static void setDeviceName(const std::string &deviceName);
static bool getInitialized();
static NimBLEAddress getAddress();
static std::string toString();
@@ -150,7 +151,8 @@ public:
int max_events = 0);
static bool stopAdvertising(uint8_t inst_id);
static bool stopAdvertising();
-# else
+# endif
+# if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
static NimBLEAdvertising* getAdvertising();
static bool startAdvertising();
static bool stopAdvertising();
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.cpp
index 29150ce63..a2310eb9e 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.cpp
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.cpp
@@ -203,12 +203,12 @@ void NimBLEHIDDevice::setBatteryLevel(uint8_t level) {
/*
* @brief Returns battery level characteristic
* @ return battery level characteristic
- *//*
-BLECharacteristic* BLEHIDDevice::batteryLevel() {
+ */
+NimBLECharacteristic* NimBLEHIDDevice::batteryLevel() {
return m_batteryLevelCharacteristic;
}
-
+/*
BLECharacteristic* BLEHIDDevice::reportMap() {
return m_reportMapCharacteristic;
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.h
index ef2ed7395..0e8b2828a 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.h
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEHIDDevice.h
@@ -55,7 +55,7 @@ public:
void pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version);
//NimBLECharacteristic* hidInfo();
void hidInfo(uint8_t country, uint8_t flags);
- //NimBLECharacteristic* batteryLevel();
+ NimBLECharacteristic* batteryLevel();
void setBatteryLevel(uint8_t level);
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp
index 68982f89e..6cca615db 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp
@@ -616,7 +616,6 @@ bool NimBLERemoteCharacteristic::setNotify(uint16_t val, notify_callback notifyC
NIMBLE_LOGD(LOG_TAG, "<< setNotify()");
- response = true; // Always write with response as per Bluetooth core specification.
return desc->writeValue((uint8_t *)&val, 2, response);
} // setNotify
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h
index 7042b19bf..353d83221 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h
@@ -73,8 +73,8 @@ public:
bool subscribe(bool notifications = true,
notify_callback notifyCallback = nullptr,
- bool response = true);
- bool unsubscribe(bool response = true);
+ bool response = false);
+ bool unsubscribe(bool response = false);
bool registerForNotify(notify_callback notifyCallback,
bool notifications = true,
bool response = true)
diff --git a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h
index 19fecfdde..54bbb9ab1 100644
--- a/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h
+++ b/lib/libesp32_div/NimBLE-Arduino/src/NimBLEServer.h
@@ -58,7 +58,8 @@ public:
int duration = 0,
int max_events = 0);
bool stopAdvertising(uint8_t inst_id);
-#else
+#endif
+#if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
NimBLEAdvertising* getAdvertising();
bool startAdvertising();
#endif
From b4269d262c279b08d487e944488eb96d74d2790a Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 24 Oct 2022 11:32:10 +0200
Subject: [PATCH 049/319] Add support for Shelly Pro 1/2
Add support for Shelly Pro 1/2 (#16773)
---
CHANGELOG.md | 4 +-
RELEASENOTES.md | 3 +
.../include/tasmota_configurations_ESP32.h | 1 +
tasmota/include/tasmota_template.h | 4 +-
tasmota/tasmota_support/support_tasmota.ino | 6 +-
.../xdrv_88_esp32_shelly_pro.ino | 125 ++++++++++++++++++
6 files changed, 138 insertions(+), 5 deletions(-)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bb8656d7..46d15e97c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,8 @@ All notable changes to this project will be documented in this file.
## [12.2.0.1]
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
-- Berry add `bytes().setbytes()`
+- Berry add `bytes().setbytes()` (#16892)
+- Support for Shelly Pro 1/2 (#16773)
### Breaking Changed
@@ -14,6 +15,7 @@ All notable changes to this project will be documented in this file.
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
- Compiling with reduced boards manifests in favour of Autoconfig (#16848)
- Add NeoPool ``NPFiltration 2`` toggle cmnd (#16859)
+- ESP32 NimBLE library from v1.4.0 to v1.4.1 (#16775)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index c377bd73d..5e85b1f00 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -110,10 +110,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.1
### Added
- DS18x20 support on up to four GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
+- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
+- Support for Shelly Pro 1/2 [#16773](https://github.com/arendst/Tasmota/issues/16773)
### Breaking Changed
### Changed
+- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index d6a691003..b252a2275 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -642,6 +642,7 @@
//#define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code)
//#define USE_MCP2515 // Add support for can bus using MCP2515 (+7k code)
//#define USE_CANSNIFFER // Add support for can bus sniffer using MCP2515 (+5k code)
+#define USE_SHELLY_PRO // Add support for Shelly Pro
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index d37ffd6a3..869e92a8c 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -208,7 +208,7 @@ enum ProgramSelectablePins {
GPIO_USER, // User configurable needs to be 2047
GPIO_MAX };
-#define MAX_OPTIONS_A 6 // Increase if more bits are used from GpioOptionABits
+#define MAX_OPTIONS_A 7 // Increase if more bits are used from GpioOptionABits
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
uint32_t data; // Allow bit manipulation using SetOption
@@ -219,7 +219,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t enable_ccloader : 1; // bit 3 (v9.4.0.5) - Option_A4 - (Zigbee) Enable CCLoader using Zigbee Rx/Tx/Rst Gpios
uint32_t rotary_mi_desk : 1; // bit 4 (v9.5.0.5) - Option_A5 - (Rotary) Enable Mi Desk emulation
uint32_t linkind_support : 1; // bit 5 (v10.1.0.4) - Option_A6 - (Light) LinkInd support
- uint32_t spare06 : 1; // bit 6
+ uint32_t shelly_pro : 1; // bit 6 (v12.2.0.1) - Option_A7 - (Device) Shelly Pro
uint32_t spare07 : 1; // bit 7
uint32_t spare08 : 1; // bit 8
uint32_t spare09 : 1; // bit 9
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index 77163871e..0b390be00 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -517,8 +517,10 @@ void SetLedPowerAll(uint32_t state)
}
}
-void SetLedLink(uint32_t state)
-{
+void SetLedLink(uint32_t state) {
+#ifdef USE_SHELLY_PRO
+ if (ShellyProLedLink(state)) { return; }
+#endif // USE_SHELLY_PRO
int led_pin = Pin(GPIO_LEDLNK);
uint32_t led_inv = TasmotaGlobal.ledlnk_inverted;
if (-1 == led_pin) { // Legacy - LED1 is status
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
new file mode 100644
index 000000000..9392dab40
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -0,0 +1,125 @@
+/*
+ xdrv_88_shelly_pro.ino - Shelly pro family support for Tasmota
+
+ Copyright (C) 2022 Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef ESP32
+#ifdef USE_SPI
+#ifdef USE_SHELLY_PRO
+/*********************************************************************************************\
+ * Shelly Pro support
+ *
+ * {"NAME":"Shelly Pro 1","GPIO":[0,0,0,0,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,0,0,160,0],"FLAG":0,"BASE":1}
+ * {"NAME":"Shelly Pro 2","GPIO":[0,0,0,0,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,0,0,160,161],"FLAG":0,"BASE":1}
+ *
+ * Shelly Pro uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring
+\*********************************************************************************************/
+
+#define XDRV_88 88
+
+struct SPro {
+ uint8_t pin_shift595_rclk;
+ uint8_t ledlink;
+ uint8_t power;
+ bool detected;
+} SPro;
+
+void ShellyProUpdate(void) {
+ // Shelly Pro 595 register
+ // bit 0 = relay/led 1
+ // bit 1 = relay/led 2
+ // bit 2 = wifi led blue
+ // bit 3 = wifi led green
+ // bit 4 = wifi led red
+ // bit 5 - 7 = nc
+ uint32_t val = SPro.power | SPro.ledlink;
+ SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
+ SPI.transfer(val); // Write 74HC595 shift register
+ SPI.endTransaction();
+
+ digitalWrite(SPro.pin_shift595_rclk, 1);
+ delayMicroseconds(200); // Shelly 10mS
+ digitalWrite(SPro.pin_shift595_rclk, 0);
+}
+
+void ShellyProPreInit(void) {
+ if ((SPI_MOSI_MISO == TasmotaGlobal.spi_enabled) &&
+ PinUsed(GPIO_SPI_CS) &&
+ TasmotaGlobal.gpio_optiona.shelly_pro) { // Option_A7
+
+ if (PinUsed(GPIO_SWT1)) {
+ TasmotaGlobal.devices_present++; // Shelly Pro 1
+ if (PinUsed(GPIO_SWT1, 1)) {
+ TasmotaGlobal.devices_present++; // Shelly Pro 2
+ }
+
+ SPro.pin_shift595_rclk = Pin(GPIO_SPI_CS);
+ pinMode(SPro.pin_shift595_rclk, OUTPUT);
+ digitalWrite(SPro.pin_shift595_rclk, 0);
+ // Does nothing if SPI is already initiated (by ADE7953) so no harm done
+ SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
+
+ SPro.power = TasmotaGlobal.power &3; // Restore power
+ SPro.ledlink = 0x1C; // All leds off
+ ShellyProUpdate();
+
+ SPro.detected = true;
+ }
+ }
+}
+
+void ShellyProPower(void) {
+ SPro.power = XdrvMailbox.index &3;
+ ShellyProUpdate();
+}
+
+/*********************************************************************************************\
+ * External called functions
+\*********************************************************************************************/
+
+bool ShellyProLedLink(uint32_t state) {
+ if (SPro.detected) {
+ // bit 2 = blue, 3 = green, 4 = red
+ SPro.ledlink = (state) ? 0x18 : 0x1C; // Blue on (wifi link) or all off
+ ShellyProUpdate();
+ return true;
+ }
+ return false;
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xdrv88(uint8_t function) {
+ bool result = false;
+
+ if (FUNC_PRE_INIT == function) {
+ ShellyProPreInit();
+ } else if (SPro.detected) {
+ switch (function) {
+ case FUNC_SET_POWER:
+ ShellyProPower();
+ break;
+ }
+ }
+ return result;
+}
+
+#endif // USE_SHELLY_PRO
+#endif // USE_SPI
+#endif // ESP32
From d173b93758afddb9b9db2e0132c9822bc552415b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 24 Oct 2022 12:21:25 +0200
Subject: [PATCH 050/319] Fix shelly pro button double press
---
tasmota/include/tasmota.h | 2 +-
tasmota/tasmota_support/support_button_v3.ino | 5 +++++
tasmota/tasmota_support/support_tasmota.ino | 9 +++++---
.../xdrv_88_esp32_shelly_pro.ino | 22 +++++++++----------
4 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index 5383ba276..3dee90dad 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -382,7 +382,7 @@ enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_I2C_INIT, FUNC_
FUNC_SAVE_SETTINGS, FUNC_SAVE_AT_MIDNIGHT, FUNC_SAVE_BEFORE_RESTART,
FUNC_AFTER_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_SENSOR, FUNC_WEB_COL_SENSOR, FUNC_COMMAND, FUNC_COMMAND_SENSOR, FUNC_COMMAND_DRIVER,
FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA,
- FUNC_SET_POWER, FUNC_SET_DEVICE_POWER, FUNC_SHOW_SENSOR, FUNC_ANY_KEY,
+ FUNC_SET_POWER, FUNC_SET_DEVICE_POWER, FUNC_SHOW_SENSOR, FUNC_ANY_KEY, FUNC_LED_LINK,
FUNC_ENERGY_EVERY_SECOND, FUNC_ENERGY_RESET,
FUNC_RULES_PROCESS, FUNC_TELEPERIOD_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_BUTTON_PRESSED, FUNC_BUTTON_MULTI_PRESSED,
FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_CONSOLE_BUTTON, FUNC_WEB_ADD_MANAGEMENT_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON,
diff --git a/tasmota/tasmota_support/support_button_v3.ino b/tasmota/tasmota_support/support_button_v3.ino
index bdfad5330..b12ef5714 100644
--- a/tasmota/tasmota_support/support_button_v3.ino
+++ b/tasmota/tasmota_support/support_button_v3.ino
@@ -473,6 +473,11 @@ void ButtonHandler(void) {
valid_relay = (Button.press_counter[button_index] <= TasmotaGlobal.devices_present);
}
#endif // ESP8266
+#ifdef USE_SHELLY_PRO
+ if (TasmotaGlobal.gpio_optiona.shelly_pro) {
+ valid_relay = (Button.press_counter[button_index] <= TasmotaGlobal.devices_present);
+ }
+#endif // USE_SHELLY_PRO
if ((Button.press_counter[button_index] > 1) && valid_relay && (Button.press_counter[button_index] <= MAX_RELAY_BUTTON1)) {
ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
// AddLog(LOG_LEVEL_DEBUG, PSTR("BTN: Relay%d found on GPIO%d"), Button.press_counter[button_index], Pin(GPIO_REL1, Button.press_counter[button_index]-1));
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index 0b390be00..b51856b4b 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -518,9 +518,12 @@ void SetLedPowerAll(uint32_t state)
}
void SetLedLink(uint32_t state) {
-#ifdef USE_SHELLY_PRO
- if (ShellyProLedLink(state)) { return; }
-#endif // USE_SHELLY_PRO
+#ifdef ESP32
+ uint32_t index = XdrvMailbox.index;
+ XdrvMailbox.index = state;
+ XdrvCall(FUNC_LED_LINK);
+ XdrvMailbox.index = index;
+#endif // ESP32
int led_pin = Pin(GPIO_LEDLNK);
uint32_t led_inv = TasmotaGlobal.ledlnk_inverted;
if (-1 == led_pin) { // Legacy - LED1 is status
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 9392dab40..d7ffd8caa 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -27,6 +27,9 @@
* {"NAME":"Shelly Pro 2","GPIO":[0,0,0,0,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,0,0,160,161],"FLAG":0,"BASE":1}
*
* Shelly Pro uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring
+ *
+ * Testset
+ * {"NAME":"Shelly Pro 2PM (POC)","GPIO":[1,0,1,0,768,1,0,0,672,704,736,1,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,32,1,1,160,161],"FLAG":0,"BASE":1}
\*********************************************************************************************/
#define XDRV_88 88
@@ -87,18 +90,10 @@ void ShellyProPower(void) {
ShellyProUpdate();
}
-/*********************************************************************************************\
- * External called functions
-\*********************************************************************************************/
-
-bool ShellyProLedLink(uint32_t state) {
- if (SPro.detected) {
- // bit 2 = blue, 3 = green, 4 = red
- SPro.ledlink = (state) ? 0x18 : 0x1C; // Blue on (wifi link) or all off
- ShellyProUpdate();
- return true;
- }
- return false;
+void ShellyProLedLink(void) {
+ // bit 2 = blue, 3 = green, 4 = red
+ SPro.ledlink = (XdrvMailbox.index) ? 0x18 : 0x1C; // Blue on (wifi link) or all off
+ ShellyProUpdate();
}
/*********************************************************************************************\
@@ -115,6 +110,9 @@ bool Xdrv88(uint8_t function) {
case FUNC_SET_POWER:
ShellyProPower();
break;
+ case FUNC_LED_LINK:
+ ShellyProLedLink();
+ break;
}
}
return result;
From 72b4ea2ee33dda0ef70f5073d6d3c5bb31522647 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 24 Oct 2022 13:52:05 +0200
Subject: [PATCH 051/319] Add Zigbee router firmware for Sonoff ZBBridgePro
---
CHANGELOG.md | 1 +
.../SonoffZBPro_router_20220125.hex | 5722 +++++++++++++++++
2 files changed, 5723 insertions(+)
create mode 100644 tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bb8656d7..300ef6298 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
- Berry add `bytes().setbytes()`
+- Add Zigbee router firmware for Sonoff ZBBridgePro
### Breaking Changed
diff --git a/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex b/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
new file mode 100644
index 000000000..1d220c012
--- /dev/null
+++ b/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
@@ -0,0 +1,5722 @@
+:20000000003A0120D924020039FB021039FB021039FB021039FB021039FB021039FB0210E2
+:1C00200039FB021039FB021039FB021039FB021039FB021039FB021011FB021002
+:200040002DE9F04FAB4EC34C05460121ADF1540DAF78327894F842000E91297845293FDC6F
+:20006000452900F0078728291EDC282901F03980002901F0F982891E01F0E382491E01F064
+:200080005583491E01F04E83C91E01F0CF82491E01F07882491E01F06B82DFF8C0C2C91F5E
+:2000A000122952D901F0F0BA2A3901F00980491E00F0FF87DFF8A0C2491E00F098870E398F
+:2000C00000F03887491E01F01883491E01F01183491F00F00287891E00F0EE8601F0D4BA27
+:2000E000D8291CDCD82900F007814A3900F0A886491E00F08F86491E00F08286491E00F0CB
+:2001000074865339242935D92D3901F0C982491E00F0B283093900F01F8201F0B5BAE13983
+:2001200001F0B882C91E01F0B182891E00F0C680491F00F09880BC4A0E397CD0491E46D026
+:20014000491E3ED0491E01F09FBADFE811F0070AC709A9099D0AE60A910982099D0A600952
+:200160003F099D0A0A09DB089D0AE20ADF0ADA0AAE08DB07DFE811F0B90AB50AB10A320665
+:20018000AD0AA90AA50A2D069E0A1006D305A20577056605560546053A0530052705990A06
+:2001A0001E050405DC04A2047E047104FE03F203E703880A880A880ABC039C03880A880A7E
+:2001C0008A036868002801F0998000F00BBE6868002801F093801146097831F0010140F0B0
+:2001E00001860488466802208DF820003146ADF8224009A829F0E4FD08A815F0EDFB012888
+:2002000015D14FF6FE70A0420BD0304628F00CFC28B9002120460A4626F074F808E00020B0
+:2002200006E0002130460A4621F084FA00E00E980F95139055E1696891B11046007830F05E
+:20024000010040F0CF85084600218DF820100990022108A88DF821101DF080FE01F01EB980
+:200260000F9501F04BB86868007878B9002027F0D1FE26F0F1FF0E980DA98DF834005220DA
+:2002800025F0CAF928F0A0FA01F054BA4FF6FF7027F0C0FE30784FF4807122F041F830787D
+:2002A0004FF4807120F03AFE00200DF135018DF83500522025F0B0F901F03CBA68680028A5
+:2002C00001F03882A34C01886180807A60B929F0D8FE40F28A21B0FBF1F220780821521D7D
+:2002E00029F039FF01F026BA708F0E9928F0EEFE01F020BAE4FA002068680F95002800F0DD
+:20030000FD8700681090807E27F06EFF061C00F0B0821098C76900252C464FF00309387821
+:20032000A04200F3FF800F2410FB04F0401CC0B240191CF08FFC5FEA000800F0988224F00A
+:20034000B7F9002840F0EC800025139588F800504CE0C0464CFF002098FD00201C030120FA
+:200360001099032315FB03F6BA1991F81AA0B1F80C9052880F2015FB00845046494625F073
+:20038000EDFBBA195288834608AB504623F0E4FB641CBBF1FF0F1AD0C8B1A6489DF827304D
+:2003A0000168D80838BF8C2012D39DF826001623207103FB0B10C18800F10E02A4F80510D3
+:2003C0000189C4F80B201398A4F8071000E086202070B8194078BB1960705888608098F8BB
+:2003E00000006D1CEDB2401C88F800003878A842B6DC1098817E474600F10E064FF00F093D
+:2004000085893A78109190F80AA01196139912950C468A4267DC204629F03EFF061C5BD0E5
+:20042000139D024641E0C046ADFE002015FB09F0391838184078491C02F8010B487802F84B
+:20044000010B887802F8010B4888001202F8010B0B7843BB4B78F3B9087902F8010B48796A
+:2004600002F8010BB1F80500001202F8010BC87902F8010BB1F80700001202F8010B087920
+:20048000834628F09AFE70B1D1F80B10584617F0EFFA024607E0487A02F8010BB1F80900A7
+:2004A000001202F8010B6D1CEDB23878A842BDDC139900910E98019002900391CDF810A0BA
+:2004C0000594129A069610980791119909230FF0EFFE304629F020FE384624F05DFB28F08A
+:2004E000C3FC1398C6E111FB09F3F818FB185E78241DA4B2401C86B9467866B90079834699
+:2005000028F05BFE641DA4B238B158461CF018FE001984B201E0A41CA4B2491CC9B278E765
+:200520004046A2E114FB0972109930785288898908AB23F011FB50B19DF82600014628F0FE
+:200540003CFE20B108461CF0FBFD2D18EDB2641CE4B2E4E69C03012068680F95002800F02E
+:20056000CD8600681090807E27F03EFE002800F080811098D0F81C8098F80000002800F002
+:2005800078818000401C1CF065FB0028119000F06E8129F08FFB24F08BF8002840F06481FB
+:2005A00000261396129698F80000B04200F3E4801398012840F08C80CC4DA878EA68162119
+:2005C00011FB00F081B2562029F018FD05F10C0640B9A8783268162111FB00F081B25620B1
+:2005E00029F012FD6078802121F09AFE2F78B8001CF030FBB8465FEA000B69D02E78B8F141
+:20060000000F0CD005F11800594642784A70428810F8144B4A807F1E01F8044BF5D1002EFA
+:200620003CD037464FF000094FF0140AA6B305F1180411E0FC0C0120002808BF4E4607D0AD
+:2006400041680668216124F0A7FA207B401E2073304624F0A1FA2E7820690028ECD1761EF3
+:20066000F6B216FB0AF2A0184188618041786170C188E1808188A18001890C30218109C8CC
+:2006800004F10C0181E80900105D2070A318C3F8109083F80C902E707F1EC7D10FF06AFC84
+:2006A000B8F1000F11D018355C4647466078618825F042FEFF2804D02678810001EB0011F8
+:2006C0006E547F1E04F10404F0D1584624F064FA12981199087018B9002048700E9F0F704C
+:2006E000109890F81AA00C4600F10E098689857A2078042110FB01F0804629F0CDFD071C23
+:200700001ED0014600202278824222DC012A03D164780CB9DDF83880002000900E99019112
+:200720000291039004953246CDF81480072306974946079050460FF0BBFD384629F0ECFC70
+:20074000119824F029FA28F08FFB26F0BFFA002090E08200A3185B780B70A3189B784B70A4
+:20076000A318DB78A2188B70B2F80320401CC0B21212CA70091DC6E7109B9F890E2016FBD8
+:2007800000856D1C93F81AA0B5F80190394650464A4625F0E3F9834608AB504623F0DCF938
+:2007A000BBF1FF0F48D0002846D02F78002F58D19DF82600E97888423CD19DF82700C008B3
+:2007C00036D3BD480168A8884FF6FF72824201D1EF88B7B1162202FB0B17F880E88838814F
+:2007E000E87828F0EAFC00B30E370021042238461EF0ACF8E8781CF0A3FCD5F80A100246F2
+:2008000010E0162000FB0B156889E880A889042205F10E070021288138461EF097F80422D1
+:2008200005F11201384628F035FD0E98139018E08C2002E08D2000E08720129BDDF844C05E
+:2008400099000CEB0102507028780CEB01075B1CB8700CEB0102DFB21297B5F80110A2F87B
+:200860000310761CF6B29EE6119824F095F9102000E002200F9DB6E26868002800F03E853B
+:200880006868006825F072FD00F008BEAF68002F00F0348500246C7040B12046014604F065
+:2008A00019FB002808BF201C00F0B8810E98B5E16868002800F022850020696868700978BB
+:2008C00061B984F8460094F82100401E84F821000E98014625F07AF900F02CBF29F058FBD8
+:2008E0000E98014607F08EFE00F024BFF00C01206868002800F002850678476800210822B1
+:2009000008A81EF023F8E7B1CD4800210170AEB1761E0ED0761E0AD0761E03D0761E10D1A4
+:200920000E990170384608A918F0F8FEC2E20E990170384608A924F04FFABBE222F09EFDE0
+:20094000B8E20220B6E26868002800F0D784686800F1120124F040FA00F0A0BD6868002899
+:2009600000F0CC846A6810785188928817F05AF900F094BD6868002800F0C08490F800900B
+:2009800046888188B0F806B0B0F808A00A301090C94807790F91002F00F03D81C5490F6865
+:2009A000002F00F0AB8480467868007881454FD128F048FB00284BD0037C002B48D04469D8
+:2009C000002C45D000200C22834240F3978410FB02F1615A8E4238D10E201CF03BF9071C52
+:2009E00000F01981002407F10A0004235B1E00F8014BFBD1BC80FF2038704FF6FF737B80E2
+:200A00003C81FC8087F800900F9A7E801099BA8007F10A00A7F806B00422A7F808A028F028
+:200A200039FC08201CF016F9D8F8141018B9384624F0B2F8EFE007604160C8F8140098F802
+:200A40001000401C88F8100067E1401CC0B2BBE73F68002FA8D100F051BC6868002800F0AE
+:200A60004D840020687068681FF000F9A968088000F060BEA868002800F040840021697048
+:200A8000AD68267860786F1C002E08BF29700ED0402124F061F84FF47A710F2300F2E7309D
+:200AA000B0FBF1F116FB03100F3828702678002F00F040863046B2E0FC0C0120AF68A18FAB
+:200AC00094F83F2094F83E3094F84060D4F838C094F841E094F8438094F8449094F845A074
+:200AE00094F846B0002F00F0098400276F70AF683981A968CA72A9688B72A9680E73A968F3
+:200B00008873A868C0F804C0A86880F80DE0606BA9680860A86880F80F80A86880F8109056
+:200B2000A86880F811A0A86880F812B000F002BE6F68002F00F0E283002068706868077DDB
+:200B400017B1C07C84F845006868877D17B1417D84F84610077C17B1C089A0876868077B97
+:200B600017B18068A0636868877C1FB1407C84F84100686807790FB10068606300F0DABDE4
+:200B80000021697070B194F83F0080090AD208A808221DF0DBFE28F0C3FF08A81AF084FD35
+:200BA00000F0C8BD28F0BCFF4FF4FA7027F0FCFD00F0C0BDA868002800F0A0830020687080
+:200BC00029F040FA2AE0D948A9680078002900F095830021697021E06868002800F08E83E9
+:200BE0006868007822F088FE00F058BC6868002800F08483002068706868007806F0E8F90B
+:200C000000F098BDA868002800F078830020687023F09CF908B90E98E5E00078AF68387069
+:200C200000F088BD6868002800F068830020687069680888897822F057F800F07BBDC046C3
+:200C400054FE00206868002800F05883B84C6968082204F10C0028F01DFB686801896180F4
+:200C6000807A2070B3E06868002800F047830188ADF830104088ADF832000CA9532024F05C
+:200C8000CBFC50200DF1320124F0C6FCE1200DF1360127F021F868689DF8361000798842C2
+:200CA00000F095808DF836000DF13601E12024F0B3FC8CE024050120F00C012068680028B0
+:200CC00000F01C83007825F033FA686896F83C104078884213D086F83C000DF13701E120CB
+:200CE00026F0FAFF68689DF837104078884206D08DF837000DF13701E12024F08DFC686881
+:200D00000E9F407807FA00F0F06428F04BF80024A6F89440384621F063FC204663E06F68CA
+:200D2000002F00F0EB82387886F84A007C887487387A86F83C007B89F3877A68F264B9894C
+:200D4000A6F84810B87B86F85C00F87B86F82900387C86F827007C697465B86996F896100A
+:200D6000B065387F884201D025F0E2F9696806F15D001D3129F010FA96F84A0006F124048F
+:200D8000082824D121207421224629F03DF90020022125F0F7F81AE06968002900F0AE8246
+:200DA0000888498825F034FC70B9696808880E9A498823F049FD69680888498825F028FCC6
+:200DC000002808BFC8200ED0696809794170002009E06868002800F0918203E0686800287B
+:200DE00000F08C8212202C465BE26868002800F049846A6810889178D27825F083FA4DE3E0
+:200E00006868002800F03E846868017A427A20F091FC43E36868002800F0348441788DF880
+:200E2000201081788DF82110007828F001F8002800F064820C3008A9022228F02BFAC6E751
+:200E40006968002900F01E84A868002800F01A84087808A927F063FB6868A96800780870C9
+:200E60009DF82000A96848709DF82100A968887000F025BC6868002800F004840A3007783B
+:200E8000002F0CBF00220E9A47780FB142F0020287780FB142F00402C7780FB142F00802A7
+:200EA000007908B142F04002696808880023891C24F000FE044630E76868002800F0E283A3
+:200EC00002206F688DF828003988ADF82010FA78B97808A821F0D4FAE0E26868002800F0FA
+:200EE000D18302218DF8281001884FF6FF70884205D0821E8A4202D0C01E88420BD128F008
+:200F0000D5FFADF820006868C27A837A811C08A823F08AFB687068680188ADF82010C27A08
+:200F2000837A811C08A823F07FFBB7E2DC02012094FF00206C68002C00F0A48302208DF8D1
+:200F400028002188ADF8201063462279B4F80680267AD4F80CB0277CD4F814A061880F92A0
+:200F60001A1D14680346F21912FB03F00F305FFA80F9B9F1500F00F3198128F097FF88424B
+:200F800033D121700812607028F054F9A41C0146204629F001F904460F98207084F801806F
+:200FA0004FEA2823A370E670241D66B15846A41E017804F8021F30F8021B761E4FEA2121A2
+:200FC0006170F5D1A41C27705FB1641E5046017804F8021F30F8021B7F1E4FEA2121617037
+:200FE000F5D1C74820224B465EE01846FBE66C68002C00F0478302218DF828102088E14663
+:20100000ADF820006288A388A679D4F80880277BD4F810E0D9F80400F41914FB01F1891D9C
+:201020005FFA81FCBCF1500F42DC9DF828100F2918BF022908D1BDF820404FF6FF71A14223
+:2010400004BF891EADF820104FF6FF71914208BF8A1E00F8012B111200F8011B00F8013BCB
+:201060001C1200F8014B00F8016B66B14146801E0A7800F8022F31F8022B761E4FEA22224C
+:201080004270F5D1801C07705FB1401E71460A7800F8022F31F8022B7F1E4FEA22224270D3
+:2010A000F5D148460622634608A91FF037FD9AE67CE06868002800F0E5820220052216E0AD
+:2010C0006868002800F0DE8202206F688DF828003988ADF820103A79798808A827F094FB82
+:2010E00081E66868002800F0CD82022002468DF8280068680188ADF82010418808A827F07D
+:201100007BFECBE12C466368002B00F0CC80187D27F0E2FE002800F0C6809D691C331F7830
+:20112000002F0CBF002002205F780FB140F010009F780FB140F00800DF780FB140F0200026
+:201140001F790FB140F040005F790FB140F0800083466068007D28F0A5FD5FEA000800F076
+:20116000A2806168887A8DF829008889ADF82A00087802288DF828000CD001280AD00F2887
+:2011800008D0032809D1891C08A8082228F082F8616802E04888ADF820008F7B002F72D0A6
+:2011A00078001BF057FD061C02D1254610201AE600216068877B8F425FDCC18A838CCDF8B2
+:2011C0003C80826A13950C2F109190F822901193BDF8208012924ADA404620F03FFD0C28E2
+:2011E00014D14FF6FE7020F039FD0C280ED1BA4A0E9992F8D4500020DC3212F8083B9D424B
+:20120000C4BF1D1C081C491C0C29F6DBC24D4FF6FE7305EBC00568686B8018B123F0BCFCBA
+:201220000020686077B14FEA470A50461BF012FD6860002808BF10201AD0686831465246B4
+:2012400028F028F8A5F80280C3486F70129B0078139F28700F990093109A019708A8CDF8EC
+:2012600008B0119BCDF80C900DF06AFA00E002206070304623F090FC5CE200694A00105A06
+:20128000491CB05295E7886A00900195CDF808B091F822000390CA8A8B8C08A841460DF0F9
+:2012A0004FFA2546FAE0254628E0686830B3007827F012FE071C21D0387B22F0F7FA0028E9
+:2012C000687040F03782AE4845683E46002D00F031822F46002117B9BE4202D02AE2BE4212
+:2012E00009D1B54219BF3068086031684160304628F00AFF1EE239463F68ECE7022072E502
+:2013000098FD00206868002800F0BC81A868002800F0B881002108221DF018FB69680878D6
+:20132000498826F0CDF8071C19D00020A968687038880880A968B8788870AC68A078002817
+:2013400000F0F8811BF086FC6060AA685068002800F0F0819278F91C27F09CFFEAE1B12017
+:201360009CE06F68002F00F08D81AF68002F00F089810024664668686C70376801782046B3
+:201380003FB13A79914204BF401CC0B23F68002FF7D1A9680870A868007840001BF05AFCF6
+:2013A000A968376848606868A96800784968002F00F0C0813A79904204D1FA88661C21F8F4
+:2013C0001420F4B23F68002FF4D1B3E16F68002F00F058816868002764466F7006782068AF
+:2013E00090B101798E420BD1002F04BF0568256002D001683960056823F0CEFB284601E036
+:20140000074600680028ECD123F0C6FC92E102206F686870002F00F08D81644639787A888F
+:201420002068002800F0868100270379994202D1C3889A4204D0074600680028F5D179E1BC
+:2014400007B967460168396023F0A6FB23F0A4FC35E16868002800F01581807800280CBF37
+:2014600000220E9A68680E9900881FF0E5F815E06968002900F00681887828B1C878002810
+:201480000CBF0E99032100E000216A68107908B141F040011088527913F01AFC687049E1B1
+:2014A0006868002800F0EE80696808A80822091D27F0F0FE032027F071FF6868C07B24F037
+:2014C00007FF6868817B009102788389418808A815F076FEE2E7C046200100206868002829
+:2014E00000F0D080384627F0E9FC041C16D11C201BF0B0FB041C00F01D8100211C221DF01F
+:2015000025FA2771204624F07DFB38B9204623F043FBD120C2E7C046F4010020E08887498D
+:2015200040F00800E08040F00400E080022028F017FD8349032028F013FD68680168089148
+:2015400000798DF824000E9F8DF825708DF8267008A820F05FF8A1E7C6FE0020686800280C
+:2015600000F0908068680088002103F0B3FCE1E06868002800F086806868007870709EE0FB
+:20158000281A00206F486F680478002F7AD0686800212A2269701DF0D9F9708F6968088019
+:2015A0006868B6F84870847269688F81F08F6968C8826868082206F1240707F139010E30F8
+:2015C00027F068FE27F036FE014668680822801C27F060FE6868082207F11C01183027F083
+:2015E00059FE96F83C10686880F823100E986968554C81F8210021784A0824BF6A6882F873
+:2016000024008A0824BF6A6882F82500CA0824BF6A6882F826000A0924BF6A6882F8270030
+:20162000C90924BF696881F8280083E0686848B390F90000044627F0EDFBA86800B104704E
+:201640003DE06868F0B100200E9F687069680F7069684F7068680226867068680624C4705B
+:20166000696803230B7165E0686858B1407818B1FF20032124F086FC28F024FC0E98334925
+:201680000860FEE7022009E7122007E729461DF0EFFB4EE000202E496870EF780F7049E0B9
+:2016A000002068701CF0CEFA44E00020687025F01DFF3FE010464FF4807120F073FA0020CB
+:2016C000ECE629461FF02EFB33E0294613F0B0FC2FE0294618F034FF2BE0294628F002FB18
+:2016E00027E0294621F018FF23E0294621F0CDFB1FE029461EF0D0FB1BE0294619F096FEB3
+:2017000017E0384629460EF08FFA12E027F06AFEC4E6294620F040FC0BE03846294607F0B9
+:20172000E5FB06E0294607F0EDF802E0294607F065FA0E900E9815B0BDE8F08FD1480200A9
+:20174000519A020034FD0020E61201207C052043481900202DE9F04704464FF6FE70ADF1E5
+:20176000600D217AADF85400606808AA13F0A4FF002800F072849DF822000228B4BF0127BE
+:2017800000279DF824000228A8BF0027BDF82A104FF000084FF6F87088420ED04FF6FE7073
+:2017A000401F884209D04FF6FE70001F884204D04FF6FE70C01E884200D1474628F070FB7B
+:2017C0009DF82310884240F04884002F00F04584208D9DF82660678EDFF80093ADF84C007B
+:2017E000ADF82E70D6B161689DF821209DF83C30012027F0A3FD002840F02F844846001DF1
+:20180000007801280AD1208D28F066FC30B1417901F0EF01417141F0080141719DF82570E1
+:201820004546002F4BD19DF83D00474658BBBDF82A00034623F050F94646022808BF012638
+:20184000002E9DF8226018BF0127B9F83A10994208BF47F0020727B1002E14BF40202020EE
+:201860000743184623F038F9012808BF47F00107002E3DD01298007828F01CF9012818BFC3
+:2018800027F0010734E09DF8411041B1FF2906D09DF84000119A24F001FD50B128E0B9F8F3
+:2018A0003A00BDF82A10884205D099F84A0004281ED101251CE09DF82660222721E0BDF82E
+:2018C0002A10FF2025F0FCFD002804BF3E1C082708D09DF8250047F001062C2740F00100D9
+:2018E0008DF8250006F00306012E08BF47F011079DF8266007F002012846084308BF47F02E
+:20190000800796B999F82F0078B107F0220022280BD007F04200422840F09F8312980078B3
+:20192000062818BF072840F09883B8111690F80956D399F832001299BDF82A2080080AD2BE
+:201940000878C01E01282CD9001F2AD0C01E28D0801E26D003E00878401E0A2821D9B8F1E2
+:20196000000F1ED1B9F83A00904240F076830D780520BDF82C408DF8110004A826F044FE1E
+:20198000002800F06A830269032313271370511C0F704C7022128A70CD7044800AF06CF9BE
+:2019A0005BE3169840081BD30878032802D148780D2815D09DF8280038B1BDF82C000E997F
+:2019C00011F0CCF9012800F044839DF8270038B1BDF82A000D9911F0C1F9012800F03683AA
+:2019E000B9F84800B4F84410884209D1CDF80080208DB4F8421094F84620434613F0E2FEFC
+:201A00009DF82600002846D0208DB4F8421024F0FFFD9DF85150061C25D19DB999F890004D
+:201A200001283AD112980078062802D11698400833D2BDF82E104FF6FE70401C884240F058
+:201A4000B6800AE3042026F048FD011C00F005836420087001274F70208D488099F8000066
+:201A600021F01AFEF9E29DF82130606819184A7BF1788A4203D0F270404670606068C0185E
+:201A80000421401C26F0DFFF7168814200F2E582401C706001E09DF8515099F8320080084E
+:201AA000C0F0DB820DB3BDF82C0027F09FFBB8B9BB49BC4CBDF82C000B6822699901A1EB45
+:201AC00083019047012840F0C8826169BDF82C008847A168BDF82C008847BEE2E4FA002037
+:201AE0006168487800F0DF0048709DF8320038B161688879401E8871C0B28DF8320008B91B
+:201B000007F07F07380924D39DF82500F9084FF4805814D279091AD3811011F0070F01F04C
+:201B2000070604D0072E1CBF761EF6B20EB907F07F0700F0E30040EA8600C0B205E020F04A
+:201B40001C00C11021F0030108438DF825006168087299F84A00042800F00082092800F0B1
+:201B6000FD8117F0610F40F0E6809DF82200012811D112980078052800F0D68003280AD17D
+:201B8000BDF82A0027F032FB28B1218D08A815AA002300F0FBFE9DF8320068B99DF8220081
+:201BA000012804D112980078032800F0568208A8214620F041FD50E226F0AEFF002840F060
+:201BC0004C829DF83D0000286DD19DF82400BDF82A10FD100028ADF854102ED13A0930D2D5
+:201BE0009DF82220012A28D0084600211DF000FC002620B14079012816D0022814D0BDF8F1
+:201C00005400B4F8441024F003FD28B1807826F097FC08B1082807DBBDF82C0027F0E6FA3F
+:201C200018B104208DF824000126BDF82A10301C08BF022272D09DF824006A0838BF00233A
+:201C400000D340230DF13D021DF00CFC30B16168087848F0200800F03F0008709DF83D00F9
+:201C600040B1BDF82A1010A822F016FF48F04008ADF854009DF82200012806D0BDF82A0097
+:201C8000BDF82C1000221AF01BF868082CBF40220022BDF82C10BDF82A0016F0EDFB08B1BE
+:201CA00048F0200833E09DF840009DF84110119A24F0F4FA00282ED09DF8410038B9BDF8A7
+:201CC0002A00ADF8540028F007FA00BB1DE011999DF8286001EB400030F8020C002EADF814
+:201CE00054000CBF082010209DF827600EB10830C0B29DF82560002106B1012140186168B3
+:201D0000401CC2B2505C401E505448F0400826F0C9F91690A3E0BDF82A100B22BDF82C00C7
+:201D200000231DF01DF998E1218D08A815AA002300F02CFE91E10020169078086AD3B4F8E9
+:201D400028A09DF833C0B74D1E211698EA79944506D1BDF82C302A88934201D1AE782EB9B8
+:201D6000491E05F1080500F10100EFD11E2826D0AE790EB3B9F84810504625F0A9FC08B111
+:201D8000761EAE71B64833210279FF2A02D00288924509D0491E00F12400F5D107E0C0465F
+:201DA0006CBC0200ECFB0020A879401EA871A8796628A4BF1698A87127F060072AE026F0E3
+:201DC00071F916909DF8320028B9BDF82C00218D814202D11EE0BDF82C00B9F83A10884282
+:201DE00002D199F80600A8B1218D169A08A812F06DF858B1380932BFBDF82A004FF6F870E4
+:201E0000C01D48F00408ADF8540003E0002027F020071690B8094FEAA71510D394F8460056
+:201E200094F8476094F948308DF81000E26B8DF8116004A98DF8123008A804F0DBFC680833
+:201E40000DD3218D169B08A815AA00F09FFD169028B112980078012808BF48F01008BDF8B2
+:201E600054104FF6FE70884204BF002016907E481B30007801282BD1618E4FF6F870C01DD1
+:201E8000884225D0218D884222D0BDF82A204FF6F870401C90421BDDBDF82C00884217D0B5
+:201EA00028F01AF9A0B10179012918BF02290FD101218DF810104088ADF81C0004A821F013
+:201EC0000DF828B105A820F095FD08B125F0C8FE37F07F0000F0C1801698002800F0BD8067
+:201EE00020891AF0B7FE071C00F0B7806168228927F0D0F9002605969DF822008DF81000CF
+:201F00001699009104ADCDF80480B046CDF80880BDF854100395228D237A384617F05CFC6A
+:201F2000C0B999F80100002800F09780BDF82A00ADF81A0045468DF81E508DF81D50BDF8A4
+:201F40002C70ADF81870169E8DF81C6006A827F0F1FA82E0384622F01FFE7EE04149BDF8A7
+:201F60002A000988814209D022F0B6FD022805D09DF8250000F0030001286ED19DF822007A
+:201F8000002851D012980178042903D19DF83C10022942D00178072905D19DF83C2099F8B5
+:201FA0000000042A06D0032957D108A8002115F0E7F952E04FF4806120F0B2F9092089F858
+:201FC0004A0029484178022904BF0021817727F031F901460D9827F00BF801283DD11020D8
+:201FE00026F07BFA07460E991298002F00F1010033D002223A704378027802EB03227A8085
+:20200000807878704A2023F007FB9DF8260010B9164905200870394620E5002008A90DF08F
+:2020200017F81AE0CC02002094F8460094F8477094F948608DF81000E26B8DF8117004A9CA
+:202040008DF8126008A804F0D5FB06E0BDF82A0001E0BDF82C0021F021F918B0BDE8F0877F
+:20206000E40D00201EFB0020ACFE002034FD0020C64A2DE9F04FADF14C0D10780F91090C62
+:2020800080F058840F99890B80F025840F99890980F054830F99490980F0D6820F98DFF8DE
+:2020A0000093C00980F060820F98000A06D321F09DFD0F9880F0800000F05BBC0F98DFF821
+:2020C000D8B2DFF8D882DFF8DCA2400A80F0DC800F98000B80F0C28010460F99C078490BEC
+:2020E00080F0B2805C460F99606AC90B80F096800F992078890863D20F98E188800A40D21E
+:202100000F98000907D3114601200F9F887187F0080000F02EBC0F98C00A0AD31046B0F871
+:202120004800012122F05EFA0F9880F4806000F020BC0F98400C38BF0020C0F01A84544612
+:20214000332501262434207980B105280EDA607900090BD28DF804606088ADF8100001A8DB
+:2021600020F0BCFE10B102A820F044FC6D1E04F12404E8D1854900200F9F087187F4803039
+:20218000F7E310461746B0F84850A7F848105020A11D23F041FAE6883227444660898542FE
+:2021A00005D0864204D0204626F0EBFF00E066817F1E04F11C04F1D10F9880F40070D8E3C7
+:2021C00040B301A827F08CFF27F05EFE49460546032091F8228091F823608DF80D0003A8DD
+:2021E00026F012FA071C15D038690B2100F8011B00F8018B06700126BE7727F01BF878627A
+:202200007D807E7701A838620023BE763846237009F032FD0F9880F00200AAE380B1494693
+:202220001431097801290BD18047A06A00B18047564800784FF480414FF47A7227F088FFA2
+:202240000F9880F4804094E320B100201146C87022F062F90F9880F480508AE322F05CF980
+:202260004946087A01280BD1497A49B1474800784FF47A7212FB01F24FF4006127F068FF33
+:202280000F9880F4006074E327F010FE4FF6FE71814200F06581104690F832008008C0F0B2
+:2022A0005F8100252C46284625F03AFC071C1AD03879012817D0022815D0F879334E411CC2
+:2022C000F97196F88B1081420DDABC727C72388824F03CFC388801A925F03DFE01A820F026
+:2022E00089FB25F0BDFC6D1C332DDCDBA8F11C0632274FF6FE75119436F81C0F85420DD07E
+:20230000307B224C411C317394F88B10814205DA1198B0747074308824F018FC7F1EEBD1F0
+:202320005C46032104F1380010F8047F0FB17F1E0770491EF8D15446332605F1010934F8FC
+:20234000240F81451FD001208DF804006788ADF8107001A820F0C2FDA8B1A8F11C053227F3
+:2023600035F81C0F2188814208D0BDF80610814204D002A8A91C26F03BFE10B1284626F05C
+:2023800000FF7F1EECD1761ED9D101E0E4FA0020119D2C4608E0C046ECFB00206C0800201E
+:2023A000ACFE0020C00D0020284625F0B9FB48B1017931F0040105D1807A26F0C1F808B13E
+:2023C000641CE4B26D1C332DEEDB25F0D3FF119E5FEA00080ED03546284625F08FF928B111
+:2023E000807C26F0ADF808B1761CF6B26D1CEDB2A845F1DCA019C7B2002F41D0B8001AF01D
+:2024000029FC1090002808BF119F3BD0BA00FF211CF09CFA119E3546B44218DD284625F039
+:202420007FFB031C10D0187930F004000CD1987A26F086F8011C07D0009718885A7A109B41
+:202440001BF06BF9761CF6B26D1C332DE4DBB8F1000F17D0119C204625F050F9061C0AD01F
+:20246000B07C26F06DF8011C05D00097109B3088727C1BF052F9641CE4B2A045EBDC01E0E2
+:2024800011981090BB4890F83000002808BF4FF0620805D026F046FFC0F154005FFA80F89A
+:2024A0000320B8F1600F98FBF0FAA8BF4FF01F0ADDF840904FF6FE7BABF1020BB8F1000FD1
+:2024C0000EBF119D2025DDF84480BA45A6BF3C1C45F040055446032014FB00F0801C8DF890
+:2024E000050001A826F090F84E46031C26D01869082104F01F02017045EA02014170801C38
+:20250000A4B12246C01E361F16F8041F00F8031F318809124170B17801F0070CF178521EF5
+:2025200001F0070141EA0C118170EDD1A3F802B001209876184609F09FFB00E00120E9094B
+:2025400006D2641EE4B20CB109EB84093F1BFFB205F040052843B1D0109808B122F01CFB92
+:202560000F9880F4807004E2B64C1E25002106264FF00408A078002840D0401EC3B2607991
+:20258000A37026F0FDFC071C37D05BB9787B022808BF7E7331D07E733868407BF02121F097
+:2025A000D1FD2AE0A3791BB9787B032813D024E0237913B3E078401EC3B2E370EBB96D4815
+:2025C00090F82500E0702079401EC3B22371787B032812D123B92046394622F03DFB0CE006
+:2025E00087F80D8027F04DFD624B00F00F00401C3881187820211FF0D5FA01216D1E04F15C
+:202600000804B7D15B48007801290FD040211FF087FE494691F82900012811D1002081F828
+:20262000290018F0C3FD25F01BFB09E0402122F093FA28B94F4800784021642227F088FD22
+:202640000F9880F0400094E1102122F085FA30B94848007810214FF47A7227F079FDB34813
+:20266000DFF8CC82417808F52774491ECFB217BB012141700020052126F076F9071C1BD07E
+:2026800006253846052126F06FF90646388978B1401E80B2388158B97889C00802D3387B0C
+:2026A00024F03CFA7D733868407BF02121F04AFD371CE6D100E0477096274FF6FE760025E0
+:2026C0002079A0B1FF2812D0401E2071C0B270B96079032805D16088218802221EF082FC62
+:2026E0006079012803D0268066806571A5717F1E04F10804E4D108F184040827207A401E92
+:202700002072C0B230B99C48214624F06FFB90B9668025707F1E04F10A04EFD1974A0C21D1
+:2027200012F8080F08B1401E1070491EF8D10F9880F010001DE121F09DF9E4E7202122F0C7
+:202740000BFA28B90B480069002808BF01261BD027F0CAFE044627F08BFB8B4F4FF47A7108
+:202760006043B0FBF1F13869002808BF002008D002E0C046E4FA002088428CBF4FF0FF3038
+:20278000081A460869D0FFE70020042126F0ECF8071C62D04FF00009FF254FF0FF3B062407
+:2027A0004FF0010A3846042126F0DEF810903889864204D8801B83B23B8113B14AE0A7F822
+:2027C0000890BB7B012B02D17889C0083CD3ABB38DF804508DF805508DF806B03968086AF5
+:2027E000C97F02AA12F068FFC846012808BFD0465FEA08001DD0788A40F08000ADF836009D
+:20280000B87B8DF838007889000908D3BDF8360040F48070ADF83600387B8DF83A007B69A3
+:2028200013B1187BADF8180001A94A4602A803F0E1FF7C73387B1BF0D5FD0BE087F80DA037
+:2028400008E0C046CC0200207C733868407BB72121F078FC109F002FA4D10FF0FFF84A481A
+:2028600003780121002026F07FF818B1184620211FF098F90020042126F076F8B3B278B1AF
+:20288000414A0789147826F06FF8F8B9BB42AEBF0027FF1ABFB2204627B920211FF082F937
+:2028A00000200DE07A00202127F055FC27F01CFE044627F0DDFA4FF47A716043B0FBF1F022
+:2028C000314908610F9880F0200052E00289BA42D8BF171CD7E727F079FC294C0546201D14
+:2028E0000068074698B1284857F80C1C007821B94FF400511EF012FB03E04FF400511FF06C
+:2029000051F9204639460022001D23F04FFF284627F0E6FD2FB13846FEF71CFF384625F07F
+:20292000C3FE0F9880F4005023E0C046D4130120200100201FF008F9071C17D01149203154
+:202940000A78FF2A0FD03C780B460020944207D0401CC0B2C200D1189A5CFF2AF6D102E0DA
+:20296000496838468847384625F09EFE0F9880F4004013B0BDE8F08F39430200EC0100205D
+:2029800038050120E0B80200E4FA00202DE9F04F064693460020ADF13C0DABF80000B06A03
+:2029A000099303460078884627F084F848B17089044622F091F8022804BFABF80040B36A95
+:2029C00001D0002009901878C84DDFF82493401E0A2800F20984DFE810F02D03B1020A0473
+:2029E0009E028D0151010704BE00880066000B00BD4C207D012840F0F7835B1CB06913F881
+:202A0000015B1F7827F098FB002800F0F5830379002B00F0F183032B80F2EE830E2D1CDC3A
+:202A2000DFB9D04907752DB901EB85010A6BC261096B0AE001EB85010B6B9A01A2EB830286
+:202A4000C2610A6B9101A1EB82018161012180F8201025F005F9002500E001250320B689F1
+:202A6000A47F8DF8190006A825F0CEFD071C00F0C38338690C2100F8011B00F8015B047004
+:202A80000124BC7726F0D6FB786204A9304625F062FA10B17C7704A838627E80BC763846E1
+:202AA00009F0EAF8A8E35C1C207820F01F0700F01F00012840F09883641C04A8214627F03D
+:202AC0006BFB284604A95D3026F092FA002800F08B83002F40F088830834A27861782078EF
+:202AE00001EB022123F06EF986E3688F7189884240F07A835C1C14F8016B04A8214627F0E2
+:202B00004BFB284604A95D3026F072FA06F01F0726F01F06002800F06F83002E40F06C8397
+:202B200078001AF097F8011C00F0668367B184460834384663782278401E04F1020402EB37
+:202B400003222CF8022BF5D100910AF03AFD084622F022F850E35C789A1C34F07F0704F0A2
+:202B60001F0E40F04983377F03201EFB00F0801CC1B2B94240F04083002714F01F0F04BF31
+:202B80004FF6FE7C614618D0D9789B7870464D4603EB012C5378117812F802EF01EB0321C0
+:202BA0003EF0770340F028832B888B4208BF0EF00707521C401EEDD1BFB960464FF6FE72E2
+:202BC000824212D004F06002602A0ED04D462A88A30907D2E30902D2904203DD0CE3904294
+:202BE00003DD09E39142C0F20783B08927F074FA002836D1B0894FF6FF7124F069FD041C85
+:202C000014D123F0EBFC041C00F0F68200211C221BF09CFEB0894D460E3520802888608109
+:202C2000AA23A3740622227401216174207C0C2805DB0620072F2074BCBF7F1CFFB26774B9
+:202C400000202073A01C25F0EFFE002840F0D482307A002800F0D082B169A01C27F09CFABE
+:202C6000CAE20021C171017A0C2905DB0621072F0172BCBF7F1CFFB24772BDE2484671894E
+:202C80000088884240F0B082307F022840F0AC82A94C201D00884FF6FE71814240F0AC82BA
+:202CA000162025F01AFC071C00F0A68201213970B07900280CBF081C02207870B06A407891
+:202CC000B872000902D2B08922F096FDB169B81C27F062FA0020F8742878394620F0DCFC1B
+:202CE000B089A08088E2C046ACFE0020E4FA00201EFB0020708921F0EFFE002840F07482C5
+:202D00005F78B84987B10C2F03F1020380F274828C463D465A7818786D1E03F1020300EBE1
+:202D200002202CF8020BF5D1484675890488DFF8D492AC4200F0B180B37C002B00F05C82EE
+:202D40003B1C0A974FF0000811D0A64A38464146921E32F8023F9C4206D0401E01F101013D
+:202D6000F7D104E018BC02000A914FF00108284600211CF03DFB00280B907DD04079012829
+:202D80007AD10B98807910F0180F75D00B984188384626F003F910B9B8F1010F6CD109F22A
+:202DA0004C704FF6FE754FF000080C97B6F80CB008904FF0010A0D95C14611E0B8F1010F16
+:202DC00008BF4FF0010908D027F05BF9C0B290FBF8F101FB08F1A0EB01094FF00008C246E1
+:202DE000089D32271C3D35F81C4F4FF6FE70A04213D0A34511D00C98214626F0CFF860B9A2
+:202E00006B7C53B1072B08DA08F10100BAF1000F5FFA80F801D1C14521DD7F1EE3D1B34D07
+:202E2000332735F8244F0D98A0421AD0A34518D00C98214626F0B2F898B96B7A8BB1072BE8
+:202E40000FDA287901280CD002280AD008F10100BAF1000F5FFA80F803D1C14501DC0D9402
+:202E600007E07F1EDDD1B8F1000F02D0B9F1000FA4D00D980B994880B37C5A4C581EB074E9
+:202E8000F77C00970A9D0195029401220392B189B269708918F098F8AEE1B4890C2F80F23E
+:202EA000AB818846ADF81040BC488DF812700168CDF8148009B104A8884720461EF0CEFEE1
+:202EC0000C2803D14FF6FE701EF0C8FE0C2880F2938109EBC005D435686808B121F05CFEF3
+:202EE0002FB1780019F0B6FE686010B984E1002068606C80C2486F700078287068780028F2
+:202F000000F07A816868002800F076817A00414626F0C0F970E1307F022840F06581099836
+:202F200028B94D4671892888884240F06581099831460CF08DF85EE1ECFB0020B5F84810AF
+:202F4000404623F065FBA846074608202FB17D781DB90621397007257D70B16A0A79CC789F
+:202F60008B794D7891F802A0CF7904EB02244A7902EB03296A0928BF1020AA0924BF0830CC
+:202F8000C0B235F0700340F03781327F904240F0338105F07005680938BF002006D306A85F
+:202FA000083127F0F9F825F010050820A90907D3B16A091804A8083127F0EEF825F020059A
+:202FC0002046514624F0A0F908280DDA8D4B410001EBC001C9188879B84240F30D818F71CD
+:202FE000002002E0360100200420B8F83A10A14219D048B9B189484601222B4610F0CCFE67
+:2030000028B1F9E020010020042840F0F58006A804AE009049463A465346019620460295C0
+:2030200013F090FEE8E0B189484601222B4610F0B3FEE1E0B5F84810404623F0E9FA4FF0A9
+:203040000609041C03D06078002800F0CD80B06A817847780891C378017900F1050A03EB23
+:2030600001200990404620F063FB9AF8001009185FFA81FAB80928BF4FF00E0937F078006E
+:2030800040F0B28007F01800182800F0AD80307F814540F0A9804FF00009CDF80090089956
+:2030A000B089524643461CF017FA032800F09C80002807F078074DD117F0180F18D195F802
+:2030C000310028B1B089414601223B4610F064FE09984FF6FE714A463B4610F05DFE002837
+:2030E00038D14FF6FF70ABF8000039E0C00D002047F00107780928BF47F00207B0893946CB
+:203100001CF076F990B1817911F0180F0ED0417901290BD154B14088B5F8481023F078FADC
+:2031200020B1437813B1607898425DDCB089414601223B4610F030FE60B94FF6FF70347A47
+:20314000ABF80000002C0CBF4946B169B089524625F044FEBBF800104FF6FF70884243D1AF
+:20316000012000900899B089524643461CF0B4F90998394622F0D8F9698F81422ED109988C
+:2031800026F0AAFF60B10079012818BF022807D1099804A924F0DFFE08E0C04674FD002026
+:2031A00026F048F8014604A826F0F6FF307A012803D1B16906A826F0EFFF06A8009004AF57
+:2031C0000197B06A407840F0300002900999089BB0894A4613F0B6FD48460CE0B06A80F8C3
+:2031E00005A024F05FFF06E04FF00009F4E70999304614F0C5F8099009980FB0BDE8F08FB9
+:20320000C6FE0020A40100202DE9F04FC24C04F128000768ADF14C0D17B1002087F8450073
+:20322000DFF8F082002517F148030BD0BF6DB84E73612FB940460068D0F84C05804773695A
+:203240005868706026F0C2FF1190082016F03CFC1CF09CFC464610B1B2A027F03DF91FF061
+:20326000E3F8684626F040FB042069468DF80000284626F007FDE06326F08CFA09A826F0EE
+:2032800061FC042009A98DF82400284626F062FC606326F089FA0DA826F064FC04200DA90F
+:2032A0008DF83400284626F065FC616BA06319B9A4A027F011F9A06B10B9A7A027F00CF933
+:2032C000E06B10B9A9A027F007F93068D0F8E00380473068D0F8180280473068D0F8F002DD
+:2032E0008047404600682F460726A03001687B5823B11846804740460068A030761E07F128
+:203300000407F3D1D0F8B8028047EB2026F0D4FDA06A2F4670B105A8FF2108221BF016FBF0
+:20332000A06A05A9082225F0AFF904F12806012818BF3768924A0CCA05A8391C80E80C0004
+:2033400021D1082019F086FC5FEA000856D0A8F10206032726F095FE06F8020F7F1E4FEAF8
+:2033600020207070F6D12020F82706F8020F4146082204F1440088F8077025F08BFF4046F2
+:2033800021F00AFC04E004F14400082225F082FF0120082105AA26F031FE04F14406002894
+:2033A00018BF092826D124F022FE80081DD205A8FF2108221BF0CAFA07AFFF21082238461F
+:2033C0001BF0C4FA0120294608223B4626F004FB80B9384605A9082225F056F928B930468A
+:2033E0003946082225F056FF04E001200821324626F00AFEE220314622F00EF924F0F7FD5C
+:20340000400834BF2E1C0126CA4F5520012107F1420226F0F3FD18B916B1284624F07CF880
+:20342000C54FE22007F1440124F056FC30461FF0D9FC05A8294610221BF088FA3846407868
+:2034400030F001000FD1BD4F05A91022384625F01BF928B905A83946102225F01BFF02E088
+:2034600005A823F003FC6220102105AA26F0C6FD28B926B16220102105AA26F0C5FD05A8B3
+:20348000294610221BF062FA304614F04DFE304622F086F8304615F0BFF81EB128460121C8
+:2034A00022F070FD242019F0D5FB0028206400F0A481E06A216B221D1DF0F8F915490968CD
+:2034C000D1F84C138847216C201D0860E06A216B04F108021DF0EAF910F05EFF216C04F11F
+:2034E00008004860E06A216B04F10C021DF0DEF904F1300904F12C08D24ED34F3070D9F855
+:203500000010D8F800C0266C2B4607F1100005E0DCFF002014010020D4DB002006F1080E0F
+:2035200034E0C04652616E646F6D5F736565644175746F6D617469632829206661696C65F7
+:203540006400C04641455343434D206F70656E206661696C656400C0414553454342206F0C
+:2035600070656E206661696C656400C054524E47206F70656E206661696C656400C046C06B
+:2035800004BF020040F823505B1CDBB2002BF9D07D61CEF80020604604F110021DF086F9C6
+:2035A000C54F654EB870308EB880C24831463D703C3126F0F1FD04F110033046216C90F8F4
+:2035C0002500CB60D9F80010787006F14C00F860D8F8000004F114021DF068F904F1180AD7
+:2035E000B649B84AB64E0870B74BBE60206C7A6204F11406D9F800100661D8F80000BB6282
+:2036000052461DF053F9B14EF071022286F824204FF6FE70B08325F00DFEAD48A54906F193
+:20362000140B0560584626F0B7FDAA48FF2138221BF08CF9A848AA4B8360AA4AC260A749D4
+:2036400041600570A84B0361A84A4261AA493961A74B8361A74AC261A84B7B61A84ABA6115
+:20366000AA48A84BA84AFB61AA491061A84FD16006F13000976015F067F909270BF12C00B0
+:203680007F1E40F8045BFBD1F07948F2010120F0CDFBF0794FF4004120F0C8FBF079212142
+:2036A00020F0C4FBF079222120F0C0FB206CD9F80010C0F814A0D8F8000004F11C021DF0FB
+:2036C000F5F8954E48F21501307020F0AFFB3078382120F0ABFB924F0222F760914B86F803
+:2036E00028208E483361216C70614FF6FE7704F11C0304F12002D8F800008B61D9F8001038
+:2037000037841DF0D3F8884AD580D5609570556101271574064615700648177148F202016A
+:203720004670304620F082FB48F20101304620F07DFB05E04CFF0020ACFE002028BC020096
+:20374000304648F2040120F071FB784E78483D49784B3061784A4B60084604F12003826023
+:20376000D9F80010226CD8F80000D36104F124021DF09CF8714B207071499870284626F088
+:20378000EFFB7049384626F0EBFB6F49042026F0E7FB6E49062026F0E3FB6D49072026F074
+:2037A000DFFB6C49082026F0DBFB98784FF6FE71491C20F03BFB68487949684B8862684A36
+:2037C0005A606848684A98600B46DA621846674A83F84670664F0263674BB760654A674FC0
+:2037E0001848674E1360674AC76003461F461E61206C7A6104F12406066213F080FF14F0C8
+:2038000067FD119826F06CFE11F0BCFD24F046FD64480068D0F8D40090F8430024F050FD2E
+:2038200060480068D0F8582429460120904726F0A1F855485B4F05707868C068007860B9C9
+:2038400004E0C0469C0301204819002038460068D0F8582428460146904719F093FE4C4F52
+:203860003D704A48058145818581C581058245828582C58205832B464583464E8583072150
+:203880000360464A43604448357024F0ADF919F055F921F0A3FE22F062F8434840780228C5
+:2038A00004D14FF40040012117F0EAFA13B0BDE8F08FC046E0000120AC000120DC040120E7
+:2038C00065490100F1AB0100859B020034FD00209CFF00206C010020FC0201207DA40000A1
+:2038E000A98802004D0A02007B67020081800200C9600200A9850200058E010001770100ED
+:203900003980020009C3000034040120D5650100D9DE0100E95B0100E80001207D5A0200AD
+:20392000E5730200897C0200F00C012020040120619902005B9F0000DD390200281A002054
+:20394000A19A0200659A0200799A02008D9A0200B5960200CD960200B5350200DC0201204E
+:20396000D94902002D2F020085530200C543020057490200F0FA0020D5410200FD8101009E
+:20398000311A0200AD420200061401208C110120FF130120FE130120EC0000205DA202007E
+:2039A0004CFF002014010020ACFE00202DE9F04FCA4CCB4DDFF838B3DFF838930F46380C1D
+:2039C000ADF11C0D80F05782DFF81883780880F0FD81C64EB80880F0C181B80980F0AA8115
+:2039E000DFF804A3F80B80F04E81BB480668780980F02981380928BF87F0080080F05A8307
+:203A0000780A80F0BA80F80880F0AD802069F90980F09080380A63D2B80A5CD2C44C380B18
+:203A20002BD2F80A27D3142019F014F9061C1FD00025A846207A012813D10096042029464F
+:203A40004246142321F0F6FE58B92068306060682946142233467060042022F0F3FD84F821
+:203A600008806D1C0C34032DE4DB304621F094F887F480601EE300201CE3182019F0EAF855
+:203A8000061C25D000252434A846207A012813D10096062029464246182321F0CBFE58B924
+:203AA0002068306160682946182233467061062022F0C8FD84F808806D1C0C34032DE4DB79
+:203AC0003046414618221AF041FF304621F064F887F40060EEE219F0ADFF87F40070E9E26C
+:203AE0001CF04CFF2078052818D1E07904211EF017FCE07904211DF011FA062025F04EFC07
+:203B0000287800F00700022801D026F083F824F0A7F819F08FFF23F04FFC01E024F0A0F84D
+:203B2000012023F0F9FC0320012104F06BFD87F08000BFE2A0B117F089FB206906682069C7
+:203B400021F02AF826615EB1F28802E0F088801AF0803668002EF9D1E079402126F0FBFA63
+:203B600087F04000A6E2FF20032122F00BFA26F0A9F9C34901200860FEE7424692F84A001E
+:203B8000082818BF04285BD124322120742126F03BFABC4D6868298800241BE0A30003EB15
+:203BA000C403C65C36F07F0212D016F07F06C654034405D101A8FF210C221AF0C7FE01AB5F
+:203BC000012021460C2222F03DFD284629884068641CA4B2A142E1DCB94C4FF0FF085546C0
+:203BE0000026E06995F8211080291FD169798DF809102A798DF808206B88ADF806302888B1
+:203C0000ADF8040085F82180297D8DF80C10EA798DF80B20AB798DF80A30A8690490314684
+:203C2000102201AB032022F00DFDE069761C2435332ED7DB00B180470020022122F0A2F9B8
+:203C400087F4807036E24EB17168087818B1486800781BF0D7FD3668002EF5D126F026F9F2
+:203C60001C34208025F0E6FA484608300078012806D1444620784FF40061642226F06BFA5A
+:203C800087F0100016E20120022123F035FFC4B294B3E00018F0DEFF5FEA00082ED0834680
+:203CA0004FF00109554633262879012818BF02280DD18DF804906888ADF8100001A81FF0A8
+:203CC0000DF920B102A9584626F066FA8346761E05F12405E8D111E02405012034FD00208D
+:203CE000E4120120E4FA0020E40D0020C0FE0020E0120120ACFE00204FF00008B8F1000FE4
+:203D000012D074B10F204FF6FC768DF80C001F25ADF8046001A922464346B148009516F0A9
+:203D200043F8404620F038FF87F48040C2E1C04664FE0020207A50B92078062802D10720B2
+:203D400025F02CFB3078012801D124F03DFDE07910211DF027FF87F02000ABE1207A00BB01
+:203D60002178E07908291AD124F004FF092025F015FBB9480078052806D0072809D1072024
+:203D8000012104F03FFC04E0012023F0F5FF1CF0F5FD3078012816D124F016FD13E01021C5
+:203DA0000FE026F077F8EF2803DB002023F0E4FF09E026F06FF81030C0B226F07DF8E07988
+:203DC00001211DF0EFFE87F0020073E1012025F0E5FA5D466678287900F00701122001296F
+:203DE00018BF02293DD1E6B1032E1AD0012E38D1012936D10A2025F0D1FA444620784FF429
+:203E000080611EF08DFA502005A923F065FFBDF81400A4F84800BDF81400002120F0E2FB13
+:203E200026E025F0B7FE002818BF032E15D1022025F0B4FAA149E06809781FF0C7F8A97914
+:203E400009090ED270B99E4A5178491CC9B20429517004BF9B49E16003E026F012F913F0D9
+:203E60001FFA28B1E07901214FF47A7226F073F987F001001EE1DFF854924FF0000A10E1B6
+:203E80007C052043300501204146934823780E784278701E00F0E280401E13D0183800F04A
+:203EA000FA80B93800F0F3802A3840F0EC8086480168002900F0F28040468847EEE0C0464B
+:203EC000FC020120012A18BF022A40F0E78099F820004E46072818BF082805D1227A1AB93E
+:203EE000012104F08FFB2378032B7BD00A2B11D0042B14D00D2B12D00E2B10D00C2B0ED09D
+:203F0000002B00F0CB8023F057FAE07910211DF049FEC3E0287800F00700012862D0237AC7
+:203F200060785BBB84F80BA05046307120F038FBE0B120780D2819D00E2817D0062025F053
+:203F40002DFA9BF806000BF10406000904D34FF40040012116F094FF307800F007000228B4
+:203F600001D025F057FE23F027FA97E0052025F015FA42F2107024F017FC8FE0012819D1B5
+:203F8000E07A401CC0B20428E07204DB5048007801280DD00EE04F4800884FF6FF71814201
+:203FA00006D003206070012666710423A37201E084F801A022F032FF22F0A0F80BF1060011
+:203FC0000078000903D34448007D012866D16078032863D10820012116F052FF5EE0C04605
+:203FE00098FD0020237A002B33D1E07910211DF0D9FD20F0D5FA28B320780A2808D12978D5
+:2040000001F00701022903D032490822891C0A7003280CD123F0D0F996F82000022806D152
+:20402000012023F079FA0220012104F0EBFA062025F0B4F9287800F0070002282ED025F000
+:20404000E9FD2BE0052025F0A9F9012020F0E4FE24E05046FAE7C0466CFF0020022B1DD159
+:20406000012A18BF022A19D125F08CFF10B116F0AFF898B125F0BCFF00280CBF5046012057
+:2040800021F006FB0AE040461CF026F906E0404616F05AFD02E0404610F0A8FA404624F006
+:2040A00003FBE0791DF050FD5FEA00087FF4ECAE87F4004007B0BDE8F08FC0468DFF0020A9
+:2040C00094FF002000F8FF07F40001204CFF0020AD0001202CFB0020ACFE00202DE9F04F7B
+:2040E000B54CDFF8D8C294F8207088465FEAD800ADF1140D80F092825FEA184006D3DFF8AF
+:2041000004B34FF6FF7AAAF1010A59E1604600785FEA5831A0F1020080F03181B84DA91DDA
+:2041200009885FEA182280F0EA805FEA980180F0D1805FEA183028BF88F4006080F0558352
+:204140005FEAD81080F0A280E7685FEA98305DD2A0695FEAD83138BF0020C0F04683A74932
+:2041600028C96A4628C209881180676938B9384625F0E4FAA061C0B997B90B2011E0017BFE
+:20418000FF2906D031F07F000FD101F07C0104290BDBE06940B9384625F0D0FAA06120B9A7
+:2041A000002025F08FFD2EE0A06160784FF4804143F2C82225F0CFFF94F82010A06908295B
+:2041C00019D00188ADF80010017A8DF80810017B491CC9B231F07F07017306D10188427A0D
+:2041E000684624F011FBA06909E0008800210A4622F088F8F7E7017B41F04001017340698B
+:2042000025F09CFAE06188F48040EEE2DFF8C0B200264FF0030AB14687B96078012E04D0D9
+:204220004FF400511EF07CF805E04FF400514FF47A7225F090FF88F40050D6E27D68287813
+:2042400010B3F02820DC51464A466B461FF084FCD0B1029803889BB984F83E908DF80DA0AA
+:204260008DF80C9003AB0A204946524620F042FADBF8001084F83E9031B12878884703E071
+:2042800001880126491E01803F68C5E71FF05EFE07462078BFB1401EC0B22070A0B16078EA
+:2042A0004FF4804120F058FC30B9606925F046FA10B938781DF06EFA6078402143F6982275
+:2042C00025F049FF207810B90B2025F0FBFC88F040008AE2B0F1FF3F18BF00280CD168465C
+:2042E000002108221AF032FB684617F0DDF918B1607802211DF056FC88F0020075E208466F
+:2043000000211FF0DBFD28460678FF24C6B14FF6FF75001D00212B4610F8142F52080BD324
+:20432000C7884FB1BB4207D055B10289BF1ABAB29542C4BF0C1C151C761E01F10101EBD18D
+:20434000FF2C19D02E49A00000EB0410401818300189C088401A80B250B929484470FF20E8
+:2043600009F030FCFF2120460A4620F0E5F900202349C88024F078FA88F0800035E2B0F14A
+:20438000FF3F18BF002814D13846401E0CD0801E0FD194F8220002280BD1012084F8220052
+:2043A000002020F039FD04E094F82110002021F00DFC88F4805018E24CFF0020ADFE002040
+:2043C00060781DF0C1FB051C08BF88F4004000F00C822F78D32F00F0098194F82000B84251
+:2043E00012D00A2F40F0168194F83F002871A16A002900F00F81A81C88470BE1A8B60200E4
+:20440000F00C0120E4FA0020B94840787F1E00F09680BF1E40F0FE80012818BF022840F040
+:20442000F980AF787FB37F1E40F0F4806F7860781FB325F03BFD4FF6FE720021824218BF1A
+:204440000121081C04D15846408F1146814209D010465F46ADF8100004A9A7F83AA0532098
+:2044600021F0DAF822F0DAFC21F048FE5946002081F84A0019F0E6FBCCE0022140F6B832BF
+:2044800084F82210A7E06878002854D125F0B0FD00210E4603460BF1080063621F460160AB
+:2044A000002F44D1002B38D0002E1F4635D0B146C64824F056F801280CD08D48408E4FF699
+:2044C000FF7181420CD03988884209D01BE0C046E0020120BD4807F10C0124F089FD90B180
+:2044E000BBF83E003989884201D1824501D1FB784BB19BF836007979884209D17C48B97910
+:20450000807B884204D0384621F030FF761EF6B2BF69B9F10109CBD1636A226B002AA9D093
+:20452000184631469047206B002873D1A2E7BF69761CF6B2B4E7002021F0AAF86AE001280C
+:2045400018BF022866D16F7894F845003FB194F84410491CC9B2884284F8441043DB94F877
+:204560002100401E04D0401E3AD0401E1ED051E025F010FB98B994F8460020B1E06A00287D
+:2045800048D0804746E0002102200F468DF808000246ADF80070684624F02EFC13E0012094
+:2045A00025F0F6FC014604F02DF833E0AB2000216A461EF0D9FFCDF808D004208DF80C00AD
+:2045C00002A812F0E9F960784FF480511DF0A8FE607841F288324FF4805125F0BCFD19E00E
+:2045E00021F0D8FA16E001200021DCE7E88948F20101401A0BD0401E05D0801E0AD12846E1
+:2046000019F0DEFA06E0284616F09EF802E0284618F0BCF9284624F047F8D1E66178381C17
+:2046200009D0401E00F0DB80C01E00F0D180801E00F0C080D7E094F83F00C10880F09F8031
+:2046400081087AD20009C0F0CE80062084F8200025F098FC00286CD01FF078FC2569071C7B
+:2046600067D068684078800837D33878032100226B461FF071FA28B968684078410831D213
+:204680000E201BE002980188B52912DAB421018060784FF47A724FF4005125F05CFD544809
+:2046A000416829B10078FF2814BF3878FF208847256968684078400803D2092025F002FBF9
+:2046C0000AE0092003228DF80C0003AB00218DF80D200A2020F00EF82569686840784108F1
+:2046E000C0F0818043490E6826B9800821D37AE0ACFE002038781DF04DF8002600B1012688
+:204700000325301C02D00E2025F0DCFA0C2020706078402143F6982225F01DFD0A208DF874
+:204720000D5003AB00212A468DF80C001FF0E2FF59E00E2025F0C6FA55E0042294F84000F9
+:2047400084F8202040084ED394F84270002F3FD160460078012818BF022844D1012504F13F
+:2047600020000021E5701AF0F1F8032084F8200028461FF0C7FB284624F0CFFC33E004F15D
+:204780002000052594F84010057089080FD394F8421061B90121E170042200211AF0D6F881
+:2047A00084F8205000201FF0ADFB0220E4E72846002111E0002084F83E0084F820003222FF
+:2047C0000846042125F0C7FC0DE0C04648FD002024F03CFB0420012103F014FF03E001209B
+:2047E000014621F0F3F988F0040005B0BDE8F08FDC020120000301202DE9F04FBE48C84C8E
+:20480000ADF1340D06902569406801214FF0E047C06809934FF000080170C24808921F40E6
+:2048200080F800804FF0020000EA020008BF002840F0E682DFF8F092DFF8F0A21E4611464F
+:204840004FF4803018EA060700EA010008BF002833D141464FF4003011EA060700EA02008A
+:2048600008BF00280ED137464FF48000394000EA020008BF002800F0B78285F804801CF0A0
+:20488000B5F9B1E285F80480EB2021F00BFE4A46514682F800800878862801D121F084FEFD
+:2048A00025F094FCE1690A6882F804800968E16125F016FE24F08EFB96E285F8048021F096
+:2048C00059FE81262778A4F80C809949A770994D0860994B2E70FF221A702169069E087AEF
+:2048E000801E81B230684A46D0F8000182F80080C0890B918842C0F26B82E16908310968BA
+:2049000004F1180001600426A6810B98657EA17E04F11902C01E80B2069EE37E0B9005EB83
+:2049200001205178C1F301193168608101F1B80CDCF80010237109780792002908BFB9F163
+:20494000020F00F04582B9F1020F00F3418219B110F0070F00F03C82667800F00705AD1EEB
+:20496000022D08BF002E00F0338231B151460978862902D1002D40F02B82001300F00200E3
+:20498000022864DA35435AD1DCF81C0090F88300022851D0E1690C31097805A80170052774
+:2049A000A78125F013FC554606462878862840D106980068403001680F6837B9D0F80C0546
+:2049C000804706980068006C07689DF9140025F041FC787706980068016C096881F81E8049
+:2049E000006C9DF914100068C177304625F078FD2679678925F0EAFB51460A7807F0100741
+:204A0000862A15D1BA4D05F11E031A88521C1A8087220A7025F064FDE879B04206D11FB99D
+:204A2000404618F001FB07E01B20FAE7E920F8E70646304625F054FD24F0CCFACAE15146BD
+:204A40000878862803D121F0AFFDA77866788FB186B9012F00F0BC816089022F03D110F0D0
+:204A6000070F40F0B581032F05D100F00701032901D0ADE16089010980F0AA81011301F09C
+:204A80000201022902DA810A80F0A28107994978C1F3810BBBF1010F4FEAA1110A9100F01B
+:204AA0009781012900F09481B9F1020F14DA00F00701012918BF03290ED1BBF1000F0BD16B
+:204AC0000A9F002F00F0848106990968AC3109680F78002F00F07C81BC49B9F1020F0DD06B
+:204AE0000A9E11F80B708A5DB918CFB25EB3C10929D3BF1E12E0C046140100200A460A997D
+:204B00000BEB0207891809793A795218C109D7B214D20A995BEA010615D0BF1CFFB212E0CB
+:204B20006811012010050120071401200A140120E813012005140120250001200A995BEAA6
+:204B4000010608BF02270B9AC0F30021781A61718242C0F23D81069E1046C01B4018316887
+:204B600080B2D1F850122081743080B2884700286678606100F02C814146742219F0E6FE24
+:204B800084F8038062891EB9C14902F020000870BF4861790678C446002E30D000292ED101
+:204BA00002F00700032808D0012828D106980068D0F8D40090F882600EB30698406840691B
+:204BC00006781EB124F022FEFE2815D006980068D0F84C02804750B906980068D0F8440249
+:204BE000804720B96289617994F803C007E00420E0706289617901E00420E07084466569F4
+:204C0000268905F1740305F17400AB65079B686093F801A02E812089CAF301190029A5F873
+:204C20005C001878AA8100F0780049EA00004CEA000028744FF0FF06AE730CBF20794046A1
+:204C400085F83AB085F849000A9885F83000A089002FA0EB010086B2A68100F0B480E16927
+:204C6000E78068463A468919083116F03FFFBF19B8B2A0812846017C4FEAAA0212F0030F39
+:204C800002F003076D4601F0400B42D0B9F1020F434601D1C9090BD29DF801209DF80010F7
+:204CA00001EB0221A0F844100DF10205A0F84210814EB0F84410B6F846208A4203D04FF647
+:204CC000FF728A4223D1032F14D06A78297801EB022189B24186B6F84420AD1C01208A4231
+:204CE00014D04FF6FF728A4218BF181C0EE0C0464C02012060692946323025F04DFA606921
+:204D00003B363146323024F073F908350346002B56D00798407886111ED06169B9F1020F91
+:204D200003D0087CC00903D309E05BEA070306D16A782878AD1C00EB0220A1F84200032E0A
+:204D400005D068782A7802EB00220A8504E060692946283025F020FA06990968AC310A685C
+:204D60006089167886B1B9F1020F0DDA00F00702012A18BF032A0BD162692FB94F4BB2F8E8
+:204D800042201B8893421BD100F00702032A05D0012A18D1886A90F88200A0B1D1F89C117B
+:204DA0006069884778B9079881786769407884F80380C1F3011100F078000843387402E004
+:204DC0001BF014FF06E00DF077FE03E0A8C3020024F0F2F825F0FAF9E1690A6882F804804D
+:204DE0000968E16125F07CFB0899099E202047460840374008BF002830D024F0A5F82DE0F3
+:204E00002F4991F90000002803DD91F90000401E08702C4991F90000002803DD91F9000097
+:204E2000401E0870114640461E464FF080770840374008BF00280DD0234991F9000000287C
+:204E400003DD91F90000401E087020480121017024F004FB85F804801BF0C8FEDFF864C037
+:204E60009CF90070B7B108994FF0E0470220374000EA010008BF002816D09CF900000028A8
+:204E800012DC06980068D0F84C0580470CE0C046071401200E48069F80F800803868D0F8B5
+:204EA000582441460846904706984068C06880F800800DB0BDE8F08FDCFF00202200012045
+:204EC000130501201205012014050120110501200E050120964A2DE9F04FADF13C0D00247C
+:204EE0000A918E2309900121101D01708046D47240215171502593712046D0730021D17159
+:204F0000DFF830B21172A02191729089917340F430509081204611681074C44CC24855726B
+:204F2000084084F832304CF21011014300200C909BF80000116058B90C981DF053FF94F848
+:204F40003200000910D30C9808A98DF8200008E094F83200000907D301200DF121018DF8EA
+:204F60002100522020F058FB12F0C9FB24F022FADFF8E4A20B90002840F0C78011F082FD2E
+:204F800000280B9040F0B6800C9804F1240674210D903246212025F031F8002857D10D9906
+:204FA00021207422334624F017FD00284FD1608F4FF6FE7181424AD001200D9094F84A001D
+:204FC000082806D0042804D011F07EFB0C980D903DE0DDF8349042200DF122018DF82290A0
+:204FE00020F01AFB06F12F01432020F015FB06F12C01472020F010FB06F11C014A2020F0AE
+:205000000BFB06F11A014B2020F006FB06F12401284620F001FB06F11601532020F0FCFADF
+:2050200006F12D01542020F0F7FA06F11801E12020F0F2FA94F83200000938BFDDF8309076
+:2050400052200DF122018DF8229020F0E5FA0C9D18E00B9151E00C9AA80000EBC5002946BC
+:205060000C23814609EB07000090012020F0E2FB30B917F80900FF2804BF002007F809008E
+:205080006D1CADB2BAF80000DAF80470A842E2DC10F034FF8A48001D006800B1804720F076
+:2050A000C3FF0D98F0B124F001FFABF81C0028B998F8000000F0F80088F80000C548401CD3
+:2050C0000078022818BF012003D1002184F84A1003208BF8010039360BF11400314625F0B9
+:2050E0005BF801E009200B900B9F74480021002F4180AED0012771480B9794F83C108146A1
+:2051000001208840CBF80C0079E011F0BBFC11F0DBFA04F124022120742124F075FF02A8CD
+:20512000FF210C2219F012FC0C9D56460CE0C046E012012034FD0020294601200C2202AB04
+:2051400021F080FA6D1CADB23088A842F4DC02A8FF21102219F0FAFB0C9D03202946102203
+:2051600002AB21F06FFA6D1C332DF6DB5448006800B1804722F0C4FD002006220C99ADF86D
+:20518000100002A819F0E2FB142017F063FD061C1BD0B1480C300768A7B103270225A8B220
+:2051A00002A90622801924F075F8AD1D7F1EF6D104A93046022224F06DF84C2014213246FB
+:2051C00024F022FF30461FF0E7FC182017F042FD071C10D00C9D1822294619F0B7FB06207E
+:2051E000294618223B4621F02DFA6D1C032DF6DB38461FF0D1FC19F0D3FC304881460B98AF
+:20520000954D01286AD1734E737804F124072BB3012B0DD0022B13D198F8000000F0F8000C
+:2052200040F002000AE0C0460000FFFFE4FA002098F8000000F0F80040F0010088F8000027
+:20524000864823F08EF9002808BF00200DD0042103208BF80A1008E03005012098F8001037
+:2052600001F0F80188F8001002208BF8010024F008FF0999B36B00F07F000818CBF80C30A5
+:205280006430022180B20C90FF2020F07BFE01201AF024FD4FF6FE706087461CE087002012
+:2052A000A4F8486020F044FF0A9801280AD002A80021082219F04AFB02A804E04804012074
+:2052C0001003012000201FF047FD212074213A4624F09AFE0020022120F054FEE8680B9C89
+:2052E00080B9122017F0B6FC0646002EEE606DD04FF6FE70B61F0327411C26F8060F7F1EA6
+:205300007180FAD1002C61D106AB4C200021022224F062FB002852D1BDF8180000284ED042
+:2053200004284CDA182017F095FC03274FF0020800244FF6FE7A0646EB681FFA88F14C205A
+:2053400006221B1924F048FB78BBE868015B8A452BD056B3009620184188002218230620CE
+:2053600020F068FA3069EA6800F2E93333611019418805F13402880000EBC100E968135028
+:20538000081973694188880000EBC1008018E96843600819418818223346062021F052F968
+:2053A00030460021182219F0D1FA7F1E04F1060408F10608C0D116B130461FF0EDFB054B90
+:2053C0007120002108224C3324F006FB24F0E2FB30B101E0ACFE00200120A8700027EF7021
+:2053E0001F48C9F80C001F48C9F8100022F048FB1E481D490860DBF8100050B10BF11004C4
+:20540000076820681FF0C8FB38460028CBF81000F6D109984FF6FF71814217D0012000273B
+:205420008BF800000BF1090201468BF80970852024F0E4FD0BF1090428B9852039460122D4
+:20544000234624F0C9FA0C9823F09EFC22F03CFE0B980FB0BDE8F08F54FE0020E000012076
+:2054600095170100659C020084020120C19F01002DE9F04F0746C44C97F824000026ADF14B
+:20548000840D0128ADF83C6006D197F828102078012902D148B9B2E2207830B9387D0228E9
+:2054A00000F0AD82032800F0AA826078CB4D01280ED1C94821790078884209D097F8380001
+:2054C000E32840F09C8223F05DFF012800F08D824FF4FA60F860E86924F0A3FC40B9E86999
+:2054E000F96824F009FE05F1980024F091FE02E0F9680818F86097F8250002288DF83000B1
+:2055000003D008B9F86A0D9005E00DA807F11801082224F0C3F80CA80DF13E010FAA1AF0A0
+:2055200015FC58B913A807F13401042224F0B6F8BDF83C000DF13E011DF078FF2078012806
+:2055400000F0BB80002840F05A82397D31F0010018BF042940F0538268463146242224F08C
+:205560009DFE384669460BF0CBF997F81780BDF8000010F0070F06D000F0070002280CBFF1
+:2055800014270B2700E00F279DF81900C01987B2384624F081FE5FEA000900F03082044679
+:2055A0006946022224F07AF8BDF80000A41C10F0070F18D000F00700022823D102200DF1EA
+:2055C000080A8DF82400082251460AA824F066F820460822514624F061F89DF810000834B6
+:2055E00004F8010B0EE00DF1040A8DF824600AA80422514624F052F820460422514624F09C
+:205600004DF8241D05A92046042224F047F89DF81800241D04F8010B9DF8190004F8010BCB
+:205620009DF8190068B10799002900F0E8810246204624F033F89DF819002418079824F0F7
+:205640006BFD08A92046022224F028F89DF8220004F8020FB14CE068FFB248B90C2024F078
+:205660001BFEE06000B186604770C0F8049015E0E4680834206820B100F1080420680028B4
+:20568000FAD10C2024F008FE206038B183680BB1866020684770C0F804902068011C00F0E3
+:2056A000AE8181F8008009A808F078FDA869322124F022FD05F174009FE197F83800E32851
+:2056C00005D1206918B18047002800F0988197F83800E2280DD0E3280BD0E02809D0E1282C
+:2056E00007D097F82800012803D0387D032840F08681BDF83C0000280CBFB0460DF13E08EB
+:2057000031462822684624F0C9FD0AA83146032224F0C4FD97F838C0DFF8E8B2BCF1E30F86
+:2057200023D097F8250010F0070F16D000F0070002281AD102A807F11801082223F0AEFF15
+:2057400097F830009DF8283097F838C08DF8100003F0F80040F0020005E0F86A9DF8283030
+:20576000019003F0F8008DF82800BCF1E30F0DD097F829109DF82800C90000F0F70001F05E
+:205780000801014306E0C046200401209DF8281041F008018DF8281097F826309DF8292004
+:2057A0009DF82800190102F0EF0200F0CF0001F03001022B42F0200241EA00018DF82920D3
+:2057C0009DF82A208DF8281002F0F8008DF82A0006DA8BB116E0C04620FB002048190020C0
+:2057E00097F8273043B1012B0CD19DF8290000F0FC0040F0040003E09DF8290000F0F8005F
+:205800008DF82900387D032807D1FB6B9DF82900099340F008008DF829009DF829009DF829
+:20582000282097F84030800100F4006100F4F860084302F030019DF82820014302F0080076
+:205840009DF82820084302F007017A6B8DF818C0084305923043ADF8000023B18DF8193048
+:2058600007F141000790BBF83A00ADF8200097F91500082805DC10F16D0FB8BF6FF06C0031
+:2058800000E00820BB7D6E3040B2002B4FEA60000CBF311C022197F8179040EA81108DF8C3
+:2058A0002200BDF8000010F0070F06D000F0070102290CBF14270B2700E00F27800A06D252
+:2058C0009DF81800E22808BF8DF8196001E03F1DBFB29DF819003F18BFB2384624F0DCFCBE
+:2058E0005FEA000A00F08B8006466946022223F0D5FEBDF80000B61C10F0070F10D000F0E8
+:205900000700022812D102A93046082223F0C6FE9DF81000083606F8010B07E070040120E8
+:2059200001A93046042223F0B9FE361D05A93046042223F0B3FE9DF81800361D06F8010BEC
+:205940009DF8190006F8010B9DF8190060B10799002954D00246304623F0A0FE9DF81900C6
+:205960003618079824F0D8FB08A93046022223F095FE9DF8220006F8020FBDF80000800A5D
+:2059800004D3701C09A9042223F088FE85F85B70F220BBF84870E378C5F85CA0A9F10C06AE
+:2059A00085F85500E188A5F85670002B85F85A6006BF0F204FF6FD71022085F85400B8F1A4
+:2059C000000FA5F84C100AD098F80100800906D305F1580008F10B0123F08CFA66E60CA806
+:2059E00019F062FEA5F8580060E624F0B3FA286AC82124F081FB05F1BC0024F009FC21B09B
+:205A0000BDE8F08FE4FA00202DE9F04FC748C84A0178CD481170CD4D4170CD495C306861A9
+:205A2000ADF12C0D086005F0E9FECE49C948CB4EDFF82CB3091D0A91C74982468946E7E025
+:205A4000480AC0F09980C8489BF800400078012868D024F0A9FA011C00F08A808A7B96F80E
+:205A6000248086F82420778F8A7B08698BF800208A898B7B72870122009200220192012202
+:205A8000029200220392049342780592406800232122069001200790F2200AF009FC8BF8E3
+:205AA0000040C84986F824800F200870DAF80800778750B3AB490C681434276857B102693F
+:205AC0003969914205D007F114042768002FF7D100E097B9DAF80C707FB1786824F01CFB2D
+:205AE0000021DAF80C000A9F4160386824F014FB0020CAF80C00DAF8080024F00DFB002096
+:205B0000CAF808002068CAF80800D9F8181024F04BFA68B30846322124F0EEFAC34824F040
+:205B200077FB25E0B9F85810778F7187C24999F85A008BF8000096F8248086F82400012366
+:205B400000930022019202930392049099F85B000590D9F85C0004232122069001200790D9
+:205B6000F2200AF0A5FB8BF8004086F824807787296921F480712961D9F80C008A0A3AD3F6
+:205B8000071C34D0C468F968A1421FD839468F6800B3D0F80880814210D00246434601E0A9
+:205BA0001A469368B3B1AAB19942F9D198689060184624F0B1FAD9F80C000BE0B4480068ED
+:205BC00024F0AAFA4046C9F80C0003E0F968091BF960BF68002FD5D14CB1D9F81C1030B122
+:205BE0000846214624F088FAAA4824F011FB296921F400712961C80A05D31DF0C9FE296996
+:205C000021F480612961080924BF21F008012961E8684FF0FF3124F05BFC0028F8D02878B2
+:205C20001BF092FF041C00F0418121782878923900F09C80333961D0491F7BD0491E70D0EF
+:205C4000173904D0491E68D0891E61D091E094F84000443080B224F01FFB071C00F089807C
+:205C600004F10408381D0C22414623F017FD20693861207D387594F915007875A07DB875AD
+:205C8000E07D0A2208F11401F87507F1180023F005FD608C788494F8240087F8250094F813
+:205CA000250087F8260094F8260087F8270094F8270087F8280094F8280087F82900E06AC2
+:205CC000F86294F8300087F83000606B786394F8380087F83800E06BF86394F8402004F157
+:205CE000410107F1410087F8402023F0D7FC3846FFF7BEFB384624F00FFA3AE020790028C1
+:205D000037D10A208DF8200008A823F00BFE30E0A188A01D12F07EFE2BE0201D20F08EFB8B
+:205D200027E0CD21002203230AE0C046D4DB00200D140120002108AA08238DF82010C12190
+:205D40001BF07CFA15E0C046C8E800207CFB0020F8FD00207004012048190020E4FA002037
+:205D6000AC0001207804012020040120201D15F0D9F820784FF00108712825DC712851D02D
+:205D8000652810DC652868D0801F77D0423800F0838018386FD0401E6AD0401E01287BD970
+:205DA000801E5DD070E0663854D0801E4ED0801E032871D9001F45D0401E3FD0401E37D031
+:205DC00062E0C0468003012091280FDC912863D07238022860D9C01E20D0401E1AD0401EC6
+:205DE0005AD0C01E58D0801E56D04DE092380DD0C01E012850D9303806284DD91B384BD081
+:205E0000801E012848D9093846D03DE0E76A002F42D035E0A768002F3ED031E06769002F23
+:205E20003AD02DE0E768002F36D029E0BC190020E768002F30D023E094190020E768002FFD
+:205E40002AD01DE0E768002F26D019E0E768002F22D015E0E768FFB112E0E768E7B10FE0B2
+:205E60002746786908B11EF097FEFF69A7B107E067698FB104E0676977B101E0A7685FB1E5
+:205E800038461EF089FE07E04FF0000807E0C04654190020E0190020204622F005FCB8F10C
+:205EA000010F03D014B1204622F0FEFB29698808FFF4C6AD08A80021082218F047FD08A84A
+:205EC00015F0F2FB23F0D4FF4FF4FA674FF47A71B1FBF0F081B207FB01F024F0F5FAFF2044
+:205EE000032120F04FF823F0EDFF024901200860FEE7C0467C0520432DE9FC47D44C0F46B7
+:205F00000646F80B80F00C826078B90F80F0AC81B90880F09F81DFF84C83F90A80F002810A
+:205F2000390B80F0CC80380907D2F80FC0F02E8227F080471AF09AF928E224F047F9814640
+:205F400022F0F2FB002800F0B480082023F0F6FF002840F0AE80802023F0F0FF002840F046
+:205F6000A880684615F0DEFF012803D10098002800F09F8094F84102002840F09A80002537
+:205F80000126E8B223F092FC48B1837A3BB1867290F9090006FA00F0C0B220F04BF96D1CF4
+:205FA000032DEED3032084F8240004F5CE7024F005F9484624F094FAC34800252A460168AB
+:205FC000056050F8081CD44940F8085C04F1600022F0FAFA40460068006B8047A168401A59
+:205FE000010BE06AC1F1FF3282422CBF08444FF0FF30E06294F8300020B12069E16AB1EBC0
+:20600000C02F25D922F0A0FB294600B13146081C1BD0C24840F6090101804580417B06F0FE
+:206020000F0221F00F010A434273017B05F00F0321F00F0143EA010202732946416023F0C0
+:20604000F9FD418811F4406FFBD084F83060E5621DF0F0FDD14829460560022022F08EF80E
+:20606000022020F02BFD112013F038FA207818B96068503024F0C0F8C948007810B90E2063
+:2060800013F02CFA94F8310020B184F83150052020F014FDC348A06284F82450B4F9B400A8
+:2060A000B4F9B610884214BF0220072017F03EFC02E0484624F014FA27F008073AE720B19C
+:2060C000042020F0FBFC0020607065681FF0BAFC38B128462D6A6FF4807100224FF00073FD
+:2060E000A847E06858B140460068006B8047E2686168801AC860000BC8600026E660AA49D9
+:2061000004F16000002222F05FFA0221D4F8A00084F8241018B104F1E00024F075F827F424
+:20612000006707E724F052F8064622F0FDFAD4F898100028894600F08480002900F08180DE
+:206140009A49042504F16000002284F8245022F03BFA304624F0C4F904F5CE7024F02EF8CD
+:2061600040460068006B8047E0604FF0010884F80180284620F0BAFCD9F810006060D9F8D4
+:206180001000816AC90803D3436A29460022984740461BF06FFA606880F81980606813F0A2
+:2061A00079FB6568D5F808A040F60A02D01F564600F1010C00E01E46736833B119888A42EE
+:2061C00003D0884218BF8C45F5D100217160727B08F00F0322F00F0213437373D9F80C206F
+:2061E0001288904224D06046904221D02B8F03B3E96305F13802518095F8440001F00F0345
+:2062000020F00F00034385F8443095F8450008F00F0320F00F00034385F845307260707B38
+:2062200001F00F0520F00F0045EA0001717300E0E160504623F0FEFC5146404621F09EFF97
+:2062400002E0304624F04CF927F480679EE0C04630F500200CF086FBD4F8A00008B927F001
+:20626000020793E08C010010514A116841F08001116020B1042020F021FC0020607023F0A9
+:20628000A5FF80464B480068016804208847216A81421BD1357ECDB1A568BDB1D4F8A85093
+:2062A0006DB1E968098840F60300884204D0E9680988401C884202D106F1140001E006F149
+:2062C00010001EF0A9FC06E01410044040F6C411316171612062404624F002F91FF0B2FB6B
+:2062E00080B1356A30466FF4807100224FF00073A847D4F89800002808BF47F0020701D0DD
+:2063000019F0B4FFF569002130464FF080630A46A84727F0005739E0011C0200F41201209E
+:2063200023F054FFD4F8B06066B306F1280106C90A234FF0E0450B40154008BF002B21D1FE
+:2063400006F1280191E8000306F1280595E8060006F1280322EA090221EA080183E806003C
+:2063600024F0BEF8B16879B1B9F1000F08BFB8F1000F09D03069B6F93010B5684B46424641
+:20638000A84701E024F0ACF827F4804727B104F1E000394623F038FFBDE8FC870000046091
+:2063A00052C30200B9670100F95D010009870200CC210840E00100102DE9F04F4FF0FF08FB
+:2063C0004146ADF14C0D0E910F914FF0000910914E46089609960A96AD4C0B9604F1300BDC
+:2063E0000C96E0680D96494611919EE0E068710306AA042323F040FE119903AA304622F09E
+:20640000FFFB02AA3046012122F0FAFB3046022101AA22F0F5FB069800F0FF0028709DF837
+:206420001900069F6870C7F30140E8709DF80E30AB702878FF2834D0BDF80C70FE2830D063
+:206440004FF6FF70B8422AD107A81EF0F5FFE06871034FF088524FF4005323F00DFEBA4857
+:206460004FF4005750F8041D3F1FBFB2B1F1FF3F07F1885201D1032FF4D810684FF0010A06
+:20648000514600F0FF03FF2B18BF8A46491C000A0529F6DB1060079822F0E4FE5744EF8027
+:2064A00001E01020E8809DF80A00BDF8087028719DF806302F81BDF804206B7129786A8142
+:2064C000E068FF292AD0FE2922D07E291AD07C2912D078290BD0702904D00D99491CC9B2B2
+:2064E0000D9120E00C99491CC9B20C911BE00B99491CC9B20B9116E00A990F96491CC9B2A3
+:206500000A9110E009990E96491CC9B209910AE00899B046491CC9B2089104E009F1010750
+:2065200010965FFA87F9761CF6B2E578B54200F323810D9F002F38D10898022835DA0C9856
+:20654000022832DA099802282FDA4D452BD00C98C0B90898A0B90B980A99084325D021F0F7
+:206560001BFB854219DCB9F1000F14D094F83200FE2120F043FAE5780120DDF8408015E07A
+:20658000012013E0089860B9B9F1000F07D121F003FB854201DC062008E0032006E00220B1
+:2065A000EBE7022002E0119800E004200028A07000F0CC80401E49D0401E00F0AA80401E97
+:2065C00006D0401E00F09880801E00F094800EE121F0E2FA05460C2084F83C5015FB00B0C2
+:2065E000817E84F83D10C07E84F83E0010F0C0FAE2782D1895FBF2F050432D1AE8B284F820
+:206600003200401C90FBF2F15143401A84F831007C201FF0FBF9FF2810D17E201FF0F6F9A0
+:20662000FF280BD1FF201FF0F1F9FF2806D178201FF0ECF9FF2808BF94F8310084F833005B
+:206640000C2110FB01B0808BE0868FE00F9F08F1010090FBF5F184F832806943FF2FA0EBC5
+:206660000100C1B284F8311014D10E98FF2804D10C200E9111FB00B004E00146880000EB3D
+:20668000C100584484F83310808BE086AFE0C0465CFC00203A46D0B2910084F8330001EB32
+:2066A000C2015944898B1729E18640F2A080C91F01AA89B215F046F89DF80F00C0083FD3DE
+:2066C000119F0097BDF81220E18E94F833000323891AC91F01AA89B20CF09AF8002840F0E1
+:2066E0008680BDF81010002900F081809DF814001CF0ACFF7BE0FEE7119EB54226DD3046E6
+:2067000012F08CFE6178E578761CF6B201436170F3E708F1010084F8328090FBF5F1694349
+:20672000401A84F831005FFA88F012F077FE6070FE215FFA88F020F061F9012084F835000E
+:20674000119802F041FD52E00020001111986D1E84F831000C2184F8325010FB01B184F8B8
+:206760003300898BE1867E2120F048F994F83200FE2120F043F93AE00C2116FB01B506AA94
+:206780000423710323F078FC1199304603AA22F037FA304602AA012122F032FA30460221AC
+:2067A00001AA22F02DFA0699163501F0FF0201F0FF00FF2A09D0FE2A07D07E2A05D07C2A05
+:2067C00003D0782A18BF702A0AD1119F47B9C1F38542032A04D19622B2EB116F3FF41EAEF7
+:2067E000304612F01BFE002860703FF4FFAD13B0BDE8F08F2DE9F04FADF1840D1B91CB4906
+:206800001C923CC9064610A83CC00EC980E80E0000248DF84240317F8DF84340B28D8DF8D1
+:206820004D40D6F828C0ADF844400F46ADF85A20F2898DF854706046ADF84A20027802F093
+:206840000303022B8DF8402000F3C38123461D93401C1F9353083CD202F00C0EBEF10C0F83
+:206860000CD053093CBF10F8013B8DF84230BEF1080F04BF01238DF84C3001D08DF84C401A
+:20688000BEF10C0F0AD0737903F00303012B0CD142F00C0273898DF8402004E04578037829
+:2068A000801C03EB0523ADF84430530911D245780378801C03EB0523ADF846300378457891
+:2068C000801C03EB0523ADF8483010F8013B8DF8433010F8013B32F07F058DF855301ED0CB
+:2068E000037833F003058DF8413040F06E8103F0030EBEF1030F00F0688113F0030F00F139
+:2069000001000ED010F8013B02F00305022D8DF8573004BF10F8013B8DF8583001E08DF8A5
+:2069200041401490A0EB0C003F1AFFB2B942C0F24C81C91B8DF85470C8B28DF84D00074354
+:2069400000F04781D00907D370891EF0C5F8002840F03F819DF8402002F00C002146001F77
+:2069600008BF01211E91910933D301211F9180B3B28923F09BFA904202D1F08D000A0ED2EB
+:2069800023F094FA904222D0F08D01460B0A38BF101C07D39DF8402002F0030C2EE07089BF
+:2069A000ADF85A20804623F081FABDF85A10884205D040461BF072FF002800F00A81864833
+:2069C000026810A940469047002840F002819DF84020F08D02F0030C01460B0A0ED2D309D1
+:2069E0000CD39DF8413013F0030F07D102F00C030C2B03D0082B1CBF01231D93DFF8E081A0
+:206A0000BCF1020F00F0C280BCF1010F00F0908012F0030F40F0DD80704A92F82F20012A6A
+:206A200003D1B779002F00F0D4809DF8542002231A92040A9DF84250BDF846B0BDF848A088
+:206A40009DF855E09DF857C0DDF850908DF86430B2899DF84370ADF85C2034D21E9F404605
+:206A60001A30046897B91D9F1FB1104610A915F0DCFD1F9800901C9F0197B07C1B9A02908A
+:206A8000F37C17A910A813F043FAA2E0307C002C8DF8560000F09D8023F008FABDF85C2047
+:206AA000904240F0968030791F9F00901C9D01971B9A02951D9B039196F8300010A90490D3
+:206AC00017A8A04785E0ADF830008DF820308DF8227034798DF833407189ADF818108DF8F9
+:206AE00035E08DF82350ADF826B0ADF828A0CDF82C90307C8DF836C0B27C8DF8320096F886
+:206B000030308DF83420354C8DF83730B4F8481096F83270ADF824101A998DF8387006A834
+:206B2000ADF82A1006F052FE53E0C04620C102001D9FB58937B1000A04D2284610A915F026
+:206B400074FDB5899DF85400B6791030C0B221F0C4FC071C3DD07D81022038703E737C7056
+:206B60009DF854203A7207F110057D609DF84000800928BF01247C721499786822F08AFBFA
+:206B80004046007839461CF087FD22E09DF8417040462230B189036817F0030F10D110A871
+:206BA00007901048ADF8181006A920F01FF980B1062141730068407B21461DF0C3FA08E0FA
+:206BC0003BB110A82246984703E08DF84D408DF8544021B0BDE8F08F80020120E4FA002026
+:206BE000AE000120CB3402002DE9F04FD24CDFF84C93DFF84C83080CADF1140D019180F021
+:206C0000D4810846400838BF0020C0F0D881676823F06AFC054623F02BF94FF47A764FF627
+:206C2000FF726843B0FBF6F081B267B13B887888CB1A9BB2984210DDC01A8242C8BF82B247
+:206C4000FF68002FF2D14FF6FF70904200F095802078012123F07FFA8FE0B87902287FD0F1
+:206C600023F042FC054623F003F997F838204946684301F10A03B0FBF6F03880187890429E
+:206C800066DD97F83600FF2808D197F83800401C87F8380097F8370087F8360097F8356073
+:206CA00097F839300020012101E0401CC0B283420FDD97F8365001FA00F285F0FF052A4253
+:206CC000F3D03618814097F83600F6B2014387F8361097F83400B98F10FB06F2891A89B280
+:206CE0008842C7BFFF2087F83600011C97F8360099F82420FF2818BF97F83A0006D1404695
+:206D00000078642510FB02F212FB05F0788046B9388D3E7A40F020003885386C87F82E603F
+:206D20000BE03A8D4FF6DF70104038853D6C87F82E6097F8342012FB06507862F879CEB239
+:206D400087F82D0007F110007E8406F03FFD10E0B87E97F82A10FA8BE9231EF0C7FE05E013
+:206D6000387CFF2802D0B86921F09EFC38461FF0E5FD207801211AF015FF019880F0010049
+:206D80001DE12878012840F00D8195F8338095F813A06F6995F831006988022220F01AFA1F
+:206DA00005F11C0405F1020B06460020002E02907BD1687F400876D3A87FCDF80CA022F020
+:206DC00071FFBA4605F11009071C60D01C2015F041FF061C59D000211C2217F0B7FDA87FD4
+:206DE000694621F09CFB9DF8010002213075304620F01EFE6888317DB08095F83100FF228F
+:206E0000F07102FA01F0707478680078307495F83000B07495F8331011FB00F0303080B205
+:206E200021F05BFB0746B76127B930461FF086FD00262AE01A20387000237B701A467A8024
+:206E4000E0885946B880B81D21F0FEFCE0783C4BF87303F1200000883882608BB885608962
+:206E60007882A0783875207B787599F80000B87599F80100F87599F902003876039A7A763F
+:206E8000C7F81CA007F13001B962304600E000200028064600F08680274886F80880007866
+:206EA00001211AF07FFE002E7CD0307AA8EB0000B0F1FF3F04BF01200290307CFF285CD01E
+:206EC0006078400828BF4FF00008317DF07C4018404503DCF074FF2088407074B069B17C19
+:206EE000227D806A08FB0100216922F0D3F9029F317D727C012398FBF1F04843A8EB0000AA
+:206F000003FA00F11143C9B27174DFB1401CFF2202FA00F001437174B769B17C207D08FBC0
+:206F20000100B884707CFF280CD1307CB1691CF0B3FBFF20307420E0DC040120ACFE002016
+:206F40000CFB002023F0D0FA074622F091FF1D4B1D4A4FF47A717843B0FBF1F0308093F8BF
+:206F6000241010781F4610FB01F1B87A6423401C10FB01F010FB03F07080F17C327DA8EB45
+:206F80000100801AB0F1FF3F04D0707CFF2801D0029F3FB1E175707C2076BBF8000021463C
+:206FA00015F043FB284621F07FFB084800781AF0CBFD051C7FF4E5AE019880F4004005B0D2
+:206FC000BDE8F08FACFE00200CFB0020DC0401202DE9F04FB74D20F03100ADF1340D0B9087
+:206FE00095F83F00002840F06781687804211DF0B3FD002840F060810B99AF7895F83F00F3
+:2070000001F03F01012F40EA010085F83F00014600F03B810120A87022F0CCF9012805D126
+:20702000562020F081FB08B123F049F8B34C00202071E06808B121F017FFB148476800239E
+:20704000A24680467FB10C247868007821F0FAFF061C05D0327C1AB10020824200F31E81DA
+:207060003F68002FF0D1184620F09AFE002859D1D8F80470002F55D07868007821F0E2FF3F
+:20708000061C4CD0337C002B49D04FF0000844E074690C2018FB00F94C44E079C00838D383
+:2070A000786800788DF814002088ADF81600A088ADF81800079A089B069905981DF0CCFE40
+:2070C000B0B90DF1240B00210422584617F03EFC74694FF6FF700090CDF804B00A23029398
+:2070E00002460392CDF810B034F809104C440AE002681189D388009102F10A00019002935C
+:207100000391049021887868A288007817F0AAF8337C08F101005FFA80F84345B8DC3F6836
+:20712000002FA9D19AF80200DAF80C20162410FB04F081B2562022F061FF0AF10C060A2881
+:207140002BD0092825D021F08FFE562020F0ECFAB0FBF4F0C7B2384620F022FE01281CD039
+:20716000336814FB07F082B20021562022F034FC8AF802700DE041680468CAF814101DF078
+:207180000BFD9AF81000401E8AF8100020461DF003FDDAF814000028EDD108F0EBFE21F024
+:2071A00063FE05F142035520002101221E4622F013FC3078002866D052480078012818BFDD
+:2071C000022843D1504804680021204621F08BFF00283BD122F0DEFC002837D120460AA9E2
+:2071E00005AA17F035FB04469DF82400FD282DD002282BD0032C4FF0000715DA05A83946CF
+:20720000142217F0A3FBFF202146142205AB8DF8240004201FF016FA3C49A00000EBC40067
+:207220000F5009184F604F7285F8427055200121324622F0E9FEFF2003211EF0A3FE687855
+:2072400085F8207004211AF0ADFC54E095F83F000B99072440F0100001F03F0185F820402C
+:20726000014385F83F1000200146FDF733FE10B912F0F4FD3FE0002020F04EF90021204699
+:2072800001F0C0F937E095F83F106878002904BF072485F82040F1D00027D1E7716910FBF8
+:2072A0000411C979C90824BF5B1CDBB2401CC0B2D3E6C0464CFF002095F82100D8B995F8FB
+:2072C000427095F83F1087B10B9880080DD348090BD221F0BBFD0420012101F093F90B9880
+:2072E00095F83F1080F002000B900B9800F03F00084385F83F000DB0BDE8F08FF00C0120CE
+:2073000020050120ADFE0020B800012064FE00202DE9F0430D460146ADF19C0D04A822F019
+:2073200038FF0026304615A920F04EF937460A2800F08681C44C0D2824D1280922D33046E9
+:2073400004A91CF073F820460DF11B01022221F001FC78B90DF147012046022221F0FAFB50
+:2073600040B90DF14B012046022221F0F3FB002800F066810C2022F08FFF002800F060817D
+:20738000044651E1304604A91AF034FA10B9761C052EC7DBAD4E280980F093800DF14701F1
+:2073A00003A8022222F07AF9BDF80C009DF88A50ADF80E00680808D30DF18B000DF10E01B5
+:2073C000022221F0C7FB012827D09DF88A0080082FD30DF18F040DF10E010222204621F0B4
+:2073E000B9FB01280CD09DF88A00042240F001008DF88A000DF18B00214622F04FF95BE0CA
+:207400009DF88A00FF21042200F0FD008DF88A000DF18F0022F042FF4EE09DF88A00FF21BE
+:20742000042200F0FE008DF88A000DF18B0022F035FF0A36304601686C460DF132054368A9
+:2074400021600DF17606018963600A2221813046294621F07FFBC8B90DF1800829460A2204
+:20746000404621F077FB70B9684631460A2221F071FB012820D1684641460A2221F06AFB1B
+:20748000012816D018E020A80A22B5E70DF1760620AD0A223046294622F000F969460A2217
+:2074A000284622F0FBF868460A22314621F052FB10B115A821F003FB384615A91BF0B6FF21
+:2074C000BEE09DF81000C00918D29DF81100400851D304A815A919F079F8002800F0B08078
+:2074E000C5F341110020022908BF01209DF8551001F0FE0108438DF855003CE03046016845
+:2075000043686E460DF176083160018973600A2231816846414621F01DFBB8B90DF13209BC
+:2075200040460A22494621F015FBB0B90DF1800868460A22414621F00DFB28B9404649468A
+:207540000A2221F007FB7BE020A801E00DF176000DF132010A2222F0A1F8C5F34110002142
+:20756000032808BF01219DF8540000F0BF0040EA81108DF854009DF81100800906D30DF1C5
+:207580005F000DF11B01022222F088F89DF81100C00913D39DF855000DF11D01012240F00E
+:2075A00040008DF855000DF1610022F077F80DF166000DF12201102222F070F89DF81000FB
+:2075C000800904D315A9087840F0200008700DF162000DF11E01042222F060F89DF84F0054
+:2075E0009DF850608DF8930015A98DF8946038461BF01CFF20460DF15F01022221F0AAFAB6
+:2076000068B90DF18B012046022221F0A3FA30B90DF18F012046022221F09CFA80B10C2082
+:2076200022F03AFE041C0BD000210C2222F036FE0120A072204622F07FF9204622F06CFD6C
+:2076400027B0BDE8F083C0461EFB002052C002002DE9F04FAF4CDFF8C082DFF8C0B2ADF198
+:20766000340DA0780591090C6ED20598400824BF059880F0010080F081810598800805D381
+:207680000120059FE07087F0020077E10598000938BF0020C0F0728158463230E76A0078DB
+:2076A0000026B146000922D222F01EFF054622F0DFFB236B4FF47A7142466843B0FBF1FCC3
+:2076C00092F82610928EACEB0300824238D8B0FBF2F39BB29942ACBFDDB20D1CB0FBF2F1F3
+:2076E0005143401A80B2ACEB0000206300E00125EFB1C846F878A8420ADD401BC0B2F87026
+:2077000040B109F101061FFA86F93E467F680CE087F803807868002E82460CBFC4F82CA05D
+:20772000706038461DF038FA5746002FE2D1A078B9F1000F04D10021216308211AF0F0FDD2
+:20774000059880F0080019E11AF0FEF9071C00F01281B87FC0B9788CE56A132815D1B7F8A0
+:207760000290281C11D000260188894508D14568002E0CBFE56275601DF00EFA284601E0D6
+:20778000064640680028EFD1E56AB87A97F831102E46022855D1788866B1DFF8E8C13288A7
+:2077A000904204D1B2789CF80030914247D07668002EF4D181468A464646002D08BF002042
+:2077C00004D0012015B16B68002B34D1F18E814237DD082015F03EFA96F82610002830D044
+:2077E000A0F8009080F802A0C17000234360E36A83B9E0629BF83200000911D222F074FE50
+:20780000054622F035FB4FF47A716843B0FBF1F0206300E06860584690F83200000910D307
+:20782000A07808211DF098F958B9A078B28E082122F08EFC05E0401C1D4680B2C2E7F37059
+:2078400096E0514805683878012806D0022840F08F80384618F032FC8AE007F11004B81C96
+:20786000BE8908943B7E0690FA7C07967969099397F819B00A923C7F0B9107F11C0604F0EC
+:207880000C000C280DD0B87F4FF0FE09FF2804D022F008FA041C10D16AE0002D68D06C68BB
+:2078A0000FE0B088FE211EF03DF98146B9F1FE0F5ED022F0F7F9041C5AD0207821F0B8FAEB
+:2078C00005464FF6FF7A0BE0207821F0B1FA054606E0B078FF284BD12D68002D48D06C6816
+:2078E000002C45D0AB68AAF1010823B9A3680BB1B3F8028007E021780220984718B1B0F8CE
+:2079000000801DF049F93389227898450AD03AB943B11CE0AC000120ACFE0020E4FA002013
+:207920009A4514D196F80280B27008980090099B01930A9902910B9A0392CDF810B0079B52
+:20794000069A3046214613F0F7F986F80280307800F00C000C28BCD1B08849461EF0E2F8A3
+:207960008146B9F1FE0F03D022F09CF9041CABD1384620F099FE059880F400400DB0BDE89B
+:20798000F08FC046D2FE0020240501202DE9F04F0E46074630687C68BD68ADF1140D0028AA
+:2079A0003AD022F013FCD4F8E81081460120019008294FF0000088BF0198B168084202D1D9
+:2079C0007168084205D0019880F00100C0B201281DD1D4F8C000B8B9C4F8C060C4F8C46063
+:2079E0000020C4F8D0000146C4F8D41094F8FC30C4F8D810002BC4F8DC100CBF019805203C
+:207A0000D4F8C410087410E094F8F80030B903203074484622F064FD002050E1D4F8C40044
+:207A20004661C4F8C46006233374D4F8C4000021416194F8FC00012808D1022194F8FB0068
+:207A400084F8FC104FF4E0211FF0F0FB706810F0704F06D128B104201FF048F806201FF071
+:207A600045F802201FF042F894F8F800DFF85482002840F0B480E86B3168884240F2AF808A
+:207A800094F8FC00002840F0AA8094F8F90028B1D4F8EC00B0F1FF3F40F0A180484622F0F6
+:207AA0001FFDB768AA463FB1D4F8E800B94609282CBF0220019802E004F1F409002077684E
+:207AC000039037B1D4F8E80009282CBF0220019802E004F1F60700200290DAF80010D6F86A
+:207AE00000B048685FEA0B0540F0020048604ED04046A0F11008D4F8E800ABF1010B092819
+:207B000020D3019803460DE0D8F800108A68398890470346002003B10198031C02D00298F8
+:207B20006D1E3F18DAF800000DB1012BECD0D8F80010C9680A4669469047BDF80000A9F8AE
+:207B400000001FE0019803460DE0D8F800108A68397890470346002003B10198031C02D056
+:207B600002986D1E3F18DAF800000DB1012BECD0D8F80010C9680A46694690479DF8000095
+:207B800089F800000398BBF1000F8144B3D17768DAF80010D4F8F030CA680020134218BF9A
+:207BA0000198102B18BF80F001000028F4D117F0704F06D12FB106201EF080FF04201EF05A
+:207BC0007DFF02201EF07AFFD4F8C010002008740746C4F8C4703E46C4F8C0606EE0D4F891
+:207BE000D800002843D1D4F8DC00002842D1287922F0EEFA4646D4F8CC00326829694068FB
+:207C00005268006891FAA1F1B1FA81F1134602229847D4F8CC0032686969406852680068DE
+:207C200091FAA1F1B1FA81F1134602229847287922F0C8FA287922F0CDFA204629460CF0EE
+:207C400013FB0021D4F8C000C4F8E0100068B0F5806F03D9204629460CF006FB94F8FE0089
+:207C600060B92968486840F00200486006E0D4F8DC0018B9204629460CF0F6FA296848696E
+:207C800040F001004861484622F02AFC94F8F800A0B9D4F8EC1004F16C05284621F037FF84
+:207CA00060B1D4F8C00003210174384609F0E4F92846002121F02BFF00200190019805B071
+:207CC000BDE8F08FD40100102DE9F04FC54CDFF80893207888465FEA1841ADF1140D39D2F1
+:207CE000BE4D281D00685FEA58011AD25FEA980028BF88F0020080F06B8164885FEA181043
+:207D00000DD36846FF21082216F020FE20466946002201231DF0CEFE88F0080058E100205A
+:207D200056E10830002113F0E1FA4C46206818B120F0BAFC002020606868806A1CF02CFF9B
+:207D4000686800248462686820F0AEFC88F001006C603DE119F0F8FE061C00F03781012072
+:207D600037780390F7B996F802A00025AB4617E0A80000EB090759F80000807C82450DD13F
+:207D800005208DF803A061688DF8020009B168468847386820F088FCC7F800B06D1CEDB244
+:207DA000002DE5D03078012850D17068017801F00202022A4ADAC1F38302032A46D1CF11FC
+:207DC00009D0407800F0070101293FD002293DDC30F07F003AD13089273080B220F07DFB29
+:207DE0002578071C32D00020787002233B70F06B06F132010A22786007F1120021F04AFA01
+:207E000007F1080006F128010A2221F043FAB6F84400F883B6F84200B88396F8460087F8DD
+:207E2000210096F9480087F8200096F8490087F822007168328907F1240021F02BFA307AA3
+:207E4000394687F8230028461BF026FC3078022803D1304602F050FC307808287ED1F0787D
+:207E600021F01EF8071C79D0B078002873D02578401E11D0401E3AD0401E4ED106F11C0107
+:207E8000384606F035FE01282AD038461DF004F8002087F8290061E006F11C01384606F000
+:207EA00027FE01281CD097F84100F02853DA97F8260000280CBF0398002097F84050387544
+:207EC00097F8410007F1420187F83800681EC2B207F1410087F8402021F0DCF9257818E053
+:207EE00003203875207839461BF0D6FB36E0042097F8413097F84020387507F1420187F82F
+:207F00003830501EC2B207F1410087F8402021F0C1F9284639461BF0BFFB97F82900E8B131
+:207F200097F825008DF8000097F82500002804BFF86A019005D001A807F11801082221F0AC
+:207F4000A9F926481321016097F830100023684603F0F4F902E038461CF09EFF307805281E
+:207F600004D1304608F012FF0390307804281BD1E068A8B196F84000443014F06BFEE568BD
+:207F8000071C0DD096F840203146443221F082F900201349B860384621F0CCF83046A8472E
+:207FA00030461CF079FF30786168062803D111B1304688473078072803D1216909B13046E8
+:207FC0008847039810B1304620F06EFB88F4004005B0BDE8F08FC0465819002048050120ED
+:207FE000541900209C0301202DE9F04FBF4CDFF80083207889465FEA1941ADF11C0D3FD298
+:208000005FEA590111D32079211D88F83C00E1201DF002FB20F0C6FE0020A8F894000120F2
+:208020001AF0DEFA89F001005CE1E7885FEA990116D25FEA191038BF0020C0F0538194F8D4
+:20804000310050B1E06A94F8301021F032F820B994F83100401E84F8310089F0080041E159
+:20806000002F04BF0020A07007D07F1EB9B24EF66022E180022122F06EF889F0020031E1B0
+:2080800019F062FD071C00F02B81C346387894F83120A178313800F00B81401E00F0BC809B
+:2080A000A13840F01481FE89383E0FD047F6DD70361A40F00C81B8690678002E40F007812A
+:2080C0004078C009C0F0038178885CE089490EC904A880E80E00D7F818A00421504620F092
+:2080E000B2FC3D4606460AF1040010F8011B049606298DF8141010DBFE2918BFFF290FD17D
+:208100000278FF298DF816200AD1401C4278007800EB0220ADF8180002E000788DF81500DB
+:2081200006295ADBFE2931D0FF2912D0287B002840F0CD8068882084002600963346019304
+:208140003246029231460391687C802114F046F9BDE09DF816509BF89600A84205DB002D88
+:2081600040F0B580FF2840F0B28028461DF0E0FF3EB1DBF84C00864203D0CBF84C6020F08F
+:2081800011FEBDF8180020F01BFEA0E09DF8165098F89600A84205DB002D40F09880FF28D3
+:2081A00040F0958028461DF0C3FF002001218140314202D1401C1B28F8DB98F83C108842DC
+:2081C00000F08580207198F82B00642110FB01F20121207821F0BFFF79E02B7B002B76D1E1
+:2081E0009DF815A0BAF1000F71D0BAF1060F6EDA304620F05EFF002869D1AAF10106687C67
+:208200008DF815606B88607004A923840EC904F12C0585E80E005AE0FF2A12D000201AF066
+:20822000DFF90246002000906078B8F894103B4615F0D5FE94F83100002848D0082132226F
+:20824000C7E798F83C007A6801213B46814011420EBF00213844017A5D680020012282405C
+:20826000154203D0C218127A8A4204DB401C1B28F4DB002018D0B8F892002084102600969B
+:2082800021896289002015F0AAFE0120E070A07840B93C20E080207802214EF6602221F0AC
+:2082A0005AFFA078401CA070002084F831000EE004290CDA10480178104820F0FAFE30B9F9
+:2082C00078882081FF2684F83160B8886081384620F0EAF9207819F037FC071C7FF4D6AE4B
+:2082E00089F4004007B0BDE8F08FC046E8000120E4FA002088C2020036FB002000F8FF073E
+:208300002DE9F04FADF1440D0B908069007800210DF12A020F909C2011F020F8B54D681CD8
+:20832000007830F0010009D1002004211FF0E4FB5FFA80FA9DF82A00504402E001204FF02F
+:20834000000A8DF82A000F989DF82A10884280F2DE809DF82A000F99401AC0B20D9002285A
+:20836000C4BF02200D901A2110FB01F000B214F071FC0E90002800F0CD800F980D9F0E9C61
+:208380000C90002F08BF002074D04FF00008B946012645460C9882450ADC0F9940468A45A1
+:2083A00004DAA1EB0A01C9B20C9163E00C9561E0411CC9B20C911FF0B3FB071C54D08E48BC
+:2083C0000146B0F848005D312080A01C21F0E4FE388860820223E375FF222276B87A6076A9
+:2083E0008DF81C503888ADF81E0007A816F0E8FAAB46012808BFB34604F10A00BBF1000FDE
+:2084000006D104F10A00FF21082216F09FFA02E008A921F0C1FE3B797BB93F88002F04BF99
+:208420002575281C04D07448267590F85C00401E207602206075A57515E06F4890F85C00BA
+:20844000401C20763879032804DB26753879032805D106E0022020753879012801D06675FF
+:2084600000E06575A6751A34B9F1010908F1010890D140460D9981424CDD0D9DDFF878B100
+:2084800004F1020804F10A0702264FF0000A4FF001091A3C2D1A0C9987206A4610F05EFF27
+:2084A0005749BDF80A0024F81A0F404621F074FE0DF10201384621F06FFEBDF800004D4BC5
+:2084C0006082587830F0010003D16675A675FF2006E084F8159084F816A09BF85C00401E5A
+:2084E0002076E675638A9DF81200002B60760CBF84F814A084F814900C9808F11A081A37CB
+:208500006D1E00F10100C0B20C90C4D102E000200E900D900B98417C0D9F0E9D8DF82B1087
+:20852000801C16210B9017FB01F0001DC0B28346401C14F08FFB5FEA000854D008F1010415
+:208540000020A2468AF800009DF82A000F9F88F802000D9E88F8037088F8046096B30D9F2B
+:208560002E46241D06F102090A362046494621F013FE08343146204621F00EFE0446A87C49
+:2085800004F8010B688A001204F8010B287D2070697D40EA8100C0B22070A97D40EA01109E
+:2085A00004F8010BE87D04F8010B287E04F8010B687E09F11A091A367F1E05F11A0504F897
+:2085C000010BD2D10D4D0B990DF12B0048F231025B462C1DC4F800A018F0A0FA40461CF0DE
+:2085E000DBFA09346C600E9808B11CF0D5FA11B0BDE8F08FACFE0020E4FA002098FD002001
+:2086000041FB0020FEB5BC4CBC4A0D46014694F83E705078491E00F02C81491E00F00981BC
+:20862000491E00F0C980B64B491E00F0A780491E6AD0491E1FD0491E40F03A810026012D7E
+:208640008DF8016004D0022084F83E0007460DE016F06AFA0D2084F83E00607884F8206025
+:208660000421C82221F077FD94F83E7094F83F0000F0EF0045E003208DF801000FB90120CB
+:2086800020722078002840F035816278606921F055F8002840F02E8110464FF480411CF034
+:2086A0005BFA002840F026810025A561E5611EF049FF60784FF4804119F032FE267A94F85E
+:2086C0003E702EB10B2F03D1284684F83E002F46257294F820106078062906D094F8230083
+:2086E000062808BF84F8235007E084F820500421322221F030FD94F83E7094F83F0000F017
+:20870000F70084F83F00D3E00221012D8DF8011016D0082130F0010084F83E1021D194F895
+:208720004200F0B9002552200DF105018DF805501CF072FF21F0F4F918F08CFB28460EE073
+:208740000025184684F83E50008850863232832021F05AFC032128461DF014FC072020F0DA
+:208760001DFE002084F8200060780421322221F0F2FC94F83F0000F0FB0077E001208DF81F
+:20878000010065B100201F8884F83E00022157863232832021F038FC072020F0FFFD0020A2
+:2087A00084F8200060780421322221F0D4FC94F83F0000F0FD0059E0012818BF022877D188
+:2087C00060780421322221F0C6FC94F83F10606A012D23D00222002084F83E2005468DF8C1
+:2087E000040021F0020184F82050012284F83F1052208DF8012001A91CF00EFF21F090F912
+:2088000018F028FB284620F0C9FD606A00284DD01DF0ACFD606A0028FAD147E001210028F6
+:2088200084F8201066D01DF0A1FD606A0028FAD1FEBD002021F0C6F8042601208DF8016013
+:20884000D0733DB1002084F83E0084F83F00072020F0A4FD002084F820006078314632221B
+:2088600021F079FC94F83F0000F0FE0084F83F001CE0012818BF02281AD1012D23D00120AB
+:2088800007278DF801004FF48051607884F83E7019F046FD00201EF03FFE002084F83F007C
+:2088A0006078022141F2883221F055FC94F83E70A66AFEB18DF800700A20002103226B465F
+:2088C0001BF018FFFEBD002003211DF05BFB04213222607884F8201021F03DFC0820002184
+:2088E00012F0CEFA002084F8210060784FF4805119F016FDFEBDC0464CFF0020ACFE0020F3
+:208900002CFB0020F0B50E467068ADF1140D002800F06381002771687770B24C087858B116
+:20892000487800280CBF381C01202246012110730C32632021F068FB71680D7965B1487997
+:20894000224600280CBF381C0120012150730D326D2021F059FB71688D79ADB90D7ACDB1E7
+:20896000088A10F0070F02D0CA68632A12D9C96820F00AF83846012112F082FA9A4A352039
+:20898000282121F041FB04E0C9794FF4005012F077FA71688D7C45B1888A22462E32022140
+:2089A0001080442021F030FB71688D7D45B1088B2246303202211080462021F025FB71682E
+:2089C0008D7E45B1888B2246323202211080832021F01AFB71688D7F45B1C87F2246921C03
+:2089E00001211070292021F00FFB716891F820504DB191F821002246D21C012110702B20B4
+:208A000021F002FB716891F822504DB191F8230022460A3201211070432021F0F5FA716848
+:208A200091F824504DB191F825002246521D012110702E2021F0E8FA716891F826504DB1FD
+:208A400091F827002246921D012110702F2021F0DBFA716891F828504DB191F82900224686
+:208A6000D21D01211070302021F0CEFA716891F82A504DB191F82B002246121D0121107075
+:208A80002C2021F0C1FA716891F82C50A5B191F82D20102A8DF8002003DD10208DF8000040
+:208AA0000246096B0DF1010020F0F4FB812011216A4621F0A9FA716891F8345055B191F850
+:208AC00035001028C8BF10208A6B0146622021F09BFA716891F83C5045B1086C22463832E4
+:208AE00004211060842021F08FFA716891F844504DB191F8450022460B32012110704B202F
+:208B000021F082FA716891F8465065B104F13C0547310822284620F0BDFB472008212A46AC
+:208B200021F072FA716891F84F5035B101F150020120082121F068FA716891F858504DB1C8
+:208B400091F859008DF811000DF1110152201CF063FD716891F85E5045B191F85F00234A54
+:208B600001211070332021F04FFA716891F85C5035B391F85D0004F1080501212A4628709E
+:208B8000322021F041FA3220394601222B4620F023FF04F1090333203946012220F01CFF7F
+:208BA0001348217A0078012904D04FF4006119F0B7FB04E04FF40061642221F0CCFA71682C
+:208BC00091F860705FB191F861000A4977680A4D087097F86100287001E00220707005B021
+:208BE0000120F0BDACFE002034FC0020B5FE0020E4FA0020291A002070FB0020F0B50E46D5
+:208C00007068ADF1140D002800F06581B068002800F061810025B24C7268757004F10C00CA
+:208C2000177803783FB1B06801210170284603B10846B16848707068637B877847B1B06889
+:208C400001210171284603B10846B16848717068C7785FB1284620F061FCB2680121800B75
+:208C6000917138BF291CB068C171706807794FB1B06801210172B0680C3020F04FFCB1689F
+:208C8000088270684779E18D37B1B068012280F82C20B068C18570688779218E37B1B06878
+:208CA000012280F83020B06841867068C779618E37B1B068012280F83420B068C1867068BD
+:208CC000077AA1783FB1B068012280F83820B06880F839107068477AE1783FB1B068012209
+:208CE00080F83A20B06880F83B107068877AA17A3FB1B068012280F83C20B06880F83D10F7
+:208D00007068C77A61793FB1B068012280F83E20B06880F83F107068077BA1793FB1B06804
+:208D2000012280F84020B06880F841107068477BE1793FB1B068012280F84220B06880F8CE
+:208D400043107068877B21793FB1B068012280F84420B06880F845107068C77B37B3B06844
+:208D6000012111226B4680F846102946812020F033FE9DF80000B16881F84700B26892F8BC
+:208D8000471089B113F066FFB1688864B268906C002808BF82F8475006D09DF800200DF136
+:208DA000010120F077FA00E095647068007C80B1102013F04FFFB1680865B168086D40B14C
+:208DC000012081F84C000B6D10226220294620F003FE7068A16B477C37B1B068012280F8BF
+:208DE0005420B06881657068877CE17A3FB1B068012280F85C20B06880F85D107068C77C94
+:208E000057B1B068012180F85E103649B06808225F3020F03FFA7068077D67B1B0680121E3
+:208E200080F8671020F006FA0146B0680822683020F030FA7068477D87B152200DF1110182
+:208E40001EF04AFF9DF81170B068012180F8701007B92946B06880F871107068877D3FB167
+:208E6000B068012180F87210B06880F873507068C77D237A57B1B06801212A4680F8741004
+:208E800003B10A46B06880F875207068077E617A3FB1B068012280F87620B06880F8771021
+:208EA0007068477E5FB1B06801210F4F80F87810387800B10D46B06880F879507068807E8A
+:208EC00058B1B068012180F87A101BF0CFF8B16881F87B0001E00220707005B00120F0BD08
+:208EE000ACFE002041FB0020291A0020F8B50D4606466868002800F06281002730466F7056
+:208F00001FF0DCFF041C13D11C2013F0A3FE041C00F0578139461C2215F018FD26712046C7
+:208F20001CF070FE20B920461BF036FED12047E1686807785FB1407820B9E1884FF6FE7014
+:208F4000084002E0E08840F00100E080686887785FB1C07820B9E1884FF6FD70084002E0B9
+:208F6000E08840F00200E080686807795FB1407920B9E1884FF6FB70084002E0E08840F02A
+:208F80000400E080686887795FB1C07920B9E1884FF6F770084002E0E08840F00800E0803C
+:208FA0006868077A5FB1407A20B9E1884FF6EF70084002E0E08840F01000E0806868877AAD
+:208FC0005FB1C07A20B9E1884FF6DF70084002E0E08840F02000E0806868077B5FB1407B12
+:208FE00020B9E1884FF6BF70084002E0E08840F04000E0806868877B57B1C07B002807BF56
+:20900000A06820F00100A06840F00100A0606868077C57B1407C002807BFA06820F00200DF
+:20902000A06840F00200A0606868877C57B1C07C002807BFA06820F00400A06840F0040099
+:20904000A0606868877D57B1C07D002807BFA06820F01000A06840F01000A0606868077E44
+:2090600057B1407E002807BFA06820F02000A06840F02000A0606868877E57B1C07E002869
+:2090800007BFA06820F04000A06840F04000A060686890F822705FB190F82300002807BFA7
+:2090A000A06820F48060A06840F48060A060686890F826705FB190F82700002807BFA068F5
+:2090C00020F40050A06840F40050A060686890F828705FB190F82900002807BFA06820F4E5
+:2090E0008040A06840F48040A060686890F82A705FB190F82B00002807BFA06820F40040B5
+:20910000A06840F40040A060686890F834705FB190F83500002807BFA06820F48010A06868
+:2091200040F48010A060686890F838705FB190F83900002807BFA06820F48000A06840F4D4
+:209140008000A060686890F83C705FB190F83D00002807BFA06820F08070A06840F0807098
+:20916000A060686890F83E705FB190F83F00002807BFA06820F00070A06840F00070A060F4
+:20918000686890F840705FB190F84100002807BFA06820F00060A06840F00060A060686820
+:2091A00090F842706FB190F84300002807BFA06820F08050A06840F08050A06001E00220A9
+:2091C00068700120F8BD70472DE9F04FB04E4FF0000A8146ADF1140D57467069CDF808A025
+:2091E000CDF80CA010B1804700B90B27F078002F40F09B8096F8314096F832700146B9F189
+:20920000000FA1F101011FFA81F818BF012155464FF0F80B86F83F1022E0AF421ED0F0683D
+:2092200069036A46042320F027FF009911F4403F1CBF0AF101005FFA80FA01F0FF017C2958
+:2092400018BF782909D1284606215A461FF0E6FC0C2015FB006080F848B0F0786D1CEDB2FA
+:20926000A842DADC401E504503D196F8350000285BD0B8F1000F06F1300500F0CF800398B3
+:209280004FF4005B019096F83F30F06813B9012186F83F106A466103042320F0EDFEB9F1AF
+:2092A000000F05D00099F07811F4403F40F09B80009800F0FF00702803D0204670211DF004
+:2092C0009DFBF06879036A46042320F0D5FE009800F0FF00FE2803D03846FE211DF08EFBB5
+:2092E00038460621FE221FF099FCB800FE2300EBC700FF2186F83C70A200A6F840B04019A7
+:2093000086F83D4000F1180A8AF80030019B86F83E1002EBC4004019A6F84430808BA6F860
+:20932000420001F065FC102801D10020ADE0B9F1000F0CBF10214946B9F1000F07D0B6F860
+:209340004000C0F50050814207DC01200390B6F84000C0F50050814201DD782100E07C21C4
+:2093600038461DF04BFB0DF003FC96F83F300446A8EB04000621FC221FFA80F8181B86F8BB
+:209380003F0038461FF04AFCFC208AF80000029A96F83210F078091996F83E400C27891847
+:2093A00091FBF0F24243891AC9B286F83210491C91FBF0F24243891A86F8311014FB0751BB
+:2093C000898B102905D1611C91FBF0F24243891ACCB20198B9F1000F96F83270029019D0DC
+:2093E0000398B8B11AE096F83F30641C94FBF0F1A8F101024143A6F840B01FFA82F8581ECB
+:20940000641A029986F83F00E4B286F83D40481C80B20290B8F1000F7FF435AF7C201CF006
+:20942000F5FA00240746FF2F1CD17E201CF0EEFA0746FF2F16D196F831700C2017FB005000
+:20944000807DFF280AD0F27896F832008018401E90FBF2F15143401AC7B203E038467E2119
+:209460001DF0CCFA0C2086F8337017FB0050808BF08696F83200FE211DF0C0FAB6F8400055
+:2094800086F83540C0F5005000B205B0BDE8F08F5CFC00202DE9FE4FA84E00900578775D97
+:2094A000002FADF8047000F04681DFF894820D2D4FF0000B4ED0052D15D0072D08D00C2DC2
+:2094C0001AD14068C08A400A28BF4FF0010B13E08478002C08BF07F11B000BD0807D242121
+:2094E00010FB017006E08178012900F02481007CC0192430ADF80400BDF804001EF0EDFF4D
+:20950000041C1FD10C2D40F0168100984068002800F0118120F05AFE444607462068009BEF
+:20952000D0F85413181D8847BDF804001EF0D5FF041C04D1384620F0D3FFBDE8FE8F384658
+:2095400020F0CEFF072D21D0725D009920461FF0A1FE19E044462068D0F8282401A9532051
+:209560009047BDF804104FF6FE70884200F0DE80BDF80410401C884200F0D880009F3889E9
+:20958000002800F0D3803C46052D46D0072D55D1009908782070487860708878A070C878B3
+:2095A000E0700A7ACF798E79487900EB026000EB074000EB06206060A778E7B18F7D27721B
+:2095C00067B1896951B1BA0004F1100002EB47121FF060FE04F11000E06002E00020E06086
+:2095E00020720098806948B31BF0D6FA009800218161817522E01B222272896904F1100027
+:209600001FF048FE04F11000009FE060B8691BF0C3FA00980021816110E0616804F11806C1
+:20962000242230461FF036FE66606169227C06F124001FF02FFE606824306061DFF808A149
+:20964000DFF808910D2D0DD00C2D2CD1009840781A2828D0676837B3F88A400823D309F051
+:209660007CFB20E000994B681878C0F3830200F0020002284DDA33480078904249D15F7866
+:2096800037F03F0745D191F83000022841D109F064FB0098418E4FF6FF728A4203D1406895
+:2096A0008079022817DA50460078BBF1010F19BF4846007800212170214619F0EDFF0C2DA7
+:2096C00039D100984168002935D044462168D1F85413001D2EE0201C1FD054F80C7CAFB93C
+:2096E00010F8021CFF2911D14D46297800F8021C17480A2221461BF0AAFD01280DD12878A5
+:209700004FF4005118F04EFABDE8FE8F1EF0CCFF03E050460078032A02D04446206806E072
+:2097200001220A7019F0B8FFBDE8FE8F2068D0F8541368468847BDE8FE8FC04638C2020032
+:20974000140100201AFB00209C030120E4FA00203C0501202DE9F04F81460D462C20ADF126
+:20976000240D13F077FA071C00F0498120F09EFB698B884214BF012002203870697B2869CD
+:209780000026401A7860687B87F82660B8707C68B87887F827602418207800F00700787094
+:2097A0002078C0F3C100387420780421C0F3401A601C1FF048F94FF00508B861BAF1010F3B
+:2097C00087F81C8006D007F108003146082215F0BDF808E0397F07F10800091920F0DCFC93
+:2097E000387F08303877387C012805D1387F205CB875387F401C38772878DFF80CA200F0E1
+:209800000300012803D0504630300078804687F8018078781FF086FD7877397F28692C7DB2
+:2098200040182861397F7B7F601AC01AC0B22875F8704FF6FF74BC82B869B0F1FF3F32D0D2
+:20984000387C01281CD038B9062078823946484616F06AFC40B30CE0387C022802D00328FB
+:2098600007D01EE0062078823946484616F05CFCD0B104207882394648460BF005F913E0F0
+:209880009AF82F507E82B32075B99AF8651001290AD1B87D19F03AFCB882844218BF301C13
+:2098A00002D1A12000E0A32004463878022806D11FF0C0FC014607F1080020F06DFC002CBF
+:2098C00040F09980514D6878B046012818BF02281CD197F82600012803D097F82700012824
+:2098E00014D1B978F8784018397F4018001D13F0B1F95FEA000809D0B878FA783C7F796848
+:20990000121840461219121D1FF0C4FC38460BF04BFE04466878012818BF022865D1002CF6
+:2099200063D0B8F1000F66D040F203154FF0680A4FF0010900E05C4697F82600012803D08F
+:2099400097F82700012850D1B978FA783B7F786852184146D218121D1FF09CFC97F8260064
+:20996000A34630B997F8270040B1BD8287F8276003E0A7F814A087F826607E8238460BF075
+:2099800013FE041CD8D168463146142214F0DEFF7B8A8DF81190D3B9B88A682803D085428E
+:2099A00015D1FF2011E07868C17B0529C3D12A30FF211FF098FB0028BDD005A8082214F027
+:2099C000C5FF05A820F0EEF8FC208DF8100002A807A9324614F03CFF01469DF81C0020B195
+:2099E000042014226B461CF02DFEB8F1000F02D040461BF0D1F838461BF0CEF800E01024DE
+:209A0000204609B0BDE8F08FE4FA0020ACFE00202DE9F04305468078ADF14C0D1FF0B0FAFF
+:209A2000071C00F03B816878F873DFF888826878F12809D0CD2807D01A2805D0E92803D092
+:209A4000E12818BF1D280CD17889DFF86C92000B80F003813846002104F05EFF002840F0E7
+:209A6000BF8010976B788DF84430A87B8DF845008F4C387C002840F085808B4802685AB103
+:209A8000384619469047012804D179894FF6FE70084078819DF84430787B02282BD17989FA
+:209AA000890826D3E92B24D0CD2B22D0F02B20D0788A7E4B000A08D3B87E30B1B87338688D
+:209AC00000881BF009F8194603E01946887A401CB873B87B401EC0B2B876B87304267E7351
+:209AE000C88D38812078202118F05CF89DF84430787B022801D0062839D1608F398B884277
+:209B000015D0607898B138680088ADF80A00388BADF80800387B8DF80E308DF80C000126CA
+:209B20008DF80D6002A81FF005FD9DF84430788940081CD37E6946B1707810F0030F04D18A
+:209B4000B078317BB2881BF0D1FF79894FF6FE7008407881386800881AF0BEFF002600B160
+:209B600001269DF84430301C01D10BB10FE073B940463E68036830881AF0AEFF28B923B105
+:209B8000984702E010A809F01BFC9DF84430E92B18BF002B07D1396801200090EA7B0888FE
+:209BA00049890BF00FFE94F8320080086ED3787B022802D17889C00806D26878E92865D18C
+:209BC00038461AF01FFE61E03B6818881AF084FF20B94FF6FF70188005205BE0032059E0EE
+:209BE00048460078800826D33968086A18B3C97F02AA0BF061FD6B78E92B07D13968012022
+:209C00000090EA7B088849890BF0DCFDBDF81200396808809DF80D0000280CBF0022402210
+:209C2000BDF81200BDF814100EF026FC18B1788940F0200078816E783889E13E18BFB6F10D
+:209C4000100608D1798911F0300F04D020F019FA00F00700801C388101E0052078736878BF
+:209C6000E92813D04046006800B18047134C206A60B148460078800808D339680888498924
+:209C80001CF0C6FC10B1226A69789047787B022801D106207873A87814F0A4FB07F0DEFE5B
+:209CA00013B0BDE8F083C046C4000120ACFE0020E4FA002008FC002016FB0020ECFB0020BA
+:209CC0002DE9F04F044665692888ADF1440D0027ADF8380016E010FB04F2BB189B780B701C
+:209CE000BB185B88BA181B124B701279401CC0B28A70C91C11E1BDF838007F1CFFB2401C35
+:209D0000ADF83800A878B8420CDD21680BA800906268087D89880EABC2F3C00217F0C0FA46
+:209D20000028E8D1E07A0C2800F09680152840F01081022000EB870080B220F0ADFAB84635
+:209D4000061C00F00681002F4FF0010939D028880025ADF83A00216808A800906268087D1D
+:209D600089880DF13A03C2F3C00217F099FAC8B1BDF82410A800321851809DF8262033183B
+:209D80001A719DF82710BDF83A207F1E05F1010506EB000301F00700587102F10100ADF876
+:209DA0003A00D8D1216808A800906268087D89880DF13A03C2F3C00217F072FA08B14FF07A
+:209DC000000986F8009086F80180216804236768087DA57AB1F804A0109001F1060BF8085A
+:209DE00080F0010000F0010918FB03F0401C044620F052FA071C1BD00146307801F8010BEE
+:209E000000207278824215DC00200090CDF804900121029103900495524605941623069792
+:209E200010980791594606F043FA384620F074F937468BE08200B3189B780B70B3185B88A4
+:209E40001B124B70B3181B79B2188B705279401CC0B2CA70091DD4E73E4606EB4600801CEB
+:209E600080B220F019FA071C73D0002E4FF0010933D02888B0460025ADF83C00216808A8C8
+:209E800000906268087D89880FABC2F3C00217F007FAA0B1BDF8241005EB45003A183B1885
+:209EA000B8F10108518005F101059DF82620BDF83C101A7101F10100ADF83C00DED12168B0
+:209EC00008A800906268087D89880FABC2F3C00217F0E6F908B14FF0000987F800907E70CD
+:209EE000216894F80A806568087D0324B1F804A0109001F1060BE80880F0010016FB04F5EF
+:209F000000F001096D1C284620F0C6F9061C1DD00146387801F8010B00207A7882423FF76A
+:209F2000DAAE00200090CDF80490012102910390CDF81080524605950D23069610980791B5
+:209F4000594606F0B5F9304620F0E6F8384620F0E3F811B00120BDE8F08F70472DE9F04FDF
+:209F6000DFF84C9204460D460020ADF1440D01461F460D9016460E9183460F91D9F808A05A
+:209F8000CDF840B014F0AEF8262803D014F0AAF8252825D1308843F6070181420ED040F688
+:209FA0000201814206D0B0F5C15F19D1F07B022816DD43E0F07B022812DD3FE096F8240056
+:209FC00002280DDD307C0F2838D13169C1F31421B1F5803F04D00F2830D1B1F5A02F2DD11A
+:209FE000002D2BD056B328784FF0010808FA00F01AEA000F22D03046594620F0F5F865607A
+:20A000006C4DA660A86980B110A800900DA90EAA0FAB30460BF0F2FF0E980B214FF6FF72E5
+:20A0200050231DF0A5FDFF2808D020F0CFF882462878022804DB504620F052FA5C46B3E090
+:20A0400000286DD107F088F95B495C4E086840F00200086009A8C9F800601FF00BFE584E3A
+:20A060005849707809AA0B9005F1E00018F012FE554905F58E7009AA18F00CFE09A81FF000
+:20A08000C1FD192109AB3078504A0A9005F160001BF080F84E4A05F17C001A2109AB1BF05B
+:20A0A00079F84C495A4605F5AC7013461AF0B4FC49495A4605F5CE7013461AF0ADFC4748CC
+:20A0C0000068C0F3814030B1454A05F1340004215B461DF089FDB078012802D10E200FF060
+:20A0E000F3FC05F1A0001FF087FB05F198001FF083FB594685F8241085F83010072085F87E
+:20A100004002A960E962374B1970E960052685F83110354A2E610420AA621EF02FF8287859
+:20A1200005EB8001401CC1F8B840C0B22870504620F0D6F91FB901A81FF086FB01AF3868C1
+:20A140004FF4FA76E6602060B8694146A062388A61766083F8692063786800280CBF40F673
+:20A16000C410594620616061204E266266622176E661F86800B12062786900B16062B86887
+:20A1800000B1E061C82204F13800594614F0DEFB04F1500059461DF0CDF815495A4604F191
+:20A1A000B80013461AF038FC204611B0BDE8F08FCC21084030F5002000200940110000E031
+:20A1C00050C302000D9302007D880100011C020015090200E9860200FD8C0200B44F005034
+:20A1E000E5360200FD130120B967010077F500005DA102002DE9F04715469F4A13680F4623
+:20A20000ADF1A00D23A90B6053684B6012890A8101A91DF0D9F98046B8F10A0F00F0278187
+:20A22000B8F10D0F00F0238112A801A902221FF035FA814601A9022268461FF02FFABDF8CF
+:20A24000000010F0070F13D0BDF8000000F00700022818BF022413D10DF106014846082291
+:20A260001FF01CFA0B240DF10E010122814603E00DF10A010422062448461FF00FFA8146EA
+:20A280009DF80500800908D30DF10F01484602221FF004FAA41CE4B281469DF805008011AB
+:20A2A00041080DD30DF11101484601221FF0F6F981469DF80500641CE4B28011410803D290
+:20A2C0009DF8041089090BD30DF11201484604221FF0E4F981469DF80500241DE4B28011EB
+:20A2E000400808D30DF11601484610221FF0D6F91034E4B281469DF80400C0093AD3002058
+:20A300000DF1260A8DF898000A22514623A81EF021FC2646641CE4B278B901220DEB060065
+:20A3200026A98DF8982048301FF0B8F951460A221FF0B4F90A34E4B281460DF1300A23A8BC
+:20A340000A2251461EF006FCA0B99DF898000DEB060326A90122401C8DF8980003F14800FC
+:20A360001FF09CF9484651460A221FF097F90A34E4B281469DF80500400836D39DF83A30C4
+:20A3800026460020641C8DF89900E4B2580811D301220DEB06000DF199018DF8992048304A
+:20A3A0001FF07CF90DF13B0104221FF077F9241DE4B281469DF83A00800816D39DF899002E
+:20A3C0000DEB06030DF199010122401C8DF8990003F148001FF062F90DF13F0148460422AF
+:20A3E0001FF05CF9241DE4B281460DF14301484601221FF053F981469DF80400641CE4B297
+:20A40000000903D39DF80400400906D211A9484601221FF043F9641CE4B217B9287818BB94
+:20A4200020E02878264608B1A41EE4B20DF1020102222018ADF8020038461FF02FF92878A6
+:20A4400000B9BF1C422E0744A8BF012010DA3246384612A91FF022F92878002818BF9DF82C
+:20A46000020003D1A41CE4B2287800192870404628B0BDE8F087C04648C002002DE9F04F80
+:20A480008246ADF1240D12980D460890287A984617464FF0000B012818BF032808D1BAF1BA
+:20A4A000000F05D0BAF1FF0F02D0032802D10FB95C4612E104A80A221EF0ECFE894C207895
+:20A4C0008DF81A7020BB0420874E8DF800003088ADF802001EF0AEFE01AE014630461FF080
+:20A4E0006FFC68460BF078FA1FF0CEFCBDF8021081420BD04FF6FE71814207D0ADF80200A3
+:20A5000030461FF0EDFD68460BF066FA01202070287A4FF004095C468DF80090022815D05E
+:20A5200003280AD001281CBF4FF6FE71ADF80C1017D12888ADF80C0012E001A829461FF03B
+:20A540003FFC684616F0E2F838B109E02888ADF80200684614F034FA10B968460BF03CFA81
+:20A56000287ABDF80C10012819BF3A1C271C0127221C4FF6FE70884200F09B805B484B46AC
+:20A5800026460E3810F80E5FDFF864C1554508D14578BD4205D145888D4202D105799542CF
+:20A5A0004DD05B1E06F10106ECD1002C48D14F484B4626460E3810F80EEFBEF1FF0F04D095
+:20A5C0005B1E06F10106F6D173E080F800A0477004464180B8F1040F0271C8BFC8466046A6
+:20A5E0008168B8F1000F17D0089D4746E146AD1E35F8022FADF81C2011B104A888472A8881
+:20A600001146504601235A461DF08EFBD9F808107F1EEDD14FF0010B089984F80580A01D05
+:20A620004FEA48021EF036FE3048330131460E22A3EB46031B1802201CF004F839E004466B
+:20A64000B8F1000F35D0089D4746E046AD1E35F8029F204649461DF0EBFD40BB34B36079A7
+:20A66000042823DA04EB4000A0F806906079401C60711E48330131460E22A3EB46031B1803
+:20A6800002201BF0DFFF08F108002A880168ADF81C2011B104A888472A88114650460123B2
+:20A6A00000221DF041FB4FF0010B00E000247F1ECDD1BBF1010F10D10E48007880211AF08F
+:20A6C0004BFA40B11CF0EAFA05461FF0F3FA0121284619F0F3FB1CF0F9FA204609B0BDE8C3
+:20A6E000F08FC046FC0201201EFB00206C010020DC0201204DFF00202DE9F04F07460020C3
+:20A70000ADF1340D002106900C22079003A814F01DF907F1240414F8011B01F00300C1F329
+:20A720008018089000208DF80C00CE110A901AD020460078022500F00701641CC0F3C103E1
+:20A74000C0F380198DF80C10C0F340120993B9F1000F0B9218BFB8F1000F40F00281184675
+:20A76000012805D1FDE081460B9001254B4609930898012824D09DF80C0050B1022812D1DC
+:20A7800014F8010B6D1C07F1080108220A90032004E02146022004222D1D241D387404A8BA
+:20A7A0001EF078FDEDB268460021082214F0CEF804A8694608221DF067FF002840F0D18013
+:20A7C0000998022810DAA3469BF80000E02803DBB8F1010F00F0C58097F8223097F82300E1
+:20A7E0000793401BC4B212E007A8214604221EF051FD97F823002D1D211DEAB28B46801A23
+:20A80000001F0422C4B206A809191EF043FD089801281AD1002E40F0A4809BF80000F0287E
+:20A8200080F29F800998002840F09B80B8F1000F0BD1002001464C4A8DF800001226019193
+:20A8400001231660684600F079FD04F1440080B21DF043FE061C00F0848004203070012195
+:20A8600031750025757097F92000707597F82100B07597F82200F075387CB9F1000F2A46CB
+:20A8800086F8200018BF0A1CAA46B8F1000F914618BF8A46022808D0032808D106F11800E2
+:20A8A00004A908221EF0F6FC01E038893083B88B7084089D86F824509DF80C0086F825005A
+:20A8C000099D86F82650DDF82C8086F8278086F828A086F829900498F062DDF8289086F8C2
+:20A8E0003090079B7363069AF2639BF8000086F8380000201BF0BEF930710020B060FF230D
+:20A90000F3607868306120201DF0E7FD0746174890F800A01FB930461DF0C6FE21E01449F1
+:20A9200030461EF007FC0720387000237B70307959462246387706F141001EF0ABFC86F8E9
+:20A94000404087F81090079887F8158003A93D750C22B861381D1EF09DFC5046394618F0E7
+:20A960009BFE0DB0BDE8F08F480501209C0301205C190020F0B5064600240A20ADF15C0D54
+:20A980004FF6FF7502228DF85B0021468DF85A403768ADF80E500DF1560013F0D7FF9DF810
+:20A9A000560007F0070100F0F800014341F018018DF85610BDF85600203D21460540F808CD
+:20A9C00000F020002843C7F34115ADF85600012D08BF01212246032D08BF01229DF856006D
+:20A9E00062F39F1040EAC11022468DF8560005B901222046022D08BF01209DF857103B0977
+:20AA0000022D01F0E00140EA010003F0080141EA000141EA02118DF8571009D09DF85700F3
+:20AA2000F90A01F0200100F0DF0001438DF85710C7F34120012899BF9DF8570000F0BF00CB
+:20AA40009DF8570040F040008DF857009DF85710022201F07F019DF856008DF8571040EA2C
+:20AA60000120ADF80C0003A90DF112001EF016FE306810F0070F13D000F00700022818D18B
+:20AA800005A806F1080108221EF008FE022006F1080108228DF8000001A81EF0FFFD08E05F
+:20AAA00006A8311D04221EF0F9FD8DF800407068019007A806F1100101221EF0EFFD3068D6
+:20AAC000400C34BF0DF10E0106F134010DF11D0002221EF0E3FD30689DF85A700122400A6D
+:20AAE00000F01C0100F00300084347EA00018DF85A100DF11F000DF15A011EF0CFFD08A8EA
+:20AB000006F1200104221EF0C9FD09A806F1240110221EF0C3FD0DA806F1110108221EF060
+:20AB2000BDFD0FA806F11A0102221EF0B7FD0DF13E00FF2110221FF0B1FB3068C0F34110C7
+:20AB4000022820D1BDF80C1012A80122C1F300211FF0A4FB0DF1490006F11C0102221EF01C
+:20AB60009DFD3068400C0BD2684614F09DFD04A9ADF810000DF14B0002221EF08FFD0DE0D8
+:20AB800006F13401F6E712A8214601221FF086FB0DF14B00FF2102221FF080FB0DF14D0076
+:20ABA000FF2104221FF07AFB0DF1510006F1360101221EF073FD9DF8120000090BD29DF88B
+:20ABC0001200400907D20DF152000DF15B0101221EF064FD05E00DF15200FF2101221FF07E
+:20ABE0005DFB31680DF11200FCF792FB17B0F0BD2DE9F04F994E96F83D0096F83F10F37811
+:20AC000096F83C800027ADF12C0D0918491E91FBF3F296F83D4077705A43891AC9B20891AD
+:20AC2000810001EBC0018919B1F84C0096F83C10ADF81C00880000EBC1008019B0F84C50A3
+:20AC4000CDF8248006A81AF0F7FB70780A97A04500F0A180B946CB46BBF1010F00F0908096
+:20AC6000BDF81C10162966DD002840F09580BDF81C0001AAC01F81B2ADF81C10204610F03F
+:20AC800061FDBDF81210BDF81C30884608F1070008F1100287B29A4246D89DF80E00962811
+:20ACA00042D19DF80F00420839D2800837D3BDF81C0000230093A0EB08001FFA80FA9DF8B4
+:20ACC0000D20BDF81C002346401A80B21BF07EFAF8B9E819B0F5005F15DCF068C5F188526F
+:20ACE0000AEB443A3B46D21B514602F500521FF0C3F9ED1909F10109ADB2B5F5005F08BF8F
+:20AD00004FF0010B0BE0BDF81C004FF0010BC01D2EE0BDF81C00401EADF81C0004E0BDF86D
+:20AD20001C00A0EB080023E0204607A916F0C4F801281FD030E0F278B9F1000F07D0484BD4
+:20AD4000BDF81C70A10001EBC401C9188F830899A14220D04249641C94FBF2F05043241AAC
+:20AD6000E4B2A00000EBC4004018808B4FF00009ADF81C0009997078A1427FF46DAF0AE09C
+:20AD8000B9F1000F07D0364ABDF81C70A10001EBC40189188F8320B106981EF063FA102053
+:20ADA00059E0DDF824804FF6F0704FF40051C5EA0040C5EA0141E1FA40F01FFAA0F283B2DD
+:20ADC000102102F18852404618F058FF71780843707006981EF046FAA0450FD1F278204FF2
+:20ADE0001019401E90FBF2F15143401AC4B2A00000EBC400C019808BADF81C00184FBDF8EA
+:20AE00001C00A6F840504FEA8801A6F8440001EBC80186F83E40C9198D83B6F9422096F802
+:20AE20003D10012340461CF0CBFE96F83E10B6F94420022340461CF0C3FEBDF81C001628D0
+:20AE4000DCBF01200A90B5F5005F03DB0A9840F002000A900A980BB0BDE8F08F5CFC00204E
+:20AE60008CFC00202DE9F0410546A88CADF1380D0328C0F22881954F0024069507F1180048
+:20AE80000B94AE6A09940822ADF828402146056007A81FF003FA079816F8012B20F00700B0
+:20AEA00002F00301C2F380030143104641EA830102092CBF41F0080121F00801000960F375
+:20AEC0000411079133B171783078B61C00EB0120ADF8200016F8010B8DF82200AB6A16F8C9
+:20AEE000010B0996AA8C8DF82300F61A901BADF82800287D1EF0D6FEB846002800F0E18043
+:20AF00008068002800F0DD80408800909DF82330079AA988287D02F003021AF0DFFF002816
+:20AF200000F0CF801EF02EFF0246D8F80810A888012741B18B88834202DCCB88834203DA72
+:20AF400009680029F6D121460798002900F00306C0F3800034D050EA060303D19DF8233032
+:20AF60000B2B2DD0D2092BD36B7E4BBB0699487D002840F0A6804888002840F0A280224642
+:20AF80001EF07CF8079E9DF82300069A8DF83000F00880F0010000F001000090BDF820506E
+:20AFA00001959DF82200911D0290107D92888DF831700CAB1AF098FC3A461EF05FF880E09D
+:20AFC000002E4BD1002847D19DF82300172841DA3F4E56F8301000293CD0287D8DF810004B
+:20AFE000BDF82870ADF81270099D059504A888470B9048B906994F7D002F62D14F88002FB3
+:20B000005FD10798802743E09DF8231006EBC106716819B106A888470B9808B11FF07CF818
+:20B020009DF8231031F002004BD0032949D0052947D0062945D0082943D00C2941D0112978
+:20B040003FD013293DD015293BD00B2939D02746069915E08227FBE78427F9E749B1896810
+:20B0600039B106A888470746FF2F2AD00798C0F380000699012F03D1002814BF8327812732
+:20B080004E7DF6B94E88E6B90798420900D3C7B1C0089DF823208DF8317080F001008DF8D0
+:20B0A000302000F001000090BDF8206001969DF822000290087D8A888B1D19460CAB1AF04B
+:20B0C00013FCC8F818400EB0BDE8F081800301204CB502002DE9F043054697484278ADF103
+:20B0E000B40D8DF8012000218DF8B21088468DF8008082788DF80220C2788DF803200830F3
+:20B1000058C802AA58C209C8C1464746464682E809002979CDF80490C1F3C1008DF80810D8
+:20B1200040BB11F0070F13D001F0070102291DD14FF0FF30039005F10801082204A813F02F
+:20B140004AFF06A805F10801012213F044FF0DE003A805F10801042213F03DFF04A8FF21C8
+:20B1600008221FF09BF8FF208DF81800FF208DF8190013E0012811D14FF0FF300390FF216B
+:20B18000082204A81FF08AF8FF2005F1080101228DF818000DF1190013F01DFF4446204644
+:20B1A0000DF12A011CF010FA30B99DF80100401CC3B28DF8010001E09DF80130641C052C22
+:20B1C000EDDB9DF80800C0F3C100012842D1002B00F0A2809DF819409C4200F39D80062C0F
+:20B1E00012DA9DF8B260204641460DF1B202FFF701F848B99DF8B2004A2803DC641C062CE3
+:20B20000EFDB01E08DF8B2609DF8B20010B39DF8B2001FF041F8071C1CD041468DF80380B5
+:20B220009DF819408DF8B210062C13DA204639460DF1B202FEF7DEFF60B99DF8B2309DF82C
+:20B2400003009E4200F101008DF8030002DD641C062CEBDB9DF80810C1F3C10000284ED1D1
+:20B2600011F0070F0CD001F00701022947D102208DF81C0004A9082208A81EF00FFA03E05B
+:20B280008DF81C8003980890FF208DF802000DF16E010AAA07A814F059FDA0B99DF8B240AA
+:20B2A000BDF8280041460DF1B202FEF7A3FF30B99DF8B2004A28C8BF8DF8B24006E04146D4
+:20B2C0008DF8B2101BE08B208DF800009DF8B200A8B19DF8B2001EF0DFFF071C0FD04146A0
+:20B2E0008DF8B210BDF828008DF803800DF1B2023946FEF77FFF10B901208DF803009DF877
+:20B3000019008DF8020028680197694610F03CFC38461EF001FF0BE09DF819008DF80200D2
+:20B320008DF8008028688DF80380694610F02CFC2DB0BDE8F083C046E8C002002DE9F04F9F
+:20B3400005460020ADF1340D8DF81A0028789A46894658B1022840F01A81291D04A808229B
+:20B360001DF098FF4FF00808032006E04FF6FF704FF00408ADF810000220DFF818B28DF8D5
+:20B380001800002701E07F1CFFB2D7B95BF82740002CF8D02E7820798642F4D104F108003A
+:20B3A000291D42461DF070F90028ECD0022E02D0002EE8D105E0B9F1FF0F02D0207C4845E4
+:20B3C000E1D1012F00F0E380B90001EB0B0000245BF801700790BAF1010FFC7009D12046A2
+:20B3E0000090012122460190234602908A46039108E02246009201920292012003902B78E3
+:20B400000DF11A0051461AF0FFFF8346079800685FEAEB1600F1170500F10407017C90F84D
+:20B4200016900995437C08919DF81AA00A930BD09DF81A00C0F3C100022803D0032818BF87
+:20B44000032602D10B2600E002261BF0030F07D13D78022D02D01DB9361D00E0761CF6B2C9
+:20B460004E44F6B2304611F0F5FB00280B9046D005465FEAEB1805F801BB18BF05F801AB82
+:20B480001BF0030F11D13B78022B0BD06BB9387905F8010B787905F8010BB87905F8010BE0
+:20B4A000F8790890089805F8010BB8F1000F0DD0CAF3C100022818BF032807D105F8014B7A
+:20B4C00005F8014B05F8014B05F8014B0A984A46099905F8010B28461DF0DCFE4D44B8F125
+:20B4E000000F0CD0CAF3C100022818BF032806D105F8014B05F8014B05F8014B2C70DDF894
+:20B500002C80B8F1000F42D0B1460798224E00687768C57890F812A027B170681DF0C4F878
+:20B52000204670602C201CF0D8FF074677605FB3680829D2384621462C2213F007FA4FF689
+:20B54000FF7BA80803D3F88A40F00100F882F88A052540F4807004A9F8820A22FC7607F131
+:20B560000800BD761DF096FEA7F812B0C7F828803C7587F82790094887F815A032680078A9
+:20B5800001211EF0E8FD02E0404619F005FB0DB0BDE8F08F58190020480501209C03012085
+:20B5A0002DE9F04F0546ADF1140D02911EF00EFE8A4C012D039000F0D280A346DBF80000EA
+:20B5C000D0F838038047002800F0C58016F0DCFF002800F0C080DBF80410864C8969606898
+:20B5E0000F783C30002F40F0B6807D4E0068357880477168F268AB00401AB0FBF3F7B06837
+:20B600004FF00008C2469146534611464F4573EB0A0301DA884206D84146524687428A41DF
+:20B6200043DA024600E041461046EB172A46C01B71EB08011DF08AFF07466F480068884666
+:20B64000418B00694018643081464FF00001B7EB090778EB0A08784271EB080125DA1EF06F
+:20B6600007FC024653464146384614F04CFC884607464FF00001784271EB080115DA1CF020
+:20B6800059FD054630691EF09DFA10B130691EF095FD28461EF031F8306939461EF08AFD7F
+:20B6A00030691EF089FD002000E001204D490870884698F8000000284DD1DBF80000D0F8EF
+:20B6C000940000780027394615F05AFC00B101274FF0000A381C3CD1DBF8040080690078A2
+:20B6E000002836D16068404D436C286902216A4698479DF8000060B302984FF00109012820
+:20B700001ED03A4F6268286997F9001011F1020F05D0926B97F90010904762682869344E7E
+:20B7200096F9001011F1020F05D0926B96F900109047626828696FF001013170397001E028
+:20B7400062682869DBF80410896981F80090D169884788F800A003981EF0C2FE3AE0206878
+:20B76000D0F894000078012115F00AFC03981EF0B7FE606880690078012811D11DF0C4F86D
+:20B7800060B1606880690178012909D10021029F0170012F04D01DF085FE01E00FF096FE2F
+:20B7A0001DF0B2F8B0B960680C30C1680978022909D101680F7837B12068D0F84C05804776
+:20B7C000241D20680C3001680F781FB9C16808780228FCD005B0BDE8F08FC04614010020E9
+:20B7E000D800002008140120700001200C0501200D050120DCFF0020800001202DE9F04F2D
+:20B80000002124220823ADF12C0D68461EF058FE7C4E002421466A4606F138058DF8184097
+:20B8200028461EF049FE06F10C0000F1040B05601EF03EFEF16806F1100215F037F830705D
+:20B8400086F8244086F82540B48316F011FD4FF0080806F1280080F800806B49316310F02A
+:20B8600051FE6A4D287830B9694A204614211AF06DFB012028700C201EF00EFD6F68B146AD
+:20B8800088B1046009F1540180F80480816037B9686008E011467FE0114654E00F46396808
+:20B8A0000029FBD138601EF05DFA5A4D40460A212A1D1AF02FFB584E776840461CF0EAFDC5
+:20B8C000F0B1DFF858A12546BD4208D03879082814D03B6803B93D461F46002BF6D10C208B
+:20B8E0001EF0DAFC60B10460514680F8048077688160002F0CBF7060286001E05146B960B9
+:20B90000474DF22705F13C00077005F16001696410F0F8FD434E307830B9434A2120014681
+:20B920001AF014FB012030700C201EF0B5FC716868B1046005F12C02077173688260002B68
+:20B9400008BF706003D00A68002AA5D10860374A38460C211AF0DEFA38461DF073FB10B13B
+:20B9600033498160C460204614F0B8F916F0CCFB1CF062F90C201EF08FFC2E4AD16880B150
+:20B980000460012380F80480224E4371D768002F866008BFD06004D00A68002A7FF47AAFA8
+:20B9A000086099F80000D9F80C70C5F824B04FF480764FF40073E8701F49AF623222AE806E
+:20B9C0004FF48067EB8005F174002F8118F00AFA1A49A8614FF4FA6205F1980018F002FA0F
+:20B9E0001749E86141F2883205F1BC0018F0FAF928628DF8244009A81DF094FF0BB0BDE8E0
+:20BA0000F08FC0467CFB0020F4030120081800209927020060B90200F8FD002065E5010075
+:20BA2000481900207004012065420200FCB302006D5E020080030120559602006D96020033
+:20BA4000859602002DE9FE4F824C00906068C06801910121017080484FF0000A80F800A0CA
+:20BA60007E4880F800A02068403001680D681E46174615B9D0F80C0580477949DFF8E481E5
+:20BA8000DFF8E491886E4FF0E2450AEA0702354008BF002A40F089800D46B5F89E1008228A
+:20BAA00053463A4013EA060708BF002A0BD118B14246508B401C50834A4692F90000401EC8
+:20BAC00010701D20ABE04A4692F90030DFF89CB142F201468E42A3F10103137002D0321D28
+:20BAE0008A4216D118B14246508B401C5083584600680199826C0098904750B1424602F1BF
+:20BB000016010088B5F89E30098842F60147874233D15748411C0A78B5F86610B1F5105F77
+:20BB200012D0AF6E42F60600884206D0002FC8D04246508B401C5083C3E7002F71D042462D
+:20BB4000508B401C50836CE0A96F5B460C3319604189062A0CD1427A022902F101024272B6
+:20BB600006DB491E89B24181062003F089FF58E018F026FE0FF06CFF53E0491C361D88B2EC
+:20BB80009E42D08214BFE1201C2011F04DFA99F9000020B199F90000002854DC48E020681E
+:20BBA000D0F85824514650464CE04A4692F900102768491E117007F1400118B14346588BD8
+:20BBC000401C58830868006840680078800925D2284A1078832824D125484378032B1BD1DA
+:20BBE00004234779D1F8945013707B1CDBB2437195F8241099420DDB817895F831304D1C82
+:20BC0000AB42C4BF491CCBB28370832010701DF0E5FC06E0E12002E0852051E7E92011F01E
+:20BC200003FA99F9000040B199F9000000280ADC2068D0F84C05804705E02068D0F85824CB
+:20BC40005046014690476068C06880F800A0BDE8FE8FC04614010020100501200F05012050
+:20BC6000501800208C11012012050120E0FF00204C0201200A1401202DE9F047884E05462B
+:20BC800096F84A00ADF1200D08280CD004280AD0287800F00300012840F0FA802869007880
+:20BCA000062840F0F58068884FF6FE74844200F0EF80718F814206D1287F20B9284613F05A
+:20BCC0003BFA0446E5E01CF027FF002840F0DE80287F4FF000092746E8B1724800780421EC
+:20BCE00040EAC00010FB01F05FFA80F8698885F81C80FF201BF0E4FB8A4648B1E88A48F007
+:20BD000001034FF00109671C2B7740F00400E8824FF0400802E0B5F802A0C846504618F0AF
+:20BD2000DBFE08B100206876A87E08B90F20A876287830F07F0008D1E87E50B996F8240006
+:20BD4000411C86F82410E87603E0287800F003002870287E012806D196F82F0018B9287894
+:20BD600008B90020287696F8320080081CD3B9F1000F0AD1688818F0AFFEA8B1287820B10A
+:20BD8000286900781DF096FE70B1E88AC00902D3A87E012804D028461BF0CCFD20B975E035
+:20BDA000E98AE01E0840E8822878012807D128690078022803D1E88A40F04000E882E88AFA
+:20BDC000C00937D2B9F1000F34D196F83200800830D3687E6988AA1D434613F043FB28B147
+:20BDE0000020EB8A687643F02000E882A87978B1698805F1080018F04FFE07466888B8424E
+:20BE000004BF0021A971E98A41F04001E98200E068882978012904D0A98842460FF050FF5E
+:20BE20006888A98842460CF027FB18B1E88A40F02000E882284606A907F000FC8046BC4272
+:20BE400008BF6F88B8F1000F1DD0059528788DF810006C8DADF812406B7D0093E88A019042
+:20BE600095F82C00029004AA0392728F9DF81830394640460DF0B0FC0446102C04D14046C7
+:20BE800018F08AFE00E0102420461AE7112400E0C224284618F080FE204608B0BDE8F0876E
+:20BEA000E4FA0020B7FE00202DE9F04F7F4E7068416EADF1340D02A88847DFF8F4B19BF99E
+:20BEC000000038B17B4890F90000002818BF002040F0E9801EF07AF9DFF8DC910A9099F885
+:20BEE0000000800806D27D2000210DF08FFD0025079001E00025079502958DF80C5005952B
+:20BF000003228DF818206D4CA4F8BE50C4F8C45094F8C800012705F00F013B4620F00F00EB
+:20BF2000014384F8C810DFF898A10B9394F8C81063F3C71194F8D73084F8C81023F001002E
+:20BF400007F0010343EA000184F8D71094F8D70067F3410084F8D70094F8D70065F38200C7
+:20BF600084F8D70094F8D70065F3C30084F8D70094F8D70065F3041084F8D70094F8D70018
+:20BF800062F3461084F8D700DAF80000D0F8282404F1D801F4209047DFF8288198F80030C4
+:20BFA000A3B94946706809788446890910D3C06B8047C4F8C40094F8C81021F00F0141F0D6
+:20BFC000020184F8C8108DF80C700290D6F804C03E4A3D484FF080738DE80C00DCF8507091
+:20BFE0003B4B006804F1BC01894602AAB8470028708006D5022041F2883115F057F80B9532
+:20C000004DE02C49334F91F90000401C087097F90000401C38709BF90000C6F808902946B1
+:20C02000401C8BF80000022015F040F8DAF8001001F1AC021068077888F8005007B180251C
+:20C04000308F17684FF67F7303401D432843308794F8D420387860F3C71284F8D420D1F811
+:20C06000D400C28CA6F84620428D00F14403A6F844201A6806F13B052A6058686860D1F8FD
+:20C08000D400C18CA4F8EE10418D00F14407A4F8EC10396804F1E4063160786870600A98E0
+:20C0A0001EF01EFA0B980DB0BDE8F08FDCFF002014050120130501200614012050180020A5
+:20C0C00014010020110501208000012020004300F9470000120501202DE9F04F0746861C34
+:20C0E000ADF11C0D30461EF027F882490446182268460FF0FBFC7D780DF10B0031461EF060
+:20C100004BF84FF6FE794FF0010802208DF8160000208DF80800B87AADF81490810805D392
+:20C12000B87A000934BF0326042603E000092CBF0226464670480078002808BF002D00F0B7
+:20C140008E80704890F84A10082940F08B801DF021FD10B1012D00F08280002C27D0207903
+:20C16000864218BF022D72D1042818BF032803D1042E10D0032E0ED0022818BF012812D17E
+:20C18000022E08D0012E06D0022818BF01280AD11EF02EF807E0208882461BF03DFE08B9FB
+:20C1A000ADF814A003E0B81C16F024FC0024BDF81430DFF848B1994514D11BF089FC70B9E0
+:20C1C0005846008882462DB11BF026FE002808BF504601D01DF03EFDADF814000346484636
+:20C1E000984231D018462B4612F078FA07F1020A002839D15846001D016811B1BDF814003C
+:20C200008847BDF81400514632460AF069F904463C4800784FF4803141F288321DF09BFF4D
+:20C2200038494046087164B1022D05D0012D11D1607940F0100002E0607940F00800607178
+:20C2400008E0ADF814900FE04FF0C7080CE02088ADF8140000208DF81600804604E04FF0BF
+:20C26000C30801E04FF0C208CDB125480078A0B9012D12D144B902208DF8160031460122E8
+:20C28000684610F0A1FC31E0002001228DF816006846314610F098FC04E02A46F8E76846CA
+:20C2A00017F0B8FA06469CB145B16079022D40F04000607104BF40F020006071B87AC0090E
+:20C2C00003D3607940F080006071A079401CA07156EA08000AD014B1B81C16F08BFBBDF8AC
+:20C2E00014104846884201D01DF082FF07B0BDE8F08FC046E8B8020034040120F0FB00207C
+:20C30000ADFE0020E4FA00202DE9F04F09AF8846ADF13C0D0026079098F80350B8F806102C
+:20C320000993B868089204240B903879DFF8F0910A9019F80E0F854205D148461BF078FF66
+:20C3400008B1761CB6B2641EF3D1002EB34600F0CD8098F81440F1B2182000EBC10085B2DE
+:20C36000601900B210F076FC041C06D02A46002112F0ECFA26746019E060002C00F0B18011
+:20C3800098F80350B8F806100022284619F09EF906466571B8F80600E08098F81600608105
+:20C3A0000021217298F81420D8F81010E0681CF071FF00250C95B8896082387C0D95A94623
+:20C3C000207551E04FEAC900002104EB000A0019817570780AF11605012810D0B0788AF8BB
+:20C3E0001D007088ADF8180004218DF80C1003A816F074FDBDF80E00AAF8180005E0012000
+:20C40000287001230C93708868803079287198F80000C00903D3A87940F00200A8710C9860
+:20C42000B0B9404869880088884211D1287988F802000A9E00960B9B01930D9B0293089A6C
+:20C44000079940460DF064FDA87940F00500A87109F101005FFA80F9B8F8061098F80300C3
+:20C460004A4619F033F906460EB1CB45AADC2E4D281D06680D98314604E00E4620E0096863
+:20C48000401CC0B20029FAD1052813DB96B1334600E01B6813B99E4202D00BE09E42F8D18A
+:20C4A000306801216860304614F05EFF304618F073FB6E68687820716878401C6870204676
+:20C4C00016B131680029D8D10D99002E01600CBF686030600A9B009409993A78404600F0CF
+:20C4E0004BFBBBF1000F18BF002C15D198F8030098F816708DF80F00B8F806608DF81070FA
+:20C50000BBF1000FADF812600CBFB92010208DF8140003A81DF04DFC0FB0BDE8F08FC046F2
+:20C520005E0100201EFB0020400501202DE9F041844FB81C00780D46290C1FD2E80B38BF14
+:20C540000020C0F0FB801BF0F5FD7D4C804604F10C00006858B107463E6938461DF0A4FF70
+:20C56000384618F019FB371CF6D10020E06040461DF0C3F885F48040BDE8F08115F0E4FA27
+:20C58000061C00F0D9803078F9780024D2280EDCD22800F0C7801A3860D01738052840F2AE
+:20C5A000C1809F3800F0BE80401E48D0B2E0D33800F0B580401E022840F2B480293823D0BB
+:20C5C000401E40F0A78016201BF087FF071C00F0A9802146162212F0B9F9932038707C7009
+:20C5E00070783871B07838743079012814BF02200120B871F0883881F0783875B0781CF04B
+:20C600006BFC00287DD080E00A201BF066FF071C00F0888021460A2212F098F991203870AA
+:20C620007C70B078787170783871F078B871B0883881B0781CF050FC002862D065E07078E3
+:20C6400088426FD0404BF870FA1C21464FF000701AF05CFC78783D49087063E030201BF0C4
+:20C660003CFF071C5ED02146302212F06FF9922038707C70B07B032838711CBFF088F880FB
+:20C6800004D1B81DB11D08221CF004FEF07BB873308A388270887882B088B882708AF88208
+:20C6A000307D3876737D204603B101207876707E214600B10121B976B07DF876F07D3877F8
+:20C6C00096F918007877F069386296F8200087F82400B08DF88496F82E0087F82800B08C28
+:20C6E0007885B08C10F0B6FAF862D8B1B16AB28C1CF0D0FD307D1CF0EFFB30B9F86A18F046
+:20C700004BFA38461BF0D0FF0CE00079394616F0C3FF07E03046F3F793FC044602E0304658
+:20C7200002F0D0FA012C03D030461BF0BDFF03E0B078314616F0B0FF85F40040BDE8F081FA
+:20C7400080040120281A0020E17E020070FB00202DE9F04F8246DAF8185069782878EA78AC
+:20C7600000EB0120A978ADF1240D044601EB0221069118F0B1F9012800F0D9804FF0000862
+:20C78000CDF810802046CDF8148018F0A5F92D1D60B970480088A04208D06F48007830F033
+:20C7A000010040F0D48040468123C2E015F8014B5CB1600010F04EFA049030B1049A2046A1
+:20C7C00029461CF05EF9054600E0444615F8017B5FEA07090AD0780010F03CFA059028B1FA
+:20C7E000059A384629461CF04CF900E0C1465B480568002D76D046460796089668680178E2
+:20C8000000296CD0AA7B520869D3AA68002A04BF8668DDF820B004D0012090474FF0010B4F
+:20C820000646002E5BD070880699814204D006984FF6FF7181424CD1F279B3680499204669
+:20C8400019F0CDFF38B9327B33690599484619F0C6FF00283DD009EB0400022110FB01F083
+:20C860001430C0B21BF039FE071C2AD0D2203870BAF80200788087F80C90002C3C7104BFA6
+:20C880000798B86008D007F114000499B860620007F114001CF0FEFCB9F1000F04BF0898B8
+:20C8A000386108D0059907EB44004FEA4902143038611CF0EFFC686840680078394616F066
+:20C8C000EBFE3078264908F1010701F808005FFA87F8BBF1000F02D0304618F05DF92D6888
+:20C8E000002D8BD1B8F1000F05D19AF80C00A8B90023984600E00023164800880090CDF8E3
+:20C900000480174F02979AF8100003909AF811100AF1020248F2060014F064F8049808B1B8
+:20C9200018F03AF9059890B118F036F90FE0002080230094019002909AF8100003909AF877
+:20C9400011100AF1020248F2060014F04BF809B0BDE8F08F50FD0020ADFE002024050120D1
+:20C96000A8FF00202DE9F041064606F11600ADF1380D18F0F1F97A48007806F11607012804
+:20C9800018BF02282FD100200DF1320501A905AC8DF8320001220095601A83B201A907A86F
+:20C9A00017F0B4F898B16F4800680DF1330101AA11F04EFFADF81C00BDF81C40032C12DA44
+:20C9C00003A8394608221CF065FC214606E003A8394608221CF05EFCBDF81C100420142254
+:20C9E00001AB19F02FFE3846FF211CF07CFB10B15D4901200870002402A839468DF804401E
+:20CA00001DF0CAFB1DF0C6F848B901A813F07EFE012804D02046394608AA1AF00FFD3079FD
+:20CA2000534D012861D006285FD0691C0B7804282AD0032840F0918038460DF11E011AF060
+:20CA4000A3FF58B14FF6FE7039460DF11E021AF0F5FC214638460A4614F06CFEBDF81E006A
+:20CA600006A91AF001FD069838B906A81AF0E6F818B9BDF81E0006990880B11D38460FF0C4
+:20CA80001DFE13F095FC68E0002B66D038460DA901AA11F0DDFE01469DF8340000285CD01F
+:20CAA0008DF8154020460290019001278DF81640142201AB8DF81470042019F0C3FDB21D69
+:20CAC0004FF4817010211DF099FA06F1060828B94FF48170102142461DF096FA6D1F3846D7
+:20CAE0000321AC7119F072F837E0721D1021204612F8017F1FB9491E00F10100F8D11B4F57
+:20CB000010280CD07179B01D1AF04CFB387808B12878D0B170790EF049FB2C7015E0387803
+:20CB200098B9204662210DF1220212F049FD0DF1220021461AF036FB20460EF037FB0DF1FB
+:20CB400022002146102211F001FF0A480178052903D1C079802115F025F80EB0BDE8F0817C
+:20CB6000ADFE0020B800012056FE002049FB002051FF002034FD00202DE9F04F0646ADF139
+:20CB80003C0D032700200A91189D0C93297C0B920CE005EBC002127F530805D3D30803D2BF
+:20CBA00012093CBF7F1EFFB2401CC0B2814201DD002FEED1B9460124002010E005EBC002CE
+:20CBC000177FFB1109D07A0807D307F0040207F00807174304BF641EE4B2401CC0B28142B5
+:20CBE00001DD002CEAD1A346B9F1000F08BF002000F0C5804FF00008B7E04FEAC8002A1891
+:20CC00004019007F02F11604400880F0AA80002723780D9793B9108B1DF05EFA70B1007901
+:20CC2000012818BF032809D1A079BBF1000F40F08000A07100F0948001200D900C9800B143
+:20CC4000202700210C22684611F080FE237813BB0A9800280EBF4FF0080A47F040074FF003
+:20CC60000A0A60884FF6FE71814228D104208DF81800E379ADF8243006A816F02FF94FF611
+:20CC8000FE7000210346B0800A46ADF8003007A814F050FD15E03B480078012808D060888E
+:20CCA00047F00C074FF00C0AB0804FF6FF7006E06088FF2147F00807217141F2080AADF841
+:20CCC00000008DF80270307D8DF8040001238DF80530684608F0E0FB9DF8141061BB039858
+:20CCE000417D6171A0F816A00B9F4776277817B124490978017769890185698A4185297D4B
+:20CD000080F82C10697980F83A10217980F83B10F188C1873189A0F84010717D80F849103C
+:20CD2000B1888187406C327D31691CF0B3FA684617F032FE9DF81410A07940F00100A0710B
+:20CD400051B90D9818B1ABF101075FFA87FBA9F101075FFA87F903E0A07940F00800A0711C
+:20CD6000297C08F101005FFA80F8414503DDB9F1000F7FF442AF2846002114F0F5FA0FB07F
+:20CD8000BDE8F08F70FB00202DE9FE4F9B461546894682461DF01AFA7B49019008680CAF0D
+:20CDA000504508BF48687B4C6FF0010828B1B8301CF008FF002840F0D6801BF0CDF9061CC3
+:20CDC00000F0DB8004F5CE701DF0F8F90023B4F9B400C6F80C90401C86F832306FF31F3008
+:20CDE000A4F8B400C6F808B0B4F8B40030866748C6F810A097E80C0020210027B8461940F0
+:20CE0000104006F1180383E80300424686F8332006F1200383E88001E8683064287C86F8DD
+:20CE2000440028687063287986F83800A868F0636869B064A869F064287F86F85000687FEB
+:20CE400086F851002F7C27B9EF6817B1012086F844002F795FB999F80C0000F00F000228F0
+:20CE600005D1012086F83800D9F808007063484608274568002D18BF002F70D100886FF391
+:20CE80000900B0F5305F18BF022506D196F83300082540F0100086F8330006F1180090E81A
+:20CEA0000C00414606F1180745EA0200194387E80300D4F8D800824507D194F8DC004108D6
+:20CEC00024BF00F0FE0084F8DC0031480768002F39D004F1A0000090D4F8A810D4F8AC20C8
+:20CEE00004F198052B463046B84710F1030F10D0B6F93010B4F9B420914207D0B4F9B4103C
+:20CF000001F6FF716FF31F31A4F8B41010F1020F1BD010F1030F18D096F83300B6F9308080
+:20CF200040F0800086F8330000278AF8FC702868864205D0F068007B00F00F0002281CD165
+:20CF400013F094F919E06FF00200B4F9B410804601F6FF716FF31F31A4F8B41005E07F1EB5
+:20CF60002846FFB285E76FF0020894F8DC0040F0040084F8DC00C4F8D8A001981DF0B0FA45
+:20CF80004046BDE8FE8FC046E8F50020FFEFFF9F5805012030F50020FEB50E461DF016F964
+:20CFA00000257F4A7F4C517855708A080ED2C9081AD31DF095FAA4F1080000F108048068DC
+:20CFC000D0F858242846014690470FE01DF088FA6068C068007828B92068D0F8582429467F
+:20CFE000012090471DF0F2F81DF07AFAB00941D337E02168D1F8982050600098D1F840136F
+:20D0000088472168D1F89800D1F85413001D884732E01DF0DBF82168CA6B117B491E117314
+:20D020001DF05EFA216800983C31CB6D0278586000988DF8042047782FB1162A0AD1D1F8CF
+:20D040001813684601E0D1F80413884721689DF804203C31162A06D0C86DD1F81813001D5C
+:20D06000884721683C310868001D1AF056F800280090CED1300C08D32068D0F8940000783C
+:20D0800014F062FD00280090B3D1700907D327682E20D7F840138DF8040001A88847700826
+:20D0A00007D327682520D7F840138DF8040001A88847B00807D327682620D7F840138DF891
+:20D0C000040001A88847F00807D327682720D7F840138DF8040001A88847300907D3276867
+:20D0E0002920D7F840138DF8040001A88847F00909D32D2027688DF80400D7F840138DF8E3
+:20D10000055001A88847300A09D3302027688DF80400D7F840138DF8055001A88847700AD6
+:20D1200009D3352027688DF80400D7F840138DF8055001A88847300B07D38DF805503720EC
+:20D140008DF8040001A81DF0ABF9700B07D38DF8055038208DF8040001A81DF0A1F9206804
+:20D16000D0F898000068C8B11DF030F82168D1F898100A6800920D601DF0B2F921680098F5
+:20D18000D1F8982050600098D1F8401388472168D1F89800D1F85413001D88472846FEBDAC
+:20D1A000D8000020140100207E492DE9F04F0A680746ADF11C0D0DF10E00026049684160E0
+:20D1C000F88900280CBF08210221BC69DFF8DCB1754A14F801A0A0B9104621461BF008FF72
+:20D1E00060B920461CF0A8FF4FF6FE7650B30179012918BF022925D106881CE059460E88E6
+:20D2000020E0617820785E4600EB012031880646B14216D01CF060FF002498B10179012993
+:20D2200010D18DF800404088ADF80C00684615F055FE00B101ACBAF1000F18BF4FF0FF0A92
+:20D2400000E014464FF6FE71B14218BF002C03D13D7B002D40F0A38056484568B1424FF061
+:20D260000B080DD064B13AF0010006D0387B012800F095804FF080090AE04FF0000907E0E6
+:20D28000FB894FF08109002B0CBF4E1C0DF10E0405F8019B002C14BF211C0DF10E01284681
+:20D2A0001CF07AFF0546BAF1010F05F8016B4FEA2620287064D158460088B04260D1B9F13B
+:20D2C000000F5DD1DFF8E8903320002649460C791CB1032CBCBF761CF6B2401E01F124010F
+:20D2E000F5D136B1022016FB00F000B20FF0B2FC00E0002003466D1C002B08BF00260DD038
+:20D30000844633214846047924B1032CBCBF02882CF8022B491E00F12400F4D163B3FC89AE
+:20D32000002C0CBF08210221B8694018417803EB4100B142A8BF002605DA761AF6B208EBBF
+:20D3400046085FFA88F805F8016B297066B16D1E017805F8021F30F8021B761EF6B2002EBC
+:20D360004FEA21216970F3D1184617F015FC08F102005FFA80F803E000204FF00C08287065
+:20D380000C49FA8910204346C87042F4004207F11100B91C13F0C2FB06490020C87007B050
+:20D3A000BDE8F08F44B7020020FC002050FD0020E40D002098FD00202DE9F04F074678695A
+:20D3C000824600780321ADF12C0D10FB01F0401C80B21CF061FF5FEA000808BF002400F0F0
+:20D3E000EC80002635464FF00709099512E0049931B93968087D228889881AF085FD01E06C
+:20D4000019F06EF9ADF82000BDF820006D1CEDB23618B6B29AF80000A84223DD396815FBF7
+:20D4200009A4641C087D2288898802AB16F094FB80B19DF80E00A178884209D19DF80F10F8
+:20D440008A0803D38909D2D37E2004E0882002E08D2000E0862088F801002088A8F8020023
+:20D46000012509950998002888F8000040F09180CB4610FB0BF0C4B2A01980B21CF00CFFCF
+:20D480000A90002808BF002400F0948081460026A14404E0BDF82000761C8144F6B29AF8BF
+:20D4A0000000B04268DD3968087D16FB0BF50AEB0504641C2288898802AB16F04DFB0028A2
+:20D4C0005AD00A982388049A2D18C5F803902B808AB9396808A800902288087D89884B4602
+:20D4E00019F0ECFD3968D4F80330087D02AA891D18F0D8FC0BE0484602A908AA1AF0DAF934
+:20D500003968087D02AA2346891D19F0FEF90028C0D0099B032113FB01F108EB010208EBC1
+:20D520000105507021885A1C6980D0B209901EB30A9C3968087D2288898805AB16F00CFBED
+:20D54000D0B1079840B93968D4F80330087D05AA891D18F0A7FC0BE09DF81A00D4F8031014
+:20D5600019F0BEF80246D4F8031007981CF096F8761E04F10704DCD1099888F8000028B949
+:20D58000002088F80100012688F800600A981CF0C3FD78683A68C00880F0010000F00100C9
+:20D5A0000090B87A911D0190107D928843460FF081FD012440461CF0AFFD20460BB0BDE894
+:20D5C000F08F70472DE9F0470646F08917468946ADF1280DC01D80B205460EF0B5FE7A4C33
+:20D5E000FF280BD12846FBF7EFFD854204DD641C207800B90520E3E0012000E00020617881
+:20D60000D9B917B1022F18D1B8B1307A8DF80C00F788ADF80A70B588ADF808500023009364
+:20D62000E18E94F8330001AA032305F0F1F89DF814003074BDF81070B78194F83310E58E11
+:20D64000E06806AA0423884649031CF015FD069800F0FF0100F0FF007E2806D140467C2156
+:20D6600019F0CCF9069901F0FF017C2940F0A580F08942F20102C11D8FB2E9198A4240F382
+:20D680009A80F188327AC1F301238DF81D10B18843EA82038DF81C308A1006468DF81E205C
+:20D6A0000423C0F3851201F0030142EA81128DF81F2010FB03F1F21D01F0FC01731990B2B7
+:20D6C0008DF820101FFA83FA0D282BDB4846314600221CF003FC0246052107A81CF0FEFB70
+:20D6E0009DF82010334600F03F064A4641EAA011B0008DF8201040F0020096268DF8210052
+:20D7000029468DF82260404616F0B8FA0646514607AA07234046667016F0B0FA3043607048
+:20D720004DD135E004F12400494632460EF0DEF907A90A68301900F12409484609790260C6
+:20D74000731D0171002204F1240099B21CF0C6FB9DF82010962300F03F068DF8223041EABF
+:20D76000A011B0008DF820103B4640F0020007AE49468DF821003268B0790A60B288887196
+:20D7800040468A8004F12402294616F077FA6070E18EED194FEA8806AAB2C919E18606EB56
+:20D7A000C8010919A1F84C2048B14046514615F04DFF607803E0052000E001206070C0B2EF
+:20D7C0000AB0BDE8F087C0465CFC00202DE9F04705467B4895F80B900078ADF1180D00280F
+:20D7E00008BFBA2000F0E980684600210C2211F0ADF801264FF0000A298B8DF80560C808AE
+:20D800000AD39DF80220C8100B0942F040028DF8022038BF032602E09DF80220C8104B0988
+:20D8200028BF46F0400640080FD342F0C00288098DF8022039BF9DF8030040F002009DF8D8
+:20D84000030040F001008DF8030001EA6100000A28BF46F00806287A5A4F002830D00F28E1
+:20D8600028D0022822D0032818D0012832D1387848B94FF6FD70ADF80000288842F00C025D
+:20D8800046F0040608E0288842F0080246F480564FF0FF09ADF80000824619E0284669469A
+:20D8A00019F064F89DF80220298B13E02888ADF800000FE0288842F0080246F0040605E050
+:20D8C0001CF0F4FA9DF8022042F00402ADF800008DF8022048081AD312F00C0F0DD128882B
+:20D8E00014F0DCFF002808BFBB2066D09DF80220298B42F020028DF80220480807D302F0C7
+:20D900000C00042804BF42F020028DF80220A87C8DF80400684607F0BFFD9DF81400002832
+:20D920004BD1039CE682E87E6076287FA076287A012804BF38782077A87E2085288B608593
+:20D94000E87F84F82C00288B00EA6000000A15D395F82000667D804618F08EFE071C0DD0DF
+:20D960003A7C002008E007EBC001CB7E984504BFCE763A7C401CC0B28242F4DCA87A84F853
+:20D980003A0084F83B90A4F83CA0E889E087288AA4F84000A87E84F84A00A87F84F84B004E
+:20D9A000687F84F84900606C69696A8A1BF072FC684616F0F1FF9DF8140006B0BDE8F08791
+:20D9C000AF00012070FB00202DE9FE4F07462C200FF040F90028386100F0E68000212C2232
+:20D9E00010F0B4FF38694FF6FF7585823C6938880DF1020112F0CEFBDFF8B4B168B30DF18D
+:20DA0000020069461BF048FBBDF80000854224D0002006262074BDF80010BDF80030668225
+:20DA2000674E8A0002EBC100A38206F1240143181A68A2611A68521C1A600E584FF47A74D7
+:20DA4000B6FBF4F06043361A07D101205E46187230784FF4006114F0A5F83969388808318F
+:20DA600012F098FB5348846880461CF093F868B13869002141823869682686823869022392
+:20DA8000037438698461621CC8F808204A48D0F800903869DFF824A10446A18A2E468E4243
+:20DAA00054D104F1080049461BF0A2FA48B91BF0C1FB014648461BF09BFA10B91CF06AF89A
+:20DAC00060B13888396904F04BFD002400B1012400200CB139698D82396908743869044606
+:20DAE000A18A8E4232D15146303991F82F303BBB91F86510012923D101200DF10A013A22A8
+:20DB00001CF073F9C8B901209DF80A50207400233A22A5755D466382D8F80410A28228789F
+:20DB2000A161D8F80410491C0129C8F8041005D14FF4007114F036F800E0A5823C692046CE
+:20DB4000828A3146914204BFA1213975818A8E4224D0017C01290ED0BE6856B91CF01AF895
+:20DB600020B9B878400838BF052100D30D21204602E00D2100E00E210177B87800F0030016
+:20DB800001281ABF514608780520396948703C6960781BF0C7FB6077BDE8FE8F16F0FCFF99
+:20DBA00000203861BDE8FE8F10203875BDE8FE8F3BFD002048040120B800012014FB00209E
+:20DBC00064FE00207A492DE9F04FFF28ADF13C0D0AD148780A78824240F3E680850005EBAE
+:20DBE00000156D18183503E01422183110FB0215E8884FF6FF74844200F0D680287B0028BB
+:20DC000000F0D28068788DF8310000268DF83060684FADF8286038882B7BADF83200C3EB22
+:20DC2000C300401C0FF016F80746287B80000FF011F80D90002F00F0B380002800F0AD800C
+:20DC40002B7B0E904FF0FF0A4FF00709A3463B7050E016FB09F039183C180023A1F801B009
+:20DC6000804684F803A007EB08004360287BB0423EDD2C69711C1846002C39D08642C8BF6E
+:20DC80006468401C491EC0B2F6D18CB32068008807EB0801A1F801002268698868781288E3
+:20DCA00008AB0EF0D7F9012822D19DF8220007EB080107EB08030422C8700E9809995860BA
+:20DCC0001BF0E8FA0E909DF822001BF076FA78B1206800210422801C10F038FE9DF8220006
+:20DCE0000FF02EFA024609992068801C1BF0D2FA761CF6B2287BB042ABDC95F801B0B5F8D7
+:20DD000002A01CF09FF900242346804624E015FB09F0391838184078491C02F8010B088809
+:20DD2000001202F8010B887802F8010B8878D1F8031009F09DFE6D1CEDB2024616E013FBE1
+:20DD40000971491C8878D1F8031018F0C9FC5B1CDBB20019C01C84B238789842EFDC204651
+:20DD60001CF09AFA061C18D0024600253878A842CDDC002100910120019002910391CDF8F9
+:20DD80001080524605940A230696584607910AA902F08EFA30461CF0BFF9384616F0FCFEDE
+:20DDA0000D9808B116F0F8FE0FB0BDE8F08FC046F00C01202CFB00202DE9F04785682A68F0
+:20DDC000D16944681162490832D3D4F8C01049BB2968486820F0020048602968486A20F0A6
+:20DDE00003004862D4F8CC002A6941686F69096847EA0200C862D4F8CC006E6941682A6951
+:20DE0000096846EA0200C1F804052968486920F001004861286801210162284619F0D4FF42
+:20DE2000BDE8F08703220A7403F026F9BDE8F087D4F8CC0041682A696F6909684FF0000990
+:20DE40000226CA4647EA0200C1F80405D4F8C070002F00F0A880D4F8CC00D5F814E0406851
+:20DE6000D4F8E0C0D0F80080BCF1000F04D1EA69A86904F1D80103E004F1DC016A6A286A10
+:20DE8000D8F8043513EA0E0F11D0806810F0070F0DD13868D4F8D030984208D17F6937B9AB
+:20DEA0002B68586A20F002005862C8F804E5906810F0070F74D10F68002F71D0D4F8D400BE
+:20DEC000BCF1000F3844C4F8D40014BF48462020C4F8E000C1F80090D4F8C010D4F8D0209C
+:20DEE000086890424BD8D4F8D420904247D881F81090D4F8C80004F1300730B9D4F8C010AE
+:20DF0000C4F8C810D4F8C80008E04369002B34D1D4F8C0104161D4F8C01040694969C4F824
+:20DF2000C010C0F814A0D4F8E00000280CBFD4F8D800D4F8DC00C4F8D000D4F8C000C4F8E6
+:20DF4000D49088B12046294606F08EF994F8FE0078B1D4F8CC00406801686869D1F80425B3
+:20DF6000024218BF886204E02968486A20F00300486238461CF04AF912E01846C5E7204689
+:20DF8000294606F071F994F8FE0048B1D4F8CC00406801686869D1F80425024218BF8862BE
+:20DFA000761E7FF453AFBDE8F08770472DE9F84F0746714D714C28684030D0F89410267856
+:20DFC00091F883B026B1D0F80C0580472868403001680E6816B9D0F80C058047A046694928
+:20DFE000674C0120012F88F80000D1F8009067702AD9DFF894A1654EBF1E59D07F1E52D0E6
+:20E000007F1E3DD07F1E73D07F1E34D12968096C096891F86D20628191F86E70002F06BF09
+:20E02000E070071CE770686840683178007811FB00F0784381005046C16690F8701021F06F
+:20E040000F0141F0030151E000202E686071306C0068D6F8D410C08AC00934BF91F8250059
+:20E0600091F84E00A070B7B9CF78A7B10228C4BF0220A0700FE02868D0F84C05804737E055
+:20E080002868006C006890F86910617190F86A00A0700027A77109F09DFE2868006C006810
+:20E0A00030BBBDE8F88F0020607117F087FB1FE030788700D9F83C00804771683C22401A3C
+:20E0C000B0FBF7F0B0FBF2F15143401AC0F1780086B2D9F83C00804707FB06015046C16637
+:20E0E00090F8701021F00F0141F0020180F870102748007898B92868403001680F682FB9CB
+:20E10000D0F80C0580472868006C07687A686178107800F0200020719078E07100E06178FE
+:20E12000032903D0022918BF062923D11CF04EF805466078022815D01648077817B916492B
+:20E140000F787FB10221BBF1010F88F8001004D10078832801D113F095FE28461CF0C0F906
+:20E16000BDE8F88F832088F8000028461CF0B8F91AF06CF9BDE8F88F140100200A14012016
+:20E180004C020120E0FF002050180020D8000020FC13012005140120071401202DE9F041A4
+:20E1A0000D4677490A680646ADF1600D14A802604A6842600A8902810A310C2268460DF0E7
+:20E1C00095FC0024204603A919F0FEF98046B8F10A0F1DD0B8F10D0F17D09DF80C0031780D
+:20E1E00000F0070001F0070188420ED1371D0DF11201042238461AF0ADFC48B90DF10E01BC
+:20E20000384608221AF0A6FC10B9641C052CD9DBB8F10D0F02D1042C00F3AF80F220594CDB
+:20E220008DF80900B4F848009DF80C70ADF80A00F80937D34FF002080DF12E0114A80A2233
+:20E240008DF808801AF086FC98B90DF13601684642461BF023FA284614F070FD071C08D067
+:20E26000608F69460C22B88138460DF03FFC2878B8730EA914A80A221AF06CFC90B910A905
+:20E28000684642461BF00AFA284614F057FD071C08D0608F69460C22B88138460DF026FCD6
+:20E2A0002878B8739DF80C00C01123D001208DF80800304611F0F8F9ADF80000284614F001
+:20E2C0003DFD071C16D09DF80D00800904D2304611F0EAF9B88106E007F10C000DF1170167
+:20E2E00002221BF0DBF9694638460C220DF0FEFB2878B8739DF80D0040083ED301209DF84E
+:20E3000042708DF80800780819D30DF14301684602221BF0C3F9284614F010FD071C0ED0F7
+:20E3200007F10C000DF1450102221BF0B7F9694638460C220DF0DAFB28780938B8739DF8E8
+:20E340004200800819D30DF14701684602221BF0A5F9284614F0F2FC071C0ED007F10C00E1
+:20E360000DF1490102221BF099F9694638460C220DF0BCFB28780938B87318B0BDE8F0819B
+:20E3800058C10200E4FA00202DE9F04F724C002704F19800ADF1140DB946B84605680297DB
+:20E3A0008246CDF80C903DB3D4F8AC00B84203D1D4F8A800B8421DD0D4F8A8600EB3D4F842
+:20E3C000A8102869096988421BD195F83300400917D3D4F8AC60A6B90127D4F8A800C068DE
+:20E3E00040880028F9D0D4F8A800C06840880128F3D006E0012704E004F1E00002211BF01F
+:20E4000003FF002D43D087F0010B03A802AA59460CF02CFE5FEA000809D0012F07D003994E
+:20E4200029B104F5AC701BF073F94D462FE0002D2DD04A48066856B3B8F1000F27D0039857
+:20E4400028BBCDF800B002980190D4F8A800D4F8AC100AF108035246B047401E02D0401E1A
+:20E4600008D014E0029800B9284601214B460091014605E001230093D4F8A800D4F8A810F0
+:20E480000069B1F930104A4605F04EFB60E0002F5ED0002D5CD060682969884252D1B8F175
+:20E4A000000F0BD0039848B1D4F8A80030B9D4F8AC0018B9082017F0BDFE49E008201AF0F3
+:20E4C00047FC95F8330004F1E006C0F3001028B9504619F0F1FFC4F8A80004E0504619F044
+:20E4E000EBFFC4F8AC00A8691D49C0430860A8694A6810434860E869C04341F8080CE86938
+:20E5000051F8042C104341F8040CEC680820294619F034FE204619F0FBFD2088A0F6020019
+:20E5200040B141F21E01401A04D041F6E671401A012803D80120214619F020FE4FF08041CF
+:20E54000304603E004F1E0004FF480611BF05CFE05B0BDE8F08FC04630F500205C0501205E
+:20E56000101004402DE9F047ADF1200D109C1D4682460E469046E811002110221FFA80F940
+:20E58000204610F0E3F9C5F3C307D6B104A8214610221AF07FFE2046514610221AF07AFEB3
+:20E5A00004A8214617F02AFC1026224613781AF8011B761E81EA030102F8011BF6D180352F
+:20E5C000ADB24846411E00281FFA81F940F09980002F72D00E2F28DA04A8214610221AF0EC
+:20E5E00059FE204600210E2210F0B0F93A46204641461AF04FFE2E128020E05521461022F2
+:20E60000E5736846A6731AF045FE04A8214617F0F5FB10206B46227813F8011B401E81EA19
+:20E62000020104F8011BF6D187E004A8214610221AF030FE20460021102210F087F93A465B
+:20E64000204641461AF026FE802021461022E05568461AF01FFE04A8214617F0CFFB102741
+:20E6600021466B460A7813F8010B7F1E80EA020001F8010BF6D104A8214610221AF00AFEBD
+:20E68000204600210E2210F061F92812E57321461022A07368461AF0FDFD04A8214617F05F
+:20E6A000ADFB10206B46227813F8011B401E81EA020104F8011BF6D13FE004A82146102201
+:20E6C0001AF0E8FD204600210E2210F03FF92F128020E573214620701022A77368461AF028
+:20E6E000D9FD04A8214617F089FB10206B46227813F8011B401E81EA020104F8011BF6D159
+:20E700001BE004A8214610221AF0C4FD2046414610221AF0BFFD04A8214617F06FFB22461D
+:20E720000021137818F8010B491C102980EA030002F8010BBFF645AFF3E708B0BDE8F087A9
+:20E740002DE9F04F09AF3D7AD7F804800E1C9A4693460446ADF12C0D26D0207A29098DF857
+:20E76000260010D302281FD121881BF09FFB884209D008460322012111F05EFF002818BF93
+:20E78000CD2040F0C180237A022B07D00F2B05D0032B0DD0012B0BD033B909E0208816F0D6
+:20E7A0009BF918B90F2B03D10220ADE00F2323728DF80830032B1CBF2088ADF8000003D189
+:20E7C000684621461BF0E8FCA8081DD250484FF000090368ADF8109043B15868864203D0B7
+:20E7E0001B68002BF9D101E09A681AB9B3688BB158880DE031780220904758B10188ADF8EE
+:20E80000101016F0C9F905E04FF6FF704FF00009ADF810006809ADF818900BD39DF8080041
+:20E820000F2807D0012805D0BDF8180040F00400ADF8180035F07F0005D0BDF8180040F098
+:20E840001000ADF81800E80938BF484606D3BDF8180040F00100ADF8180001208DF8250016
+:20E86000E80805D3BDF8180040F04000ADF818008DF82490A80934BF012004208DF81B0014
+:20E88000617A8DF80B10ADF80EB0ADF812A03D68059598F800008DF81A00397B8DF81C1070
+:20E8A00030788DF80A001AF0C3FA18B1016909B16846884709A815F0DDFA504508DA15488F
+:20E8C0000168002908BF022706D06846884702E06846FEF77BFF07469DF8080002280CD173
+:20E8E0001BF0E4FABDF80010884206D1307898F800105A463B4617F0F9F827B998F80000F8
+:20E90000401C88F8000038460BB0BDE8F08FC04624050120B40001202DE9F8430646307B51
+:20E92000894603461AF02CFB0125041C5DD1D6F8008077891C461C200EF08CF950B1002189
+:20E9400041730473478101818173C173C0F8008041614160041C00F0C08000270781307CF4
+:20E960002074708A6082337C23BB716911B30F460E200EF06FF9E0B1394691F838200270B0
+:20E9800091F83920427091F83A20827091F83B20C270CA8F8280B1F84020C28091F8422067
+:20E9A000027291F84A2002734A88428191F849104173074638466061308B20836189B07E4E
+:20E9C0004FF67F472E46A07607EA0100C108608107D244490A78802707EBC2110843608186
+:20E9E00004E0608940F08000F9E700266089DFF8F880B9F1000FC0F3C21224D10AB38109E0
+:20EA000011D2410909D2C00838BF281C10D31BF038FB00F02000801C0AE01BF032FB00F00C
+:20EA20000F000A3004E01BF02CFB00F07F005F3020810420474660733878202113F0B2F8B6
+:20EA400017E0002515E0022060732068C089C00803D3404634300088208152B160894FF6FD
+:20EA60007F414FF680770140618107EBC21001436181012E32D1667B27893CB3012E0AD0D2
+:20EA8000042E02D0022E0BD020E0042019F060FC062805DB1AE0012019F05AFC082815DC35
+:20EAA000667300202781114960600868002808BF0C6003D00146486830B94C604046007873
+:20EAC000202113F06FF809E00146F4E7606908B116F062F8204616F05FF800252846BDE8A3
+:20EAE000F883C046C1FE0020E4FA0020380501202DE9F04F0C4606460D220021ADF1640D08
+:20EB000014A80FF023FF10220DA821461BF066F94FF0010A002840F0CE8096F82600032891
+:20EB20000DD196F840000EF095F8051C00F0C38096F8402006F141011AF0ACFB00E000256D
+:20EB400096F825004FF000088DF8440040B1022808D112A806F1180108221AF09BFB01E089
+:20EB6000F06A1290726B404611A914AB13F0C1FE96F82500002808BF062403D002280CBF67
+:20EB80000324022496F82610009196F82710019196F829100291C146CDF80C9096F82820E4
+:20EBA000034618A8414617F02FFC834696F82600241DE4B2032805D0022833D196F8400043
+:20EBC0002418E4B220460EF045F85FEA00082CD0074607F801BB9DF8600007F8010B96F8DF
+:20EBE000250038B102280CD1384606F1300152467F1C04E0384606F12C0104223F1D1AF015
+:20EC000049FB06F13401384604221AF043FB96F82600022806D196F84020381D06F1410167
+:20EC20001AF038FBB8F1000F03D1002D43D0A8463EE004A81BF048FA14AF0D230A940DA880
+:20EC4000089706F13C028DF8303096F82610CDF814801B4C049004270992032904F13403C5
+:20EC600018688DF8317016D10695079596F840100B9104A91BF054FA38B996F8402006F17A
+:20EC8000410029461AF006FBCA46284615F084FF606B96F8261002290AD1CDF81890CDF8EC
+:20ECA0001C90CDF82C9004A91BF03AFA00B9CA46404615F071FF504619B0BDE8F08FC046EE
+:20ECC000D4DB002090B50446E08948F20601ADF1240D814211DB81421CD0133800F0AB8099
+:20ECE0001939401A5CD0401E51D0401E00F09780801E21D0401E16D0ADE01A31401A00F063
+:20ED00008480401E78D0401E6CD0123860D0801E55D0A0E0204617F07BFD011C00F09B80E5
+:20ED20004E4B40203AE0204617F072FD011C00F092804B4B202031E06846002118220FF0D6
+:20ED400005FEA06910F8011B8DF800109DF800704278017801EB0221ADF802101FB9C01C3C
+:20ED600001A90DF019FC61883E4B10206A4618F0CDF8039818B115F00FFF002003900598F1
+:20ED8000002868D015F008FF0020059063E0204611F0D8FA011C5ED0334B02200F4606E0B0
+:20EDA000204611F0CFFA071C55D001202F4B61883A4618F0ABF8384615F0EEFE4BE0A06989
+:20EDC0002B4B007807AA8DF81C004FF480003FE0A069284B00780DF11B028DF81B004FF41F
+:20EDE000801035E0A069244B00780DF11A028DF81A004FF400402BE0A069204B007806AA9B
+:20EE00008DF818004FF4005022E0A0691C4B00780DF119028DF819004FF4804018E0684678
+:20EE2000002112220FF092FD204669460BF08EFD144B04200BE0684600210C220FF086FD67
+:20EE40002046694619F05AFB0F4B4FF080706A46618818F05BF809B090BDC0465120020043
+:20EE6000F51F02005BBD01002D1402008F140200DD6E0200AD6E02003D6F02004D6E0200A6
+:20EE80007D6E0200E18A01008D4102002DE9F04F07467E6931780120ADF13C0D00EBC10063
+:20EEA00080B21BF0F9F95FEA000808BF002000F0CB80307800254FF08F0B4FF0860A88F8BB
+:20EEC000000041E06A00B018B0F8010008EBC504641CB21820803968B2F80120087D89888E
+:20EEE00008AB14F039FE01282AD19DF82710C80909D2002031F07F0318BF01207A68C2F336
+:20EF0000C00282421CD1480817D33868490900F1060909D3007D1AF02DFF031C04D0484642
+:20EF200008A90122984700E00020A0709DF8261040B9E1700A98606004E084F802B001E0A4
+:20EF400084F802A06D1CEDB23078A842BADC3968087D7B688D888E1D00240D9697F80AA07A
+:20EF60000C90464631780E95D808254680F0010000F0010B19E0EA00B018B218D778E41CA1
+:20EF8000A4B2401C7FB94168641CA4B229B902880E990C9818F0B8FF02E0C07817F0A0FBD6
+:20EFA0003178001984B26D1CEDB2A942E3DC20461BF072F95FEA000942D00746002527E0CE
+:20EFC000E900701871184978401C07F8011B0188091207F8011B817807F8011B8378ABB9CD
+:20EFE000C17807F8011B416859B90BA9009102880E990C983B4618F061F8BDF82C003F18CE
+:20F0000004E0C0783A4608F033FD07466D1CEDB23078A842D4DC00200090CDF804B0012328
+:20F0200002930390CDF810A00594CDF8189007930E9A0D990C9801F03BF948461BF06CF87F
+:20F0400030461BF069F801200FB0BDE8F08F70472DE9F0410D4680460E220021ADF1200D97
+:20F0600003A80FF073FCA86A417811F01F0F18BF002040F0BD80880924BF01208DF81800E7
+:20F0800031F07F001CBF01208DF81700C80924BF01208DF816009DF816200024012A03D0DB
+:20F0A000287A00B1AC6902E0E87900B16C6934B10DF10E0021461BF06FF89DF81620A98958
+:20F0C000012AADF80C1020D14B4A5778167F27F00100064300F08B80002F00F08880022FA6
+:20F0E00004D11AF0D1FE884240F08180688915F0F3FC00287BD144B11AF09CF801460DF136
+:20F100000E0019F075FF002871D03C4E96F83200800815D39DF81600012811D0BDF80C10BB
+:20F120001AF0B2FE88420BD09DF81700012807D008461AF05BF818B1BDF80C0016F05CFB32
+:20F140009DF81600012821D0BDF80C101AF09CFE884211D19DF81700012808D02848007834
+:20F1600000F00700022807D101208DF818009DF818000AF07DFF35E09DF817209DF81830F7
+:20F1800008460DF10E0107F051FE2BE000249DF818008DF81A40E0B99DF8175007461AF027
+:20F1A000BFFC96F84A00082818BF042811D14FF6FD70ADF800001AF03DF801908DF80940B2
+:20F1C0008DF808708DF80A508DF80B4068460DF005FB9DF818000AF04BFF52200DF11A015C
+:20F1E00016F01AFA0748016809B103A88847404608B0BDE8F081C046ACFE0020E4FA0020E7
+:20F20000E41201208CFD0020F0B50C460546A9792068ADF1440D40EA01406979206040EA5C
+:20F22000012029792060084310F0070F206015D000F00701022920D14FF0FF30606005F18D
+:20F240000801082204F108000FF0C5FE04F1100005F1080101220FF0BEFE0DE0201D05F1BA
+:20F26000080104220FF0B7FE04F10800FF2108221BF014F8FF202074206841097AD2410932
+:20F2800011F0030F18D001F00301032914D0012918BF022922D104F11100FF2108221AF0F5
+:20F2A000FDFF4FF6FF7005F108010222608304F11C000FF090FE10E004F1110005F1080105
+:20F2C00008220FF088FE04F11A0005F1080102220FF081FE4FF6FF70A083206800093ED356
+:20F2E00004F11E0005F1080101220FF074FE206805F10806C10B3CBF4FF0FF31216206D34A
+:20F3000004F12000314604220FF065FE2068000C06D204F12400FF2110221AF0BFFF05E055
+:20F3200004F12400314610220FF055FE2068410C3CBF4FF6FF71A18606D304F13400314694
+:20F3400002220FF048FE2068800C38BFFF200ED304F13600314601220FF03DFE2EE04FF0ED
+:20F36000FF312162FF20A0774FF6FF77A78684F8360023E000252846694618F025F90A286D
+:20F380001CD00D2817D0276817F0070706D10DF10600211D042219F0DDFB48B9022F0AD194
+:20F3A0000DF1020004F11101082219F0D3FB10B1684619F084FB6D1C052DDCDB11B0F0BD6E
+:20F3C0002DE9FC4F83F0004301E02DE9FC4F1F03FF0847EAD2574FEA42284FEA43095FEAE0
+:20F3E000595906D147EA080A1CBF00210020BDE8FC8F57F000575FF4E06E1EF1FF0EF14564
+:20F4000005D14FF00000190D0905BDE8FC8F002B05D55FF0000AD8F100086AEB07070C03D2
+:20F42000E40844EAD0544FEA40254FEA4106760D08D144EA050A19BF00210020191C101C5D
+:20F44000BDE8FC8F44F00054764504D10020090D0905BDE8FC8F002904D55FF0000A6D42E6
+:20F460006AEB0404B6EB090E08D5A2463C465746AA464546D046CEF1000E4E46BEF1360FAD
+:20F480005CBF4FF0000B23E0BEF1000F04BF4FF0000B1AE0CEF1390ABAF120092EBF08FA7A
+:20F4A00009FB07FA0AFB4BEA080BDEF1200A07FA0AFA38BFBA4647FA0EF72DBF28FA0EF8AB
+:20F4C000AEF1200E4AFA0EF8D04415EB08057C4154EA050A02BF00210020BDE8FC8F002C8C
+:20F4E00058BF4FF0000A06D55FF0010A5FF0000E6D426EEB0404A6F101066D006441FAD58B
+:20F5000015F4806E11D005F480794BEA090B15F5806554F1000428BF761C0BD205F40079D8
+:20F520005BEA090B08BF25F4006525F4E0656D0044EB0404B61CDEBF00210020BDE8FC8F4B
+:20F540005FF4E06E1EF1FF0E76450AD34FF0000013F00043FF21C900C91D09051943BDE8F3
+:20F56000FC8F270547EA1530210B41EA065141EACA71BDE8FC8F704767492DE9F04705461B
+:20F580000878ADF1580D002800F0C280A878884610F007008DF844000FD0022840F0B8805F
+:20F5A000A96812A808221AF079F8A96801F10800A86090F800A009310EE0A968CA780878A5
+:20F5C0008F784E784FF0000A00EB0260091D00EB074000EB062012900846491CA9604C1C99
+:20F5E0000F460678AC603C78E32E18BFF32E05D19DF844101298084340F08A8004F1180074
+:20F6000080B218F06AFF071C00F08280FF2C08BF002487F810A04FF0010987F80390A96881
+:20F6200007F1170022461AF039F8BC75381D11A90C227E741AF032F8484616F01BFBB874AE
+:20F640000520387000267E70A878000903D3F87840F02000F870314CAA8804F13A01D8F8F3
+:20F6600010000988914215D011A869460DF1520210F06CFB60B99DF80000800808D3694650
+:20F68000087800F0FD000870BDF8520013F0CEFEBE7038E010B18047002839D088F801909F
+:20F6A00011A8694614AA10F051FB60B99DF80000800808D26946087840F002000870BDF83A
+:20F6C000500013F0B3FE87F8029094F83C1088F80410A8790B30814215D0114E306A1AF0A2
+:20F6E000A0FB40B9306A41F288311AF005FD06F1BC001AF08DFDA87904F13C010B30087097
+:20F70000E12015F089FF07480078394613F0C4FF16B0BDE8F087C04620040120E4FA002024
+:20F72000481900209C0301202DE9F043002407460C22ADF1340D214668468DF814400FF0D4
+:20F7400005F9624DDFF88881B87804281DD001280BD0062809D0022805D003281CBFB320F0
+:20F760008DF8140014D11B2010E0687858B91AF055FD40B9B9684646082206F11C0019F0A7
+:20F7800089FD38883080232000E022208DF804009DF81400002840F086803888BE7BADF8E0
+:20F7A00000003B698DF805607A7B0293012A14BF012021208DF80200684605F06DFE9DF8A7
+:20F7C000140000286FD10398466C05233370B8787070796829B9B01C214610220FF0B6F8B0
+:20F7E00003E0B01C102219F055FDB8781236012812BF0628F87806F8010BB96830461AF012
+:20F80000DFFAB8780836042806D0012804D006281CBF387B307004D1AB202146324613F0C4
+:20F82000A3FE388815F058F910B103980421C1829DF81400002836D1B878042809D038699F
+:20F8400018B9684615F0A8F82DE068460CF032FD29E0B8680BA906AA0EF0FAFF06469DF839
+:20F860002C0018B94FF6FF70B0421CD038694FF0010918B9684615F08FF802E068460CF078
+:20F8800019FDB96808A8082219F004FD8DF8289020468DF8294031461422079006AB069031
+:20F8A000042016F0CFFE687850B91AF0B7FC38B946462146082206F11C000FF047F8348098
+:20F8C0009DF814000DB0BDE8F083C046ACFE002070020120F8B5694C21680546143108685C
+:20F8E000407F002800F0C880D1F8C000B5F84220C08C904240F0C080D1F8581305F1280071
+:20F900008847002800F0B880206840690026467721687031486E90F8290028B16068816A97
+:20F920000220884721687031086890F82B0018B16068816A01208847287C400908D360688D
+:20F94000816A102088472068D0F82813802088476068C16B202088472168C868D1F8FC142E
+:20F96000103088476868226841785269007800EB0120C0F30321517622685269C0F3003759
+:20F9800097762268526900F00F03C0F3031793772068D0F8D40080F82C7022680C32D2F872
+:20F9A000C81091F84F000F2806D093689B7F984202DD6B68DF780FB19068807F48731068A8
+:20F9C00080F83060D2F8C800417B0F290BD19068C07E022850D1D2F8580180472068D0F802
+:20F9E0006C018047F8BDD2F800252846904723680C339868C07E022815D1D3F8F014186883
+:20FA000088472268D2F8D4001169467BD06831F81630D2F8F0244FF4707707FA06F1C91A2A
+:20FA2000904723680C33D3F8C8002A89D3F8A83190F82C1002209847206800F11401D1F81F
+:20FA4000C020D0F8D400527B90F82C0082420FD00868D1F8E81488472268D2F87C01516977
+:20FA6000886050694169D2F8F024904721681431D1F8141310208847F8BDC04614010020D9
+:20FA80002DE9F047634F8046381D0068416EADF1280D02A888475B4D2A684032106800685D
+:20FAA00020B9D2F80C0580472A68403256484FF001096E6880F80090F068007830B9D2F87F
+:20FAC00018244846002190472A684032106801684C68088921788246C1F3401109F096FF46
+:20FAE000079011F0B7F8494E746786F873A00024A6F866401AF06AFB059482463146B8F164
+:20FB0000010FA6F8664004BF4148C1F8B80038F001083E4654D1A1F89E4001F16400C1F874
+:20FB2000A00091F8A90002231A4602F00F0220F00F00024381F8A92091F8A80004F00F078A
+:20FB400020F00F0047EA000291F8B3708C6627F00F0081F8A82040F0040009F00F0291F887
+:20FB6000717081F8B30027F00F00024381F8712028684030006800684268127801F16407A2
+:20FB800092090FD301F120028A66406891F87150807803F00F0381F82E0025F00F000343E4
+:20FBA00081F8713001F1100001F19C0242604A7F04F00F0322F00F0213434B77014601E0C5
+:20FBC00064310F467068174A056D08238DE81800114B106802AAA84710490028088006D486
+:20FBE0000F4991F90000B760401C087004E0484641F2883111F05AFA50461AF071FC0AB0BE
+:20FC0000BDE8F087140100200F05012050180020801A0600DCFF002045BA000028050120EE
+:20FC200012050120800001202DE9F8430D4606466868002800F0C580007819F04DF90028DF
+:20FC400040F0BD8019F0DAFB052880F2B6804FF00008304685F8018019F030F9041C01D0A6
+:20FC6000207B60B11C200CF0F5FF041C00F0AB8041461C220EF06AFE2671012600E046461C
+:20FC80006868007820736868007A504F2076142027610CF0DFFF0028606141D041461422BD
+:20FCA0000EF054FE6968626949689079897900F0F00001F00F010143917168684068616933
+:20FCC000808888806868406861690078087068684068616940884880686840686169C07995
+:20FCE000C871686840686169007B08736069C07940000CF0AFFF616988606769B86818B13C
+:20FD00004046F97981424EDC387B40000CF0A2FF3861606907691FB14146027B8A4238DCE8
+:20FD200004F10C00814608F00FFE0746022F18BFB82F06D1207B13F0B9FD484608F004FE07
+:20FD4000074637B9012E1FD1204615F05BFFC0B11AE0012E15D0606968B1816819B1084620
+:20FD600014F01AFF6069016919B1084614F014FF606914F011FF4846414610220EF0E6FDFF
+:20FD800002E020461AF0C0F9022F18D0B82F16D019E06B685B684A001B690069D35A13521A
+:20FDA0006069491CB9E76A68526841009268BB688A5ACA526769401CA3E7D12002E0D02012
+:20FDC00000E0022068700120BDE8F8832A1A00202DE9F04FDFF898910646A9F1080000F170
+:20FDE00008078068D0F80001807AADF12C0DC0000CF030FF0028089008BF1A2500F0B4809D
+:20FE00001AF0E4F900244FF0FF0B25460A9027E0ADF800608DF80240D2F88823D0206946A2
+:20FE20009047D8B99DF80C00012802D19DF80B1019B998B99DF8071081B1002814BF0823E6
+:20FE400004230DF103005B1E00F801BBFBD105703868D0F894246946D0209047641CE4B260
+:20FE60003A6802F580721068C07AA042D0DC4C462068D0F80001C0884FF6FF78AA461DE0E3
+:20FE8000089901EBC0018A8896421CBF401CC0B261D1C1F800A0A1F804803A68D42004A996
+:20FEA000904702E07F1CBFB225E020682268D0F800016D1CEDB202F58072C088A842D8BFC3
+:20FEC00055464BDDADF80060ADF80250D2F88823D120694690470028E7D1BDF80400804519
+:20FEE000E3D0ADF810002068D0F8882404A9D420904790BB5746226802F580721068C0880B
+:20FF0000B84210DDADF80060ADF80270D2F88823D120694690470028C4D1BDF81000BDF8BB
+:20FF200004108842BED12068D0F80001C088B842BBD1ADF81480ADF8168006A8594608224A
+:20FF40000EF004FD2068D9F8003000F29447D3F80001837A5046834292DC19250A981AF0D0
+:20FF6000BFFA089814F018FE28460BB0BDE8F08F140100202DE9F04F654CE768ADF1140D78
+:20FF8000002F00F0C2804FF0000A5046039094F8028004903DE094F8028035E00A200CF086
+:20FFA00059FED4F80C80071C00F0AF8019F0BBFB0BEB0800808805EB080104220E31388075
+:20FFC000B81D19F067F9049D3A88029948466B460CF040F8012808BF0125284604F11805DC
+:20FFE00020B10199B81C042219F054F9B000394600EB061040190C3015F02CFB012800F03C
+:020000040001F9
+:200000008480204690F80280E7680AF101005FFA80FAD04579DD16201AFB00F5E919785DCC
+:2000200049888146029116F087F9AB460646FF2EB4D12278002F8C46E7D004984FF6FF7678
+:20004000B646014615E0162310FB03F5EB197D5DA9450CD15D88AC4509D1DD88AE42C8BFF7
+:200060002E1C1B89491CC9B29E45C8BF9E46401CC0B28045E7DC0029C7D0042A45DC90006F
+:2000800004F11805634600EB0210291881F80190DDF80CC04B8007198E80521CA1F806E0D6
+:2000A00007F11803A1F808C066461E6131461973D7B229540A2027700CF0CCFDE668071CA1
+:2000C00023D019F030FB06EB0B018888042238800E31B81D19F0DEF83A88029948466B467F
+:2000E0000BF0B8FF012804D10199B81C042219F0D1F82178880000EB0110401939460838B5
+:2001000015F0A8FA01287FF446AF05B0BDE8F08FF00C01202DE9F04160485F4E614C604DBB
+:2001200070601030B06004F14400B0E88C1005F17C01A1E88C108DC881E88D00182204F120
+:20014000140705F1340039460BF0D0FC1822394605F14C000BF0CAFC05F16407182238463F
+:2001600004F12C010BF0C2FC95F870003C2204F1840140F0800085F8700005F1BC000BF085
+:20018000B5FC95F8CB100120024602F0010221F001010A4385F8CB2095F8CB1060F38201E2
+:2001A00085F8CB1095F8CB1021F0200185F8CB1095F8CB1060F3C71185F8CB1004F16401B0
+:2001C000B1E8085105F19C02A2E8085191E80A5082E80A50C5F8A07095F8A81060F3C711E2
+:2001E00085F8A81095F8A91021F00F0141F0020185F8A910042385F8AD30052185F8AC1019
+:2002000095F8AE1000F01F0221F01F010A4385F8AE20032185F8B01095F8B31000F00F0207
+:2002200021F00F010A4385F8B320B4E8841005F12001A1E8841014CC81E8140095F82C1076
+:2002400060F3C71185F82C1095F82F1003F00F0321F00F010B4385F82F3095F82F1060F37F
+:20026000C71185F82F1095F82D1000F00F0021F00F01084385F82D004FF4586028630A4833
+:20028000F0600A4800684069007808B10CF056FC0AF0A4FDBDE8F0817000012038FA002098
+:2002A000501800208CB4020068050120180100202DE9F04F09AF9A4690468146ADF1240D54
+:2002C000B7F814B0BE89069119F0ECFC0028079008BF022000F0B38019F054FD0446E00984
+:2002E00008D259481830056825B1687E012808BF44F0400404A80021082219F0CFFF3D7827
+:2003000035B904A90868002220F00300086006E00498012220F0030040F001000490079819
+:2003200085683DB16888534641460090484615F0D5FD08B9012082E0002E04BF0498C0F359
+:20034000800607D004A90868ADF81460012640F0040008603D7925B904A8016821F0080184
+:2003600003E004A8016841F008013D7A016025B904A8016821F0100103E004A8016841F0F5
+:2003800010010160387C8DF817A0002E8DF8160014BF05200320584480B2814619F07CFFFE
+:2003A000061C4AD0049901F003010170049AC2F3800241EA8201C9B20170049A02F00802F5
+:2003C00011430170049A02F01002114300F8011B0499C90808D39DF8141000F8011BBDF883
+:2003E0001410091200F8011B9DF8161000F8011B9DF8171000F8011BB9695A4619F04EF9F9
+:20040000387F68B90F480096811C01910294007803900799069842464B46FEF791F907E08A
+:20042000009601940698079942464B4608F072FE0446304619F070FE00E01024204609B068
+:20044000BDE8F08F800301208003012001282DE9F84F40F0B080DFF88491D9F8340101282F
+:2004600040F0A6800220C9F8340118F01DFC012015F070FC5FEA000805D00120C9F834011E
+:2004800018F020FC99E0112019F052FD00280CBF00250125102019F04BFD08B145F0020582
+:2004A0000F2019F045FD08B145F00405444CA06A0068014601208847012805D099F83801CA
+:2004C000012818BF002703D1002004F021FD012719F028FDDFF8ECA040080AD20026206A62
+:2004E00080680146504688478346BBF1040FF6D000E00126304600214FF0FF3202F0DCF846
+:20050000012E0ED0BBF1010F05D1206A4068012102465046904732496C39086840F0030070
+:200520000860206840690146284688470B2019F0FFFC254E30B12068C06A3146091D024684
+:20054000088890470A2019F0F3FC28B12068C06A31460246088890471C4903200124C9F8F3
+:2005600034011B4E0C6000233360284613F048F80128FAD1174D2868042015F0EBFB0646C7
+:20058000154804602868012F02D1204604F0C0FC19F09EFC082015F0DDFB0746C9F83441C6
+:2005A00018F090FB57EA060018BF4FF0FF3804E06FF0040801E06FF001084046BDE8F88FCA
+:2005C000B8010010004003401ABD0200282008600C2008402C2009400C4009401015002063
+:2005E00090220840F8B5074661485F4C001DC26A0168B7F5C067C2F30722C4F81071C1F35F
+:200600008441C4F81421C069C4F81811C0F38120C4F8280100F0A38094F830616EB9C4F8CA
+:200620002C71D4F81801C4F82001D4F81461C4F81C61D4F82851C4F82451D4F82C01D4F8A6
+:200640001451002854BF02236FF0010304F59072116800EB4000C018431000EB937001EBCE
+:20066000A0011160D4F82011C4F81C5100291CDD1E293DDDD4F8240130B93429B4BF1539C7
+:200680001E21C4F8201125E02A29BABFD4F820010B381E20C4F82001D4F81C013E28D4BF30
+:2006A000401C3F20C4F81C011FE0D4F82401032812D011F10A0FA6BFD4F820010B300120E0
+:2006C000C4F82001D4F81C010028CCBF401E0020C4F81C01032009E011F1140FA6BFD4F8E8
+:2006E000200115300120C4F820010020C4F824014FF08057D7F8A401B4F81C111B4D406822
+:200700004FF47F4208230646009128463021B047D7F8A40101214FF400321123406800919F
+:20072000064604212846B047D7F8A401B4F8201140684FF4F8021223064600910421284608
+:20074000B047D7F8A401B4F8241140684FF440620A230446009120212846A047F8BD00204D
+:2007600084F83001F8BDC0461015002000A00C4000A00C402DE9F8435F4CDFF868815B4D90
+:20078000D4F83C0100286ED0574E401E0AD0401E60D0401E1CD0401E53D0401E1AD0401E0E
+:2007A00033D02FE04E4801250221006884F83A517022042340680091002107464046B847F4
+:2007C000356004F1500019F0F7FC2846BDE8F883022100E003214FF08059D9F8A40184F884
+:2007E0003A1140680025702204232946074600954046B847D9F8A401C0687022294613465A
+:200800000125DAE70320BDE8F88300262E606E6028688008FCD268688008FCD23748344924
+:200820000127001D06600E200F6008F057FE022016F044F9C4F83C6184F83B610220BDE886
+:20084000F8830520C4F83C010027376030688008FCD242E00320C4F83C01002737603068BF
+:200860008008FCD239E0234F01260F202E6042F62A21C7F80B004FF08059C7F80F10D9F89F
+:20088000A40140684FF4C072072302218446404600910021E047D9F8A401C06800214FF41E
+:2008A000C072072384464046E0472E6028688008FCD394F83901C7F81B6018B903210020DB
+:2008C0000E4602E0002028630321C4F83C6147F8011C686068688008FCD20020BDE8F88330
+:2008E000A401001000A00C4058600C4054600C4004800C4001400C401015002038500C40DD
+:200900002DE9F0410D46044602220021ADF1480D11A80EF01BF800263046694616F054FE4E
+:2009200007460A2F00F0AD800D2F32D094F825809DF8000008F0070100F00700884227D157
+:20094000B8F1000F0BD104F12C000DF10601042218F000F918B1E06A6860002015E0B8F11D
+:20096000020F16D104F118000DF10201082218F0F1F870B105F1080004F11801082218F0F7
+:200980008DFE94F83000287402208DF8440005E00227761C052EBFDB002F72D19DF8000015
+:2009A0009DF844709DF801609DF80D30C11007F007009DF845209DF80D7001F018010143FD
+:2009C00006F0010094F8296041EA401103F00300002E41EA80118DF8441002F0F800C7F332
+:2009E000820141EA00018DF8451007BF9DF8450000F0F7009DF8450040F008008DF845000B
+:200A00009DF84510676B94F838602A8841F050016F619DF844002E7601F0DF0110432880A9
+:200A200040EA0120288094F840008DF8451050B1687619F031FCE86128B194F8402004F105
+:200A4000410118F02BFE104894F9151000880829288405DC11F16D0FB8BF6FF06C0100E032
+:200A60000821A77D6E3148B2002F4FEA60010CBF00220222C8B285F8220040EA821085F864
+:200A8000220012B0BDE8F0811EFB00202DE9FE4F5B4C5C4994F83C80B4F848500A688346AD
+:200AA00001A8026049684160DFF85CA101A80AF11409494618F09CFA00280CBF01260026D7
+:200AC000A76887B11EB93888854206D008E007F10C00494618F08CFA10B1B878804502D00A
+:200AE000BF69002FEED1002F08BFCA2000F0858039894FF6FE70884208BFC3207DD019F0CC
+:200B0000D5F9884208BFC22077D03888A84218BFA4F8480017F094F9F87A4946401C84F87B
+:200B20005C0004F15D0019F037FB02208DF80100684617F069FD04F12405061C58D0306908
+:200B4000062100F8011B94F8321001704FF0010986F81E9018F06EFB706286F81A904020DB
+:200B6000F0823889708086F818B03046FBF784F8061C3ED1092084F84A003B89E38794F84E
+:200B80003C00804518BF84F83C8005F11A014B2014F042FD05F12401502014F03DFD05F1C7
+:200BA0001801E12014F038FD05F11601532014F033FD082049460AF063F94FF4005000216D
+:200BC0000AF05EF920784FF4806111F0A9FB0F480078022804D008200FF0C2FC820001E04E
+:200BE0004FF4DC6220784FF4806119F0B4FA00E0102600208AF805003046BDE8FE8FC04696
+:200C0000E4FA0020E0B8020034FD0020ADFE00202DE9F043054603200C46ADF1340D8DF8B3
+:200C20001E000DF1160019F0B7FA18F003FB01460DF1160018F0DCF9002800F08980207DCC
+:200C4000032818BF012840F08380277A002F7DD0FE2F7BDC032804D1A07D002876D0FE28E4
+:200C600074DC45490A6809A8026049684160DFF80C81082209A908F10C09484617F004FDDB
+:200C800028BBAE1C3E483188008888421FD040460178FF2909D0B94207D040884FF6FF71D8
+:200CA000814202D06189814211D100208DF808004946082203A818F0EDFA02A80FF026FD44
+:200CC0003088BDF80A10884218BF8D2042D12D48EB890768AE1C212B11D02B48076867B1E3
+:200CE000207A6189A37D04F10C02B84728B900208DF82C0016F0B4FF2EE088202AE08C2077
+:200D000063898DF82C00ADF822302FB30DF122000090A27D207A04F10C010123B847D8B146
+:200D200000278DF82C7016F09BFF207D032813D104F10C0008A915F019FE04F10C0858B937
+:200D4000394640460A4610F0F5FC05E0822000E08420AE1C8DF82C000BA80090287C01904F
+:200D6000EA893146012305F1110042F4004213F07DFC0DB0BDE8F083B8C3020094FF002065
+:200D80001EFB002000030120BC0001202DE9F04F0446E078ADF11C0D400810D304F1130028
+:200DA000FF2103220DF0D2FD012001904FF0000903902079CDF8089030B1022801D00120A2
+:200DC00099E00820009005E00427E078009700F0DF00E0704F464A48039E0497C8460597B7
+:200DE00000F1100B069660E04FEA88005BF8007000EB0B0A002F52D025793E79B5424ED1CB
+:200E0000009A07F1080004F1080117F03DFC002845D0A3785BB9022D06D1E078800903D3D1
+:200E2000387C217C88423CD1069F02970FE0DDF818903EB1E078800906D3387C217C88421C
+:200E400002D02EE04F460297B9F1000F24D0042017F043FB071C1FD00498787006263E70FE
+:200E6000DAF80000807CF870DAF8000017F01CFC0598B9F1010FCAF800001CBF0420B8700B
+:200E800005D10698B870059E0396CAF800401B480078394612F000FC029810B12AE0CDF8F6
+:200EA000048008F101005FFA80F8B8F1000F9BD0029D45EA0905012D1CD0042017F00DFB97
+:200EC000011C17D0059806224870019F0A70A27CCA7057B9A078012818BF042005D138467F
+:200EE0004BF82040059A0392022088700348007812F0D2FB039807B0BDE8F08F9C03012039
+:200F0000481900202DE9F84F534D2968D1F8D40090F883A040310868006820B9D1F80C057E
+:200F2000804729684031886F4C4EDFF83491DFF834810078E8B919F049F9377883464FB94B
+:200F400049460F7837B9832041460870584619F0C7FA60E002214046BAF1010F017004D197
+:200F60003078832801D110F08DFF584619F0B8FA65E014F023FC3C4800683C4F016C38687B
+:200F80008847044619F022F9824630460778002F44D149460F78002F40D12868D0F8B800AD
+:200FA000C16C002088472868D0F828246946F42090479DF90000A0421EDC2D4CA079D8B942
+:200FC000504619F08DFA6078042803D02868D0F84C05804704204146A7792E680870781C37
+:200FE000A071D6F8B800C16C09B103208847032060810FF0C7FD22E08320414608700020F6
+:2010000015F09EFA504619F06BFA1A486968C01D09690078087017F019FA10E00222414608
+:201020000A700078832801D110F02CFF504619F057FA2868D0F8B800C16C04208847686826
+:20104000C068007828B92868D0F85824002001469047BDE8F88FC04614010020051401205C
+:20106000071401200A140120E0FF0020800001204C0201204D0201202DE9F0410646746807
+:20108000B56819F0A3F8D4F8C0108046002900F0A18094F8F80028B9087C032818BF0428DC
+:2010A00040F09D80287919F093F8D4F8CC0041686F690968CF6294F8F90018B92968C868DC
+:2010C0004009FCD22968486820F002004860D4F8CC0041682F690968CF622968486A20F030
+:2010E00003004862D4F8CC002A6941686B69096843EA0200C1F804052968486920F00100E6
+:201100004861286801270762D4F8D400D4F8C0100860D4F8D87067B1E8698068C0F3091030
+:20112000401C874205D3D4F8C0201168C919091A1160D4F8DC7067B1686A8068C0F3091061
+:20114000401C874205D3D4F8C0201168C919091A1160304610F00CFE287919F033F8287901
+:2011600019F038F8D4F8C070386857B100230222397C03291CBF04293A743B607F69002F02
+:20118000F6D1D4F8C0100860D4F8C8100022002904BFD4F8C000C4F8C80004D04869B8B9CC
+:2011A000D4F8C0004861C4F8D020C4F8D420C4F8D820C4F8DC20C4F8C020C4F8C420404670
+:2011C00019F08EF904F1300019F020F8BDE8F0810146E3E72968486820F002004860404691
+:2011E00019F07EF9BDE8F0812DE9F0418046D8F80460D8F80050307817F0CAFC7178002773
+:20120000814249D02879401E28D0801E1FD0801E012803D9001F14D0801E35D1287C10F080
+:20122000120F08BF02240AD00324AA69E96928682C71891A18F0BEFF286818F0BDFF2C71B4
+:2012400022E0287C800928BF20270A201DE00421287C2971800828BF022717E019F044F9D2
+:20126000297CA860480828BF012711F0120F0BD00322AB69E96928682A71C91A18F09AFF2B
+:20128000286818F099FF01E0022028717078002850D0012851D055E02879401F26D0401E7F
+:2012A00017D0801E08D0C01E3ED10721287C2971C00828BF042739E0A86818F0BFFB297C14
+:2012C000E860C80828BF0427080928BF47F008072AE0A86818F0B2FB297CE860480928BFB2
+:2012E0001027C80828BF47F004071DE0287C80090ED2A86818F0A2FB07212971297CE86050
+:20130000C80828BF0427080928BF47F008070DE00822AB69296A28682A71C91A18F04AFF90
+:20132000286818F049FF01E007202871707820B1012807D14FF4A02101E04FF4C0213078C1
+:2013400015F074FF2FB1686918B10246394640469047BDE8F08170472DE9F043584C94F831
+:201360004201ADF1140D002840F091804A484B4E4FF00108027B3368416884F842818146C8
+:2013800084F84121C3F38147C4F86C11BFB9D9F81000A0B156F8085C18F06AFD6421024620
+:2013A000C5F306604143B1FBF2F23D49002304F1940013F031FB3B494FF00040086001A886
+:2013C00018F04BFE00252F4604F10C00029501AB8DF80470344903953A4613F01DFB01A88C
+:2013E00018F03BFE04F150000822029501AB8DF804702E49039513F00FFB2D4A04F1D800A1
+:2014000032213B4613F0C6FE2B4A2A4F04F1F4002C212B463D6013F0BDFE306899F80D30DB
+:20142000C0F381501BB1032803D184F8398103281FD002281DD001281BD14FF08059D9F8F8
+:20144000A4011E4C406803214FF040521C230746009129462046B847D9F8A4014068294662
+:201460004FF4007209230746CDF800802046B84706E0386840F040003860022015F036FBAE
+:2014800056F8040CC00802D2284615F02FFB05B00020BDE8F083C046FCC10200B44F0050B0
+:2014A0006595020000A10C404F510100553D0200917E02009022084095F2010000A00C408F
+:2014C000101500202DE9F04F044608469A46ADF1240D214605908E680692129B04914C68AB
+:2014E000756807935044854238BF6FF00304C0F093804B4D28684FF0FF3118F008FB4948C7
+:20150000328C079F48496368026083460B60780819D23846800813D3F768002F3AD03569E8
+:20152000002D37D000970195012002900599069A049853460DF0ACFB5FEA000813D114E057
+:201540004FF0000811E0A0683AEA00070AEA00021CBFB1680A4405990140049808F010FB6A
+:201560005FEA000801D0044652E034680598DDF818905746241805E0BBF80010049818F0F2
+:20158000ABFAA944AFB90798C00840D3F16809B1306910B96FF007043AE000910190002795
+:2015A0000297069A0599049853460DF071FB80462DE0049810F0BCFF38BB049814F00AFFF0
+:2015C00018BB04F0FF05C5F58075BD4288BF3D1C210C8DF80D1002208DF80F40230A8DF87B
+:2015E0000C00BBF8001004988DF80E3018F06BFA03A8042111F0DAFD7F1B641928B9484622
+:20160000294611F0D3FD0028B6D04FF0FF3844460348006818F0F0FD204609B0BDE8F08FF1
+:20162000A8130120A4130120A0130120F0B50446207CADF13C0D0F28C0F2A680656860690B
+:201640000DF1260210F07AFC9DF82600002840F09B80207C0B28C0F29780287A022840F02C
+:201660009380A88900F00F010F2940F08D80C0F303100F2840F088809DF82860002E18BF5A
+:20168000022E40F08180424C404894F84A20022A3BD00068062A39D010B18179012935D01B
+:2016A000082A18BF042A6FD16D8910B18079022827D0B4F84800854266D1012E07D004F1F5
+:2016C0005D000DF12D0117F093FC00285CD120784FF4007113F040FA002855D1E06C0290E1
+:2016E00001268DF80D6002238DF80E3094F852708DF80C7002A80FF08DFF10B114F0FEFCA6
+:2017000042E0284615F0B8FF3EE0006840B900230093288869896A7C04F054F89DF8286063
+:201720002888ADF810006889ADF81200A87B8DF81400AF8900206FF30E0707B101208DF8B3
+:2017400018608DF815009DF827408DF819409DF82C708DF817709DF82A009DF82B308DF82C
+:201760001600687C0DF12D018DF81A009DF838608DF81B3008228DF81C600DF11D0017F05A
+:2017800089FD04A804F036FD0FB0F0BD38040120E4FA00202DE9F04380460E20ADF1340D0D
+:2017A00015464FF001098DF80100B8F1000F8DF8023050488DF8005000F1010000788DF834
+:2017C00004900F468DF8030047D1112004A93A2218F00BFB00283CD1444E0DF111007B19CE
+:2017E0009DF80320716803901C4642F02802481C7060581C227017F041FD054617F01AFD1F
+:201800000146284618F0C8FC48460DF131013A2218F0EBFA083500280CBF9DF8310000202A
+:20182000287017F007FD01460DF1210018F0B4FC7088401C80B27080B0F57A7F02D8706821
+:2018400001282FD12A4800784FF4007110F0AAF928E000207C19039024E07C19ED19687B4C
+:2018600011F054FC3A2808D03B280FD1112004A93B2218F0BAFA30B108E0112004A93A22A0
+:2018800018F0B3FA10B90DF1110000E0002003909DF80300217808432070611D0DF121007F
+:2018A00018F07AFC0DF12900611C042217F0F2FC039E2078002E8DF82D0008BFA12012D068
+:2018C000404669460DF121023B4604F009F9054620780021102200F0F80020700DF111007E
+:2018E0000DF034F828460DB0BDE8F083480401203BFD002013FB00202DE9F047564CA4F105
+:20190000080000F108058068D0F80001807AADF1280DC0000BF09EF90028089008BF1A242C
+:2019200000F0958018F052FC8246286800F59162D0F8000100894FF6FF780026C14608E0E9
+:2019400020682268D0F80001761CB6B202F591620089B042D8BF002473DD2068D0F80001F1
+:20196000C07A0127002548E0ADF81480ADF8168006A8FF2108220CF0E9FF2068D0F8942460
+:2019800004A9D42090472068ADF80480D0F894246946D12090472068D0F800012268C08804
+:2019A0006D1CEDB202F5916230E0ADF800608DF802501268D02069469047A8B99DF80C0037
+:2019C000012810D19DF80B0068B90DF102020820002112F8013FFF2B03D1401E01F1010157
+:2019E000F7D10829ACD0002720682268D0F800016D1CEDB202F59162C07AA842D5DC002F5A
+:201A00009ED12068D0F80001C0880025A84297DDADF80060ADF802501268D120694690474E
+:201A20000028B8D1BDF804008145B4D0ADF810002068D0F8882404A9D4209047002893D03E
+:201A40001924504618F04CFD089813F0A5F820460AB0BDE8F087C04614010020574B2DE9F3
+:201A6000F0475879002840F0A5800020012116F07BFF002800F09E800668002E00F09A8043
+:201A800007464089C1096CD2984698F83210890872D3326A51791479400B04EB01242CBF65
+:201AA000402500253868B7F818900088824613F013F8002846D15046032112F0E7FE00283F
+:201AC0003ED15046002113F02FFD29460DF090FC061C31D07079012806D0032824D00428C3
+:201AE0001FD14FF6FE702FE0B179708811F0180F10D0FF21A042317105D0484503D04FF6EC
+:201B0000FE71814209D1204649464FF6FE7205F041FF02E098F8381031714FF6FE71814207
+:201B200008D17079022807D05046072112F0AEFE10B105E0824603E0504616F025FE03E083
+:201B4000504601E04FF6FF70844202D0398B81420ED1386801880222002320460DF000FA8F
+:201B60000AE038680088034612F0B6FF30B918464FF6FE71814203D1CD2111E04FF6FF702E
+:201B80003968088012F0A8FF00280CBF012000203968C8810849386809F0A8FB011C04D0D7
+:201BA0003868407B12F0CEFA20B91FB138460121FCF7B2FEBDE8F0878D5D0200E4FA00200E
+:201BC0002DE9F04F0446656928780026ADF12C0DB0468DF824000DE03918C978401CC0B20F
+:201BE00002F8011B74E09DF82400761CF6B2401C8DF824006878B0420EDD216809A80090FC
+:201C000008AF01976368E27A087D8988C3F3C0030CF026FA0028E6D1F01C80B218F03CFBC7
+:201C2000071C7BD006B3287845468DF82400216809A8009008AB01936368E27A087D8988DB
+:201C4000C3F3C0030CF00CFA68B19DF822009DF824307919761E05F10105C87003F1010001
+:201C60008DF82400E3D1A846216809A8009008AE01966368E27A087D8988C3F3C0030CF0D0
+:201C8000EFF900280CBF012000203870E07A87F8028078702168666808F1010501F1060BE4
+:201CA000087DB1F804A0A47A0A90F00880F0010000F00109E8B2804618F0EEFA051C08BFFF
+:201CC000102624D002463878002602F8010B3046B978814280DC7878112803D0132813D1D5
+:201CE000142300E012230096CDF804900120029003960494CDF81480069507900A985946F9
+:201D00005246FEF7D5FA0646284618F005FA384618F002FA002E08BF012000D000200BB063
+:201D2000BDE8F08F29282DE9F0410EDC29285FD0203800F09A80401E00F08C80401E7ED015
+:201D4000401E71D0401F61D007E02A3845D0401E38D00E3820D0401E02D00020BDE8F081F4
+:201D600093E8600091E880010CCA284631460BF091FC4FF0000403D828461E46154601E01F
+:201D80001946104633462A46FDF71AFB43463A460BF080FC74D872E093ED000A92ED001A5B
+:201DA000D1ED000A0024B4EEC10AF1EE10FAACBF30EE410A31EE400AB4EEE00AF1EE10FA2F
+:201DC0005EDB5CE018680B68116800248142D4BF411A091A8B4253DC51E018680B68116891
+:201DE00000248142D4BF411A091A8B4248DC46E0B3F90000B1F90030B2F9001000248142AC
+:201E0000D4BF411A091A8B423ADC38E093F9000091F9003092F9001000248142D4BF411A00
+:201E2000091A8B422CDC2AE018680B6811680024814294BF411A091A8B4221D81FE01B6834
+:201E4000106809680024984294BF181AC01A814216D814E01B881088098800249842D4BF3A
+:201E6000181AC01A81420BDC09E01B781078097800249842D4BF181AC01A814200DC0124C6
+:201E80002046BDE8F0817047F0B504462C20ADF16C0D18F001FA071C00F0A28008223A70B1
+:201EA00000257D70207FF870207C04F11401387407F1140017F0F2FB381D211D0C2217F0EF
+:201EC000EDFB4848237D217FC01E466984462846B04206D000E0B6683279914218BF002E3C
+:201EE000F9D1F6B1DCF80C00D8B173B9C17DF27D914212D190F8251096F8252091420CD139
+:201F0000C16AF26A914204D007E0416B726B914203D101793279914203D180680028E4D1EB
+:201F200001E000283AD120461AA916AA01F0C2FC0246BA7098B1401E02D0C01E0FD010E05D
+:201F4000607D9DF8681016AB09F054FF38B107F11C0016A9102217F0A1FBBA7801E0BD70B9
+:201F60002A468DF80020F8783E1D8DF8010096E80D0001A981E80D00387C07F114058DF806
+:201F8000100095E8050005AC07F11C0184E8050007A8102217F082FB68461CE0BD708DF8B7
+:201FA0002C50F8783E1D8DF82D0096E80D000CA981E80D00387C07F114048DF83C0094E871
+:201FC000050010AD07F11C0185E8050012A8102217F064FB0BA817F0B9FC384618F09CF8DD
+:201FE0001BB0F0BD4B1900202DE9F0470546A87A022840F09B804E4CAF7B5248DFF840A1A0
+:20200000666A002F7CD1E168F9B12769EFB16769DFB1A768CFB114300078012815D16888A7
+:202020008847AE1C88B943490A6830889101A1EB820122699047012878D16169308888474A
+:20204000A16830888847BDE8F0873B486D88006878B101680A88954208D1096A4A7809786A
+:2020600001EB0221490A01D220B136E040680028EFD10020314933230027012401F6C4427B
+:202080001679FF2E02D01688B54206D05B1E02F124024FEA4404F3D100E0274601F59A781B
+:2020A00001F12E09002319F803208AB19E0058F8064027420CD0104616F062FF38B1417B8A
+:2020C000052904D1BC431E2348F8064000E000205B1CDBB21E2BE6DB68B1417B05290AD14B
+:2020E000016801270D8056464773307820210FF059FDBDE8F087284611F0B2FBBDE8F087DA
+:20210000A6B1017D012911D1807F40080ED3042016F0E3F9011C09D06420087001274F70D7
+:20212000688856464880307811F0B6FABDE8F087ECFB00206CBC0200380501202001002006
+:20214000E4FA0020ACFE002070B5534C054694F84A00ADF1300D082818BF042840F099807B
+:2021600028460DF10E0116F0C9F94FF6FF7012F033FFBDF80E0004AE314600F0EFFD012843
+:2021800000F087800DF11A0017F0AAFF0DF11A00314616F02DFF58B1BDF80E2017F074FE5A
+:2021A000904205D004F13E014B200A8013F034FA17F07CFEA98A3B4D884216D004A817F07F
+:2021C000BBFF38B10079012818BF022802D104A810F010FC3148016839B105F113000078E1
+:2021E000012802D1BDF80E008847BDF80E00002115F0D6FFBDF80E0015F036FE00248DF8EE
+:202200000040BDF80E00ADF8020068460CF0D8FB98B10DF11A00214608220CF097FB01AC6A
+:202220000DF11A00214616F0E3FE30B104A9204617F0C6FD684603F0CFFB01A804A917F0B2
+:20224000BFFD68460EF062FA50B1BDF80E00BDF80210884204D0ADF80200684603F0BCFB92
+:202260000F482E78046836F0010012D10DF12200FF2108220CF06AFB5CB104AD0DF1220141
+:202280000822284616F000FA18B9BDF80E102846A0470CB070BDC046E4FA0020F4FB0020B1
+:2022A000B0030120ADFE00202DE9F041524D2968F4310A68064692F84400ADF1180D8228EA
+:2022C0001ABF92F84400401C002082F84400086890F8441000EBE10090F82C104A1080F86F
+:2022E0002C2048080AD22968F4310A6892F84400401C82F84400C0B28128E8DB2A68F432C0
+:202300001168DFF8F88091F84400812824DB8878E8B944462168D1B10868C0B10F4615F00F
+:2023200009FF8046386817F0A9FF10B1386818F0B3F8384618F0B8F8384612F02DFC083C49
+:202340000020A060404617F0D8F92A68F4322A203070D2F84C1249E0D2F83C234431E1206D
+:2023600090472C684FF6FF730220ADF80830F43422688DF810009778BFB917F079FD4FF4AE
+:202380007A71B1FBF0F01E49434600220AF0A8FC00282DD02868D0F8F4001A2141702A2768
+:2023A00037702868D0F8401320E0022F1CD0012F19BF0720832108208021002700974932D9
+:2023C0000192D4F8844202AAA047DB2807D0E52805D0F32803D0DF2818BFE82808D1296843
+:2023E000D1F8F4104870DAE7D4F874133046884706B0BDE8F081C04614010020D8040120FB
+:20240000FD7C01002DE9F041064670680F46ADF1300D000944D2F07A002837D0012841D1B4
+:202420000024B968ADF8284021B13068801D089008A8884731680094087D898822460AAB4C
+:2024400013F0C7FABDF82800002800F083803168012500959DF828008DF82A00BDF82870B3
+:20246000019538128DF82B0002950394B27A0492022305930DF12A0706970795087D03220D
+:202480002346891DFDF714FFFF2064E0F06841783768007800EB0120397D10F025FC59E07F
+:2024A000F07A08B1012056E02C4D346868784FF480410FF035FF6869A846A41D40B91820C5
+:2024C0000AF0C8FBC8F8140008B10021416121E070B1637A417A8B4207D161894289914208
+:2024E00003D121880288914220D040690028F1D1D8F814501435286820B100F11405286807
+:202500000028FAD118200AF0A5FB286070B100214161286850B1217A017221880180617AE6
+:2025200041726189418100250573056198F801004FF480410FF036FBF96859B13068F76812
+:20254000801D08907A78387800EB0220ADF8240008A8884700200CB0BDE8F0814CFF0020F2
+:202560002DE9F0430E460024ADF1240DADF8160006F108078DF81440384616F055FA50B955
+:2025800005A80CF01DFAA124012840F08A8005A814F004FA85E038460DF122016A460CF0F4
+:2025A00057F905464FF6FF70A84276D09DF82200DFF8FC8000282BD03C4801789DF81000CD
+:2025C000F8B1401E11D0401E04D0FB3814D0801E12D048E001290CD002290AD006F11E0002
+:2025E00002A9082216F056FE3DE0012918BF022902D14FF4817001E040F20310B08274820E
+:2026000031E005219DF81300718200F07F0029E002A83946082216F03DFE4FF001098DF80E
+:202620001190FF208DF8100017F02BFD274600F00F0000942946142201976B468DF8120091
+:20264000042013F0FFFFAF0007EBC507404621460C223F1838460CF079F9748287F809907C
+:2026600040F20310B082A8003474414600EBC5000A58B2610F580A237F1CB7FBF3F20F50C2
+:202680005A43BF1A0DD1401801210A4F017238784FF480610FF086FA03E0748240F203102F
+:2026A000B082204609B0BDE8F083C046ADFE002064FE00203BFD00202DE9F0478246484E5B
+:2026C0004E4C56F80C0C9046894680082AD245480068810D28D2051704F13400006800683F
+:2026E00080476D1CC0F13E0110F1020F4FEAE101D8BF07218D42B8BF0D1C3B480068C0F3A1
+:202700000320401B102803DA0028D8BF012000E00F20364900F00F0040F0F00081F84D00D3
+:20272000087801E03248306000203249324F256808603868A96927208847324D304805F168
+:20274000300211682B460840106003F17800006820F48070A8672068016B4FF480608847D8
+:202760002068016B4FF4816088472068016B4FF4C0608847244901200860C5F88091286000
+:2027800056F80C0C800806D2B8F1FF3F14BF40464FF0404030603868E8698008FCD3072075
+:2027A00010F07CF90228FAD1BAF1010F13D0206A164E8168304688470428F8D0012804D103
+:2027C000206A4268032130469047D5F8180220F00300C5F818022068806B8047BDE8F0872D
+:2027E0001C000940B44F00500C1300500D620840FD0000400C4009402C200940B8010010CB
+:20280000FFFFFEFE0C20084028200860004003402DE9F04F15460646287A0C4600F03F01F7
+:20282000E8886FF39F2040EA0130A988ADF1140D6FF39F2141EA003B49490E9FC8789A46D5
+:202840004FF0000988462EE09DF80B10C8080CD3BDF80E00844204DD241AA4B2162C13D9C9
+:2028600031E02146304610F0F1FE0020F6F7ACFC98F8330098F803204FF00009401C90FB21
+:20288000F2F15143401AC6B298F803008119491E91FBF0F24243891ACEB2B10001EBC601E1
+:2028A0004144B1F84C40484503DC0020A8810A2052E098F8323009F10101B3421FFA81F9D7
+:2028C000E4D0172CE2D3E41F30466A46A4B2214608F038FF9DF80B108808B7D34808B5D296
+:2028E0002A7AEB881AF00F0018D0401E12D0401E07D0401E18BF04202ED100985845A5D148
+:202900000CE09DF808009042A0D1BDF8060098429CD103E09DF80800904297D1AFB10AF0D5
+:20292000F000102811D1BA89BB68684600210FF0DDF8002888D1F988B868BA884018396827
+:2029400015F0F4FC00287FF47FAF68460EC80EC503C885E80300002005B0BDE8F08FC04628
+:202960005CFC00202DE9F84F504CD4F8A000D4F8A060002800F095800546E86840F60301AC
+:2029800008274A1C02E040687F1EFFB260B15FB10388994218BF9A42F5D129692CC83831DB
+:2029A0002CC189C881E8890006F1280090E800034FF0000A06F12807D34687E8000CB16831
+:2029C00021B357464FF0E24A07EA08001AEA090508BF002813D036A090E80C0002EA0802EE
+:2029E00013EA090308BF002A04D0B5683069B6F93010A847504607EA080800EA0909B568C5
+:202A00003069B6F930104B464246A84717F0DEFB0546B4F9B600401C6FF31F30A4F8B60039
+:202A2000214886F833B06FF00207378615F044FD284617F055FDB4F9B400B4F9B6108842FC
+:202A40002FD16068D4F8B860D4F8BC7090F8FC1000290CBF052007200AF068FF58462EB120
+:202A600096F8FC5005B9306886F8FCB05E462FB197F8FC5005B93E6887F8FCB0864238BF4F
+:202A8000061C66B1B6F1FF3F0BD017F0F1F9B6FBF0F104F5CE7016F03BFEBDE8F88F16F012
+:202AA0002DF9BDE8F88FC046D0F5002030F50020F0FFFFFFFFFFFF8EFEB5524C6069258954
+:202AC000A689E169806D2A468919083109F00EF86269916D49199165E2697619B0B21218BF
+:202AE0000832127801A90A70444EE169401C80B20918097A721C401C117081B2E269A181D5
+:202B000052180832126868460260091DA181042115F099FF63690090054616F035FFD86361
+:202B2000284616F0F5F9A3F84000EA2013F0BAFC02213548324D017068684069007830B133
+:202B4000307810B97078FF2801D00420E0706769E078397C084338749DF9040017F07AFBC6
+:202B600087F8460007F17406BE6539899DF904007B6887F84800B7F85C000026401AC01892
+:202B80007860B88987F84760800A0AD32868D0F80813384688476769786E10B1B7F8680041
+:202BA00010B397F8600050B12868D0F80C13384688476769F86C10B1B7F85000A0B12968C8
+:202BC000B8310A68107838B1936C2BB119463846884767692968B831D1F8A0113846884791
+:202BE000666116F0F7F9FEBD2868D0F8541204F11400884766610DF0F9FFFEBD240001200B
+:202C00001401002068110120051401202DE9F04F0546E97A6869ADF11C0D0229814609D144
+:202C20000078032410FB04F0401C80B217F034FB061C01D100208DE00027A346A246B846BB
+:202C400047E017FB0BF0862332E09DF80E00A178884230D10498F8B129688888032814D108
+:202C6000238893B9D4F8031005A8022216F012FB2868007D10F040FE11F068F92968BDF8A7
+:202C80001400097D10F030F81FE0087D02AA2346891D13F03AFE07E02968D4F80330087DFC
+:202CA00002AA891D13F0FEF8031C0ED017FB0AF031184B7004E017FB0AF08D2231184A701A
+:202CC00021887F1C3018FFB2418008F101005FFA80F899F80000404522DD2968072018FB4B
+:202CE0000094641C087D2288898802AB10F034FF0028A6D09DF80F30002033F07F0318BF92
+:202D000001206968C1F3C00181429ED017FB0AF1862072187318507021887F1CFFB25980C5
+:202D200037701FB9002070700127377068682A68C00880F0010000F001000090A87A911D59
+:202D40000190107D928833460AF0B4F9304617F0E3F9012007B0BDE8F08F70472DE9F047C2
+:202D60008A46071CADF1200D08BF002000F0918049480088B8420AD116F05CFA0146504686
+:202D800016F036F900280CBF0125002500E012254FF00009ADF8027068468DF800900BF08C
+:202DA0000FFE20B101A815F03FFE012843D0122D4AD1504617F0C0F928B101888F4202D059
+:202DC0000679052E03DBB9F1000F3CD13CE00780E6B132490D78032E18DA31493DB901EBE4
+:202DE0008502126B01EB8501C261096B0AE001EB85010B6B9A01A2EB8302C2610A6B91011D
+:202E0000A1EB8201816180F8209003E06FF00101C16181614E46C6600125ADF810705146B5
+:202E20008DF80E500DF1120016F0CAFF0DF10E0002F0D2FD07E001A9504616F0D9F80028DD
+:202E400008BF012500D04D463846514610F04EFA0A2818D0A02813D1124C322604F102084A
+:202E60004046514616F0C4F830B9761E04F11C0408F11C08F4D100E02780384612F0ACF854
+:202E8000012D01D004E001253846494616F01EF9284608B0BDE8F0871EFB0020CBFE00209B
+:202EA00018BC02006C0800202DE9F84F8146D9F80040D9F8047094F82360B4F814A0D4F8F3
+:202EC00010B090460D465EB1A168434816F01FFE002818BF6FF001007BD1012084F82600D5
+:202EE00084F82180002625604A463C483C49E66115F06AFB3978272017F070F95146584623
+:202F0000062204F06BFC002857D13749091F086820F00200086094F82000042806D1334822
+:202F20004C38006840690146272088472D4F4FF0020B4FF0805AC7F8FCB2DAF8FC014068DA
+:202F40000146062088470AF5FE7A38BB584613F0CDFDB8F1020F4FF0010005D0B8F1040FD5
+:202F600018BFB8F1060F01D1314600E00421C7F84C11E968C7F85011C7F8546184F82400CD
+:202F8000DAF80000AA68E968036968681C460B46A04748460DF086FBBDE8F88F40203860F6
+:202FA00080253D6094F8260020B10B4817F024F984F82660C7F8FC6207E094F8260020B14C
+:202FC000054817F019F984F826604FF0FF30E061E069BDE8F88FC046B80E01204012012005
+:202FE000510002000444024088470240FC0100102DE9F04F80464E489346ADF1240D07690D
+:203000000691002F00F090807D6801248246494F07940320B8F1000F8DF8140003D0069800
+:2030200003A914F098FF4FF000094E4601E0761CF6B2A968087BB04217DD03A80090CDF8D8
+:203040000480079802900969FA7C7B69287831F816100AF039FE0446B22C06D0002CE6D1EE
+:20306000DDF81C90B8F1000FE1D1B22C26D0B9F1000F02D0B8F1000F20D0A968002602E045
+:20308000A968761CF6B2C879B04217DD03A80090CDF804800024029489683A7EFB692878D3
+:2030A00031F816100AF010FE0446B22C06D0002CE6D1DDF81C90B8F1000FE1D1B9F1010F33
+:2030C00004D1B8F1000F08BF802100D0FF21DBF80000B22C017314D03878FF2824D1DAF864
+:2030E00010000668CAF81060F6B175682B7823B1F12B02DA002E8CD116E03668CAF81060DC
+:20310000F2E700208AF800009AF8010040210FF007F915F07BF89AF801004FF480410FF033
+:20312000FFF80C2016F0CEFD09B0BDE8F08FC0464CFF0020DC0201202DE9F0470646880F1E
+:20314000C0F08E8000200EF095FA464816F072FD454C40F60A09A4F8009000256580207B56
+:2031600005F00F0120F00F00014321736560607B4FF0010808F00F0720F00F0047EA00010C
+:203180003046617306F086FBD6F808A04A462146D01F574600F1010C00E027467C6834B161
+:2031A00023889A4203D0984218BF9C45F5D179607A7B2E4C05F00F0322F00F0213437B73A7
+:2031C000D4F8983033B1DA681288904223D06046904220D0338FF3B1F56306F138025580AA
+:2031E00096F8440005F00F0320F00F00034386F8443096F8450008F00F0320F00F0003435D
+:2032000086F845304A60487B05F00F0620F00F0046EA00054D7316F02BFB1548A06294F819
+:20322000310080B91348006801684046884701280FD0787B08F00F0120F00F000143797351
+:203240000D4EA66205E011F0C7FC0028FBD010F0A5FD504616F0EEFC5146404614F08EFF99
+:20326000BDE8F08701010E04F412012030F50020F95E0000E0010010992B02002DE9F0435B
+:203280004E49DFF830910A68ADF1140D1AB94C464A34267800E00226444BD9689F68761FD9
+:2032A0007ED0761E7AD0002A67D09179012964D03F4CE76A022903D0A169002973D071E078
+:2032C00038460027002854D1780009F0C3FC5FEA00084BD0E06A40B10021028828F8112029
+:2032E00040684E1CF1B20028F7D14C46B4F89200618F814233D081460A2000EB47008DF8FB
+:203300000D0003A815F080F9061C2CD035690920287004F15D016F70A81C16F03DFF5FB1B2
+:2033200008354046017805F8021F30F8021B7F1E4FEA21216970F5D10124B47715F07AFF69
+:20334000706201A9484614F006FE10B1747701A83062A6F802903046F8F78EFC03E0CDF8AD
+:203360000080FAF72EF9404611F016FC12F0C6FE19E040687F1CFFB2A4E740780E498DF84A
+:203380001000086838B900208DF8050001A9012013F03CFC07E0096804A803E019B101E07A
+:2033A0000FB13946884705B0BDE8F08334040120ECFB0020E4FA00207CFD002038040120DE
+:2033C000F0B5064631684889ADF1440D4008C0F092804A894FF6FE70104048810868036A1D
+:2033E000C57F5978187800EB0120694611F010FFD878997801EB0021ADF80A105A791879CC
+:2034000000EB0220ADF80C0098799DF807708DF81200D879002F8DF8130008BF082403D05C
+:2034200003F10800102405909DF808701FB1181908340690E4B28DF801409DF8057037B199
+:20344000185D641C8DF80500E4B28DF801409DF806C02A480027BCF1000F06D190F82F2033
+:2034600052B1428F8A4206D106E090F82F201AB99DF8022002B90127A7B9BCF1000F05D1B9
+:203480001B190A932D1B8DF81C500CE090F830001B190E330A9315F045FF2D1B281A0E3853
+:2034A0008DF81C000A9B37BB1878042823D10DA800210E220BF04AFABDF80A000A9FADF8D2
+:2034C00034007978880924BF01208DF83F0031F07F001CBF01208DF83E00C80934BF0699AC
+:2034E00005990DF1360016F057FE30798DF840000DA812F037F811B0F0BDC046E4FA0020D9
+:203500002DE9F84F80460D462868DFF824A1D8F80040D8F804700689D0F804B0E16891468A
+:20352000504616F0F4FA0028CDF8009018BF6FF0010074D148464FF0000960723A49656117
+:2035400042464B46C4F804903648A37015F03CF83978272016F042FE31465846062204F0C9
+:203560003DF9A8B9334E4C3E306840690146272088472E4F4FF0020BC7F8FCB2F06C4068D1
+:2035800001460620884750B14020386080263E60504616F031FE4FF0FF30BDE8F88F5846AF
+:2035A00013F0A4FAF06C95F82010C26928699047F26CDDF800C095F8200095F821101368E5
+:2035C000BCF1010F4A4608BF01229847E869C7F85001C7F85491A869C7F85801A96959B18B
+:2035E000F06C076968684A461346B847F06C806901461148401E8847207A042804D0306803
+:203600000069014627208847F06C0369E969EA68A8681C460B46A04740460DF0B7FBBDE8F4
+:20362000F88FC046401201205515020004440240B80E0120FC01001003000080F8B5054625
+:20364000687F0F4600280CBF08201020AE7F0EB10830C0B22E7F0EB1401CC0B2AE7926B115
+:20366000297A00EB4100801CC0B22E7E6870002E0CBF00260E260024297D2B7E85F8344032
+:2036800009188919397033B13A48007815F04AFE3978081838703878742867DC09F0DAFABE
+:2036A000071C64D016F0FCFB95F83420A97F2B7F41EA42016A7F42EA4102A97941EA4201AD
+:2036C0002A7E42EA410203B1012429786B7E44EA420441EA800103F0030041EA801141EA73
+:2036E000042188B2397000127870A878B87068880012F87028793871A88800127871A87E7B
+:20370000B871E87EF871687F002808BF082405D0296A07F1080016F03FFD1024A87F28B1D1
+:20372000696A381916F038FD0834E4B2A87988B1287A3855697A631CD8B239542A7AE96861
+:20374000431CDCB2E019520015F0A4FD287A04EB4004E4B2287F00B13855687829692A7D22
+:203760008019C0B2C01915F095FD00E027463846F8BDC04614FB0020F8B50546A869837815
+:20378000002427461BB3FE2B21DC41780078474E00EB01203188814206D015F01BFD00283B
+:2037A0000CBF8126892613E0184615F041FB264650B18268002A04BF4068846804D0012089
+:2037C000194690470127044604B9832600E08226374801685EB954B1227BE079022380189C
+:2037E00010FB03F00C30C3B2502B01DD58E0042301F8016BA869007801F8010BA8694078A6
+:20380000042B01F8010B42DD181F01F8010B207801F8010BA07801F8010B6088001201F86C
+:20382000010B207901F8010BA088001201F8010BA07900F00F0001F8010BE07901F8010B24
+:20384000E67916B10020864214DC207B0870267BFEB1491C002086421BDD26694200965DFE
+:203860000E702669925B12124A70267B401CC0B2891CF0E7A6684200965D0E70A668925BC9
+:2038800012124A70E679401CC0B2891CDBE70020087005F11100A91C48F204020DF03EF9DE
+:2038A0001FB114B1204611F077F9F8BD50FD00209CFD00202DE9F04100250E1CADF1580D28
+:2038C000904603950746ADF8105004D0B8F1000F18BF002F01D1042083E0104635702946D3
+:2038E000102216F0DBFC38798DF80000002804BFB868019005D001A807F10801082215F039
+:20390000CDFE68460DF1120104AA0CF01FFA36490C7802284ED001284DD09DF8000002280A
+:2039200008D1387C9DF81C10814203D0002818BFFF2840D19DF81F00397D00F00300884245
+:2039400004D19DF81F0010F0030F49D008A903A8042215F0A3FEB8690399884228D99DF86E
+:203960001F00397D00F00300884221D19DF81F00801000F00401042902DA797D012917D07A
+:2039800000F00701072918BF042901D1787D78B105290DD006290BD009A94046102215F087
+:2039A0007DFE9DF81F00C0F382003070012018E00CB115E00CB9284613E0387D0228A8BFCC
+:2039C00003200EDA787D58B9084C40461022214615F0C0F820B921464046102215F05EFE4D
+:2039E000022016B0BDE8F08120040120CCB302002DE9F04F05468846ADF1140D1C46D5F8A7
+:203A000008B00E990092DBF80400019108EB0401884238BF6FF003047BD3404E30684FF07A
+:203A2000FF3116F074F83E48019F01684FF0000978081CD23846CDF80C90800827D334B357
+:203A40003046DBF800200099066823464244491E521E11F8010F12F8015F054085421CBFC6
+:203A60006FF00604301C52D15B1EF2D10FE034EA010701EA040202D02A480068121801EA6B
+:203A8000080128460EF046F9002803903CD1DBF8005010F0A3FA27464544DDF800A00290ED
+:203AA00002E0BF1BB244AD1997B1082F8CBF08263E1C16F08BFB049029463246504615F09A
+:203AC00083F88146049816F00BFDB9F1000FE8D0029814F0F1F9B9F1000F12D10198C00804
+:203AE00012D38CB1DBF8000000994044491E401E10F8012F11F8013F9A4202D1641EF7D175
+:203B000002E04FF0FF3003900448039C006816F073FB204605B0BDE8F08FC04694130120EE
+:203B20009C130120981301202DE9FE4F0CAF1D468B465FEA02083E78009014BF4FF0804A22
+:203B40004FF0005A16F042FB0324DFF804910190BBF1FF3F14D1D9F8A810009816F072F805
+:203B600058B9D9F8AC10009816F06CF800280CBFD9F89870D9F8AC7008E0D9F8A87005E036
+:203B800000985946002211F093FC0746002F59D097F8330030F07F0053D04C46D4F8A8000D
+:203BA000B84219D0D4F8AC00B84215D000982A463346394608F05AFE002842D094F8240091
+:203BC00001283CD094F82400042838D0214904F1E00016F019FB32E0D4F8A8005346002232
+:203BE00011F084FCD4F8AC005346002211F07EFCB8F1000F14BF1848184814F089FAB6B15D
+:203C0000D4F8A80000224FF0807311F06FFCD4F8AC0000224FF0807311F068FC3869C4F8E2
+:203C2000D80094F8DC0040F0010084F8DC0035B1D4F8981000982A46334608F017FE83242C
+:203C400000E00424019816F04BFC2046BDE8FE8F30F500200200004001000204010001044A
+:203C60002DE9F04FADF1140D02921D460191DDF83CB00E9C009016F0A9FA464A6FF001080B
+:203C80004FF00109002392F840A2039009FA03F616EA0A0F6FD0B5F1FF3F18BFAB426AD182
+:203CA000D8B215F003FE002865D0877A002F62D192F84012B14382F840124F468772009DED
+:203CC000437292F842120560491C82F84212019E06722E4F4760017A074601291ED0022973
+:203CE00024D140F20361018290F90930C17C5B1D21F00F0103F00F030B43C3746379817CBB
+:203D000063F3C7018174C17CA37963F34611C174C17CE37963F30411C17407E00A20388251
+:203D200097F90900401DB874A0687861BBF1000F08BF002012D09BF801009BF8001097F935
+:203D40000960134C4FF6FC75800040EA4110711D40EA012005EA000144EA0100B86102983F
+:203D600000B17860506808B9386850600CF07EFA97F9098002E05B1C032B87D3039816F0E2
+:203D8000AFFB404605B0BDE8F08FC04677F500000100040630F500202DE9F84306464FF676
+:203DA000FC751C4617468846B54200F08480002111F0BAFBDFF804910646B9F83A00B042AE
+:203DC00001D1E00977D3214630460BF011FBC0B9A81C00210BF00CFB98B914F0180F0DD041
+:203DE000374B0020997911F0180F03D1962805DA184606E0401C08339628F3DB0220BDE848
+:203E0000F883AD1C0680454518BFA0F802808471610824BF44F004048471012F0CD0417925
+:203E2000012913D0817911F0180F0CBF99F83710FF210171477109E001214171817911F0AE
+:203E4000180F0CBF99F83810FF210171012F32D1B9F84810404612F0DBFB60BB194C1A4F82
+:203E600000204101A1EB8001C919B1F84C6707F52772002396215588AE4205D0491E02F12A
+:203E8000080203F10103F6D1962B04D0401C1C343228E6DB0FE0204600211C220AF056FDFC
+:203EA000A4F80080B9F848006081AA27A77401266674062525740020BDE8F883E4FA00201D
+:203EC000BC0300206C080020200100202DE9F0479646464A88461E2300240146012520466F
+:203EE00097782FB15B1E02F1080204F10104F7D11E2C79D03E4C3F4F814633264FF6FF7C10
+:203F000082F8069037F824AFD04510D0638F53450DD03B7933F0040A06D0012B07D14B89A0
+:203F20009C4508BF284302E093795B1C9371761E4FEA4505E6D1304D3226ACF1010C35F88B
+:203F40001C3F98450DD09C450BD0B4F848306F89BB4206D16F7C27B1AF7C17B193795B1C67
+:203F60009371761EEBD19779082F01DC17B909E0082393718B7C012B04D094F826305B1C81
+:203F8000137101E082F8049094F82B30937094F82570D7708E891680CD7C82F805E0D571C1
+:203FA000B8B116491E2201F12D030D46494613F8017F37B1BE4504D0521E01F10101F6D180
+:203FC00007E01E2905DA83F800E005EB8105C5F834012078402110F0BFFD20B9207840218A
+:203FE000642216F0B5F80120BDE8F087CC020020E4FA0020C00D00205008002020010020B9
+:204000002DE9F84F8346DBF81800057800216A46A3200FF0A9FABDF800004FF00009854218
+:2040200024DABDF80000401B84B2042C01DA0CB91DE00324E00000EB041008F00BFE5FEA1F
+:2040400000090FD007464FF000088CB146467119A2203A460FF088FA761C1837F6B2B4424F
+:20406000F5DC05E04FF0B508002401E04C46C8469BF81100E1B215278DF8020011FB07F0EC
+:20408000001DC0B2401C08F0E5FD4E460BF1020B071C45D0781C82468AF800809DF8001083
+:2040A000E3B2B970FD7004253C7143B3001DE4B2314616F071F8317A00F8011BB17A00F88E
+:2040C000011B7189091200F8011B317D00F8011B317D032906D0317B00F8011BB1890E35EC
+:2040E000091205E006F10C0116F056F8B17D1535641EEDB200F8011B06F11806D8D10C4EA3
+:204100002B460DF10200594648F23302341DC4F800A00CF003FD384610F03EFD09347460AD
+:20412000B9F1000F02D0484610F036FDBDE8F88F98FD00202DE9F84F8046D8F80430B8F87B
+:204140000240002739463A461D191EE013F8036B7F1CD21CFFB292B2A6B913F8056B30467C
+:2041600015F02BF8521D92B278B1304608F0E8FF8618B442B8BF002073DB09181B181218EF
+:2041800089B201E09B1C921C92B29D42DED80E2017FB00F0401CC5B2681880B216F07CF896
+:2041A0005FEA000A5CD0D8F80440002F0AEB05068AF8007054D04FF000084FF0010B0AEBA0
+:2041C000080500210E226D1C284616F067F814F8010B28702B7861782078A41C00EB012095
+:2041E000A5F8010093BB14F8010BE87061782078A31C00EB0120A8801878597800EB012092
+:20420000E880E878014614F0D8FF9C1C20B30846314612F065FAADF800B09DF80030A14602
+:20422000002B07BF411E4FF0FF335B46002128B119F8012B401E72541944F9D1E878C5F87D
+:204240000A6008F07DFF2418361805E061782078A41C00EB012028817F1E08F10E08AED100
+:204260005046BDE8F88F70472DE9F84FD0F8E8200023083A002AC8BF0123D0F8C0C0D0F84E
+:20428000D020E346DBF8004094420CD8DBF81470002FBC4678D001228CF81020D0F8C0B059
+:2042A0004FF0000E00E09646DCF80020A2EB0E02B2F5806F88BF4FF48062D0F8D8702FB96A
+:2042C000C0F8D820D1F81C808E6904E0C0F8DC20D1F824800E6ADCF804402CB92B4C9F0042
+:2042E000E55900F1F6040AE0294D9F00ED5903F1010A02FA03F90EFB0A444C44641EB560DB
+:2043000034600C6804F10809C6F80490B56843F6F07A1401103C0AEA04042543B560DCF8CF
+:20432000086026B9194BDD5900F1F40308E0194DED595F1C02FA03F30EFB07669B195B1E10
+:20434000C8F80850C8F80430C8F80090D8F80830E34544EA0304C8F8084004D1D0F8D030F7
+:204360009B18C0F8D03090F8FE706FB90B685A6A42F003025A62D0F8CC004F6943680A6920
+:20438000196847EA02008862BDE8F88FE8C30200F8C30200F0C30200F8B5374D0024287047
+:2043A000364E85F84A40382030804FF4287008F051FC706028B1706821464FF428720AF08B
+:2043C000C5FA2F482F49304F304E81613049C7610A7D0662012A15D12E4A2F4F4262897F0D
+:2043E000C760490802D2006B58B90BE02B4F07632B4981622B4E06612B4B83602B4A42617E
+:2044000038468047AC602A48046012F007FD15F0D1FB294996274FF6FE7201F1E80020F8C8
+:20442000082F4280047144717F1E8471F7D121480C2700F150035A805C705C607F1E03F825
+:20444000084BF8D10827428004727F1E00F10A00F9D128781E277F1E21F8082BFBD1174A7C
+:204460000121117010214FF47A7215F071FE02F02BF913480460F8BDE4FA002030050120E7
+:20448000ECFB00208D6A02008D8C020045080200ACFE0020CDD101005D8002006986020079
+:2044A00021F20100B1EA01006D300200758C010038050120A4010020CC020020D513012091
+:2044C000380401202DE9F04306467568B7680C46ADF1140D15F07AFE95F8FD1021B9616922
+:2044E000102901D8042903D215F0FAFF00206FE04FF0010985F8FD9015F0F2FF2069C5F8AC
+:20450000E4006069C5F8E800207B85F8F900207885F8F8000020616885F8FC008046C5F846
+:20452000C080C5F8C480C5F8C8802B4AC5F8EC10217E12F8211085F8FA10F989A5F8F61081
+:20454000237B002B0CBF1021494685F8FE00C5F8F010387B05F0B8FA30460DF009FC97F86E
+:204560003B0085F8FB00304609F0F0FB684615F049FB787900966B463979184A01902846EC
+:2045800010F008FE684615F075FBB96802911449009605F130006A460EF07CFB0FF014F9F4
+:2045A000014633460F4AC5F8CC1005F11C00042113F01AFB95F8F80030B905F16C004146A3
+:2045C00012F0B8FE084800E0A068C5F8BC00304605B0BDE8F083C046A0C10200B9DD000030
+:2045E0001549020015A0020001A102002DE9F0410221ADF1280D8DF81210C188ADF80A1014
+:20460000417D8DF814108188ADF81610417E8DF81810818C491E8DF81A10816A4A1C0892E5
+:2046200009788DF81910418A808DADF82400374800250768ADF81C10002F31D04FF0D3087C
+:204640004FF6FF74BDF81600F988884206D08C4223D1C10BCE0301D113281ED19DF81A00AC
+:20466000203080B213F039FF061C16D002A9202214F010FE9DF81A1041B106F120000A465E
+:20468000B061089906F1200014F004FE86F80080387931460FF000F801253F68002FD1D190
+:2046A0001B4908310A884FF6FF732F4693420CD0BDF816500C460020954220D0401CC0B2CC
+:2046C000C2001119A25A9342F6D1DFB9BDF81610C80BC00316D19DF8140098B9132911D04F
+:2046E00041F4004100919DF8180001909DF81900842200230DF10A0112F08AFE02E04968D8
+:2047000002A888470AB0BDE8F081C046A0FD002044B702002DE9F04FADF1140D02A914F0CD
+:2047200083F85FEA000940F08380434F029CFE68218856B1B61F0322002036F8063F9942CB
+:2047400005D0521E00F10100F7D1C82601E080460026182008F07EFA051C0ED0002118229D
+:204760000AF0F4F8608818212A4615F04DFC4FF6FF706080284610F00FFA4FF6FE7A4FF06D
+:20478000000BA4F800A0002E84F804B050D1F868444668B3142008F05DFA5FEA000827D083
+:2047A0004C205946022203AB15F016F902255E46F868B44207D0A9B24C2006226B4615F06B
+:2047C0000BF9694603E0610001EB84010918A8B20622404414F05EFD761CAD1D032EE7DB9C
+:2047E0004C201421424615F00FFC404610F0D4F94C205946022203AB15F0EEF8C0B9FF6885
+:204800005FB1610001EB8401BDF80C007A5A5646964204D138B1401E03E0BDF80C00401C91
+:2048200080B2ADF80C004C20022103AA15F0ECFB484605B0BDE8F08F54FE0020F0B5ADF151
+:204840003C0D12F009FD454E96F84A00082807D0332086F8290086F8270001277765B765D6
+:204860006846002124220AF071F83D4D2878012804D0012000278DF80A0002E000278DF834
+:204880000A700F2446208DF837400DF13701B47010F0C2FE6D1E8DF82470A87B8DF825007E
+:2048A00015F0FEFA8DF826008DF827708DF8287096F85C008DF82A700F28A8BF201C06F13D
+:2048C0005D018DF829000DF12B0015F065FC0DF13300FF2103220AF039F896F896008DF8F3
+:2048E000360009A80CF078FC06F11401452010F093FE08F055FF8DF80C708DF8207096F86F
+:2049000050008DF8157096F851508DF80800B6F848308DF8095096F85320ADF8043096F815
+:204920003C408DF80B2006F13A018DF80640532010F072FE06F13E014B2010F06DFE96F8D1
+:204940002B203078642111FB02F2082115F003FC684604F0FDFF0FB0F0BDC046E4FA0020A4
+:20496000ADFE0020FEB505462B7A33F001000BD02888044610F0B0F830B9032B06D12846CC
+:2049800001A911F0F3FF18B90220FEBDADF80440688A443008F05EF9071C08BF10206ED0D6
+:2049A0000021442209F0D2FFA87A0DF1060113F0B6FD9DF8060087F83A009DF807000121B7
+:2049C00087F83900384613F033F8242207F11000294614F05FFC07F144003864688AB8874E
+:2049E00069696A8A386C14F055FCBDF804002449B8800878F8710878401C087015F074FDE7
+:204A0000044615F035FA97F839604FF47A71FF236043B0FBF1F0388003FA06F087F8370010
+:204A2000002487F83600288B8DF80040400834BF201C01208DF80100287A8DF80200684630
+:204A40000FF018FA801EC1B2BE8FBD8F87F8341097F8342095FBF1F0C0B2387296FBF2F1F4
+:204A60005143761A1CBF401C3872064E388D40F008003885307801210DF094F82046FEBDAF
+:204A8000AC000120DC040120F0B50E460746002406F10805ADF1240D28468DF81C4013F0B9
+:204AA000C3FF18B9384629460BF074FB284607A96A4609F0CDFE3B4D6B78A127012B18BF44
+:204AC000022B11D19DF81C20B2B905A82146082209F03CFF05A807A96A4609F0B9FE4FF617
+:204AE000FF71814204D16B789DF81C5025B907E001216B788DF81C104FF6FF71814207D1FF
+:204B0000002B4CD115F08AFB002848D1274631E0254A9DF8101015782746002932D0491E54
+:204B200024D0491E0AD0FB3908D0891E37D1012B12BF022B012086F826001BE0810001EB2E
+:204B4000C001B069891810314A6882420CD8401C012B486013D0022B11D006F11E0002A95E
+:204B6000082214F097FB1AE0A22718E0012B06D0022B04D040F203107482B0820FE04FF418
+:204B80008170F9E705209DF81330708203F07F00B08205B1012486F8264086F8274038468F
+:204BA00009B0F0BDACFE002054FE0020F8B5474C054620684030816F0F780023B7B395F83F
+:204BC000987097B92521297501680968C98AC90939BFD0F8940090F82500D0F8940090F8B5
+:204BE0004E0085F86A00801C0EE01521297501680968C98AC90939BFD0F8940090F8250022
+:204C0000D0F8940090F84E0085F86A00042085F8693005F1900185F86B000A6805F17007F3
+:204C20003A604E687E600889388101E001202875B5F89E0095F8A07095F82C20E88295F8A5
+:204C4000A160EF760F2A2E770CD02068B5F8A870D0F8046305F12C011A4607B901222846E4
+:204C6000B047034673B995F83C00FF2801D1A86D38B12068D0F8FC2205F13C012846904722
+:204C800003460BB11F461FE020680027D0F87463009795F89C10B5F89A3005F19002284620
+:204CA000B047071C10D1216801F5807108682A89C0899042A8BFD1F8781103DAE5206870D8
+:204CC000D1F86C1128468847F8B2F8BD140100202DE9FF47444D0C4606469046600831D2F1
+:204CE000304610F021FC698F814205D03046022122460BF0A1FC08B9002072E030464FF60A
+:204D0000FE7102222346FFF747F8002868D124F02004E0091ED2304602A913F01CF970B98E
+:204D2000B5F84810304612F0D3FC071C12D0B81C13F07AFE70B1B91C02A815F02DFA44F0D3
+:204D4000200407E04FF6FC76A00834BF44F0080444F0100425486B8F90F80090012509F1CF
+:204D600001010022C9B20170491E00951846C9B20AF0B2FBA0BB4FEA641AA00934BF0620D3
+:204D80000E208DF8050001A813F03EFC071C25D0BD7714F04FFA78623869057004F078047C
+:204DA000447080F802903112C670002301715FEA5A01437103D3801D02A915F0EDF94FF681
+:204DC000FC70B8F1000F788004D0B8F10F0FB8BF87F81A803846F6F74FFF02E0102000E0E1
+:204DE000C7200090BDE8FF87E4FA0020D41301202DE9F041454C05462078002800F0828036
+:204E0000B4F9B600B4F9B41088421DD004F1980128460E4612F0AFF970B9D4F8A8102846F2
+:204E200014F010FF28B906F10801284612F0A3F901E0D4F8A80038B1B0F930100A224FF0E0
+:204E4000E043284602F082FE15F0C0F9804604F1B8000168A94219BF00264660002606609A
+:204E60002078401EC0B2207000283BD194F82400656002280ED1082011F0DCF9404615F0FF
+:204E80002FFB05F150004FF0FF3114F040FE15F09DF9804604F1E00015F0B0F904F16000B8
+:204EA00015F092F904F58E7015F0A8F904F17C0015F08AF904F5AC7015F076F904F5CE700C
+:204EC00015F072F9E16911B104F14800884704F1340013F0F9FB0C480078012802D10E2034
+:204EE00004F0FCFA606805F15007854208BF6660404615F0F5FA384615F07CF905F1B8003F
+:204F000015F052F9BDE8F08152C3020030F500202DE9F843434D444C3E4EDFF8FC80DFF8A8
+:204F200000910746012F44D139480068006801460120884701283CD096F83801002838D199
+:204F400008342068C0F38140C8B940460068B0B154F8080C000834BF4FF480504FF4405008
+:204F60002E4908600A2015F008F94846006901460120884706F1940015F01EF901E013F069
+:204F8000B5F80121206886F83811C0F3814010B94046006848B914F0C5FF800905D28020FF
+:204FA000A860286840F080002860032011F09EFD2BE057BB0BF0DEFBA068C0F38140A8B994
+:204FC0004046006890B106F1940015F0F7F82068000834BF4FF482514FF44151134A4846CA
+:204FE0001160006910B101460020884796F8380158B12868802720F0800028600320AF608F
+:2050000011F05CFD002086F838010020BDE8F883E0010010101500200CC20200A8A00C4085
+:20502000FCC1020090220840AC4F005028A10C40F0B50C466168ADF13C0D002900F0828095
+:205040000878002843D10C3101A8102214F022F96068C1690591016A0691001D0AA913F000
+:20506000E3FB607000282BD06068011D40880DAA0D4612F0E3F908BBBDF834000BA912F067
+:20508000F3F90B9850B90BA811F0D8FD20B9BDF834000B99088001E0112054E0284601A9A3
+:2050A00007F00CFB28460CA913F0BEFB10B90C98012101710BF07CF9002044E0012042E01B
+:2050C0000A984088182101AA14F09EFF3BE001A80021102209F03AFC00273E4605A80090B3
+:2050E000B1B200221423042010F0A4FB607090B9656807A908222D1D284613F0C5FA40B106
+:205100004FB9284601A9082213F0BEFA00B9374601E0374602E0761C032EDFDB002F13DD78
+:20512000616807A80822091D14F0B4F86068C1690591006A05AB1422B1B20690042011F001
+:2051400081FA00E0022060700FB00120F0BD704770B53448324E4FF08055C6F8A800D5F856
+:20516000D801314C036801210A46ADF1400D20469847D5F8D801426801212046904714F019
+:205180001DFB2A4906F154040822204614F082F827490822204613F0C9F820B925492046B6
+:2051A000082214F077F82448A060244DE560244B2361244A62612449A161244DE561244B77
+:2051C0002362244A62622449A162002525636563E562224BA363224AE26322492164F06D7B
+:2051E00010B1F16D2846884706F0CCFF684629463C22082315F04CF940F6B83406F1B000D9
+:2052000008946A462B46184907900224301D069415F03AF915F034F9284610B070BDC04601
+:20522000C8E8002075A1020000400340C87F0500C0C30200F0120050F1A501001D300200FA
+:2052400025D801008DBE0100DDD20100E5E501009DA60100ADF10100C92202004D920200D8
+:20526000ADFA0100DD070200095A00002DE9F04F002788460646ADF1140D039714F0A6FFA5
+:205280003A4D04906868384CC36C2069052103AA9847684614F0E2FADFF8E490CDF808800F
+:2052A000DFF8D0B0DFF8D4A0DFF8CC80009629F0010926F00106B1451BD02D4820F00100EC
+:2052C000B0420ED19BF900106B68206911F1020F24D059469A6B91F90010904781281BD04D
+:2052E00015E040460068D0F84C0580476FF001071AE09AF900106B68206911F1020F0DD09B
+:2053000051469A6B91F900109047812804D040460068D0F84C0580476B682069DB6A6946E5
+:205320003A469847071C04D540460068D0F84C058047B14507D00E4820F00100B04204BF5B
+:205340005846077001E05046077001206F6803902069FB6C052103AA9847049815F0C0F8C4
+:2053600005B0BDE8F08FC04670000120DCFF0020D94E02000D050120140100200C050120FF
+:2053800071C401002DE9F0413C4F3B4C3C4D38696168ADF1300D58B921B92868D0F84C051C
+:2053A00080476168096A07F11C0088473548B8636069016929B12868D0F8D40090F853005B
+:2053C00088472868D0F8D40090F942000CF042FAB0F1FF3F0A9008D00290000834BFBDF83C
+:2053E00008004FF6FF7028490880DFF8A0800026A8F87E60C8F8806098F8890020F00F0085
+:2054000040F0010088F8890098F88810012363F3C71188F888102868D0F8C403804730B9F1
+:205420001B4910206B680870596814230B703869454650B9606804687968164805F17C02FE
+:2054400007F11C03A047386113E0304611F078F86068416E02A88847334660680593066D9F
+:2054600008228DE80C0038697C35294602AAB047A5600CB0BDE8F081DCFF002070000120BA
+:205480001401002054F10080DE18002050180020D800002010080120BCB505460020E8601F
+:2054A00001242861A978287501F0030348081DD2C80801F00C0201D3042A04D1022B01D1A5
+:2054C000480900D202240C2A04BFA41CE4B2022B01D148090AD2241D32F00807E4B203D02D
+:2054E0000C2A18BF042A01D1641CE4B231F07F070BD0E878641C10F0030FE4B205D0641C2A
+:205500008808E4B224BF641CE4B214F0CFFC2A88641CE4B290420BD0880909D321480168E9
+:2055200028468847286918B9A87800F0DF00A870287D002834D150202F6969792B798DF8E0
+:2055400000008DF802101819C0B227B17A7F397F89180918C8B28DF8010068460FF039FEE2
+:20556000C8B12988012747764180A97880F83810E97880F839102979036980F8421019194E
+:20558000416480F848402F691FB13A7F416C89184164E860BCBD284614F05AFD10202875FB
+:2055A000BCBDC04674020120F0B50446A178606840182178ADF1440D0546F9B9217F0D2952
+:2055C00014BF00230123227C617841EAC20141EA431100F8011BA16913F050FE0646012BE6
+:2055E00004D104F1080114F0D7FD0836207C04F10801012804BFA07D307005E02978607821
+:205600000843287004F10801A7692E7804A814F0C3FD06A8394613F031FE0670A078237FF4
+:205620008DF80000E7788DF8013066788DF80270608A8DF8036060B9A18A40F201128A42D4
+:2056400007D194F8281004F11E000CAA0CF034FB03E0A18A0CAA09F0B3FF0CA8FF270390DE
+:20566000207C8DF84070022803D003280CD1022000E000208DF8400008210CAA08AB10A823
+:205680000CF078F908A8039020786368694604AA00F026FA044628780021102200F0F80065
+:2056A000287008A809F052F90CA80021102209F04DF9204611B0F0BD2DE9F04104460D4660
+:2056C000164610460021342209F040F9082D5CDB61782078357000EB012031460FF098FDD6
+:2056E00000280CBF01270027E178A078A2792379657900EB0120B274E179708103EB0520D2
+:20570000F174F579B081002D08BF082103D004F1080010217061357A084625B16018083112
+:20572000B061C9B20846002386F82030757973622DB17070605C491C7071C9B20846757F5E
+:20574000FDB1481CC2B2605C7270511C86F82000C9B27170A25C86F821208242A8BF7377EC
+:2057600010DA0C28C8BF0C20DFF85080450009192A46404613F08EFD7078C6F82480401923
+:20578000C1B270703078814202DD0020BDE8F081B379401A6418C5B2002B08BFB46209D0DC
+:2057A00007480E3D0E34EDB2B4620078357713F0B9FD2D1A35773846BDE8F081360100209D
+:2057C00014FB00202DE9F84F0AAF984691468A463D78009010F01CFFDFF8ECB0002426469C
+:2057E000071C15D16DB1012D42D1B8F1000F3FD05D46287880083BD3009811F0A7F9BDE8C3
+:20580000F88F009851464A460FF01EF8BDE8F88FDFF8B8A00AF11C00006895B9B8F1000F4D
+:205820000BD1B87848444010C0B2B87008B90120B870787808B903207870B878062817DDCE
+:2058400022E000B18047B8F1000F1CD05D46287880080DD35046026A12B1414638469047DE
+:2058600038780D2804DA401CC0B20C28387004D054EA060009D1BDE8F88F009811F066F9A5
+:2058800001247E7001E03E7001265D46323D95F8320080080DD3009814F01EFC48B11EB188
+:2058A000417901F0FE0141715CB1417941F00101417134B195F83200800802D3009813F044
+:2058C00089FCBDE8F88FC04616FB0020ECFB0020B0B5C16891F838300A6903F0030535F0C7
+:2058E000020702F8013B40D1D90803F00C0401D3042C08D1022D01D1590904D2C16891F8AC
+:205900003B1002F8011B0C2C09D1C16891F83C1002F8011BC168898F091202F8011B022D5F
+:2059200001D1590921D2C16891F83E1002F8011BC168C98F091202F8011BC16891F8401076
+:2059400002F8011BC168B1F8401034F008074FEA212102F8011B03D00C2C18BF042C04D164
+:20596000C16891F83A1002F8011BC46894F8391003F0020701F003010F430DD1618D090AF2
+:205980000AD2144D297884F84910297802F8011B2978491C297003E094F8491002F8011B20
+:2059A00033F07F0714D0C16891F839101170C16891F8394014F0030F0AD091F84B1002F8E5
+:2059C000011F990804D3C06890F84C0002F8010FB0BDC046AC0001202DE9F04307464FF60E
+:2059E000FE754FF00008ADF11C0D391DBD8101A88DF8008014F0E4F968460AF087FE07F1DE
+:205A00000409444601280BD1BDF80C00BDF802107E88B8818E4218BF6E4602D1012441E0AF
+:205A200046468DF80E807888ADF810000DF10E0008F0C6FF012808BF0DF10E0430460126AC
+:205A400018BB74B97888854206D1484612F0ECFF012818BF404602D138460CF0DDFB064636
+:205A60001FE0A089B881201D12F0DEFF012807D0484612F0D9FF012813D103213C460DE0A1
+:205A800038460CF0C9FB064606E080893146B88138460EF087F824B16580022120460EF0A1
+:205AA00081F834463E78A6B1384611F0FDFF01280FD10A48BD89001D0168AA0002EBC502E6
+:205AC000501889180A78164203D116430E7014F0C3F9204607B0BDE8F083C04630050120E7
+:205AE0002DE9F04F0C46834661782078D4F80C904018C6B2E0781D469246ADF13C0D0428E7
+:205B0000A8BFA77803DAA07800278019C6B212F011FB0E90E07813F005FC0D90494610226C
+:205B2000F01900EB050809A814F058F94FF000090146BBF1000F25D1E078042847DB00294F
+:205B400046D1684614F0C0FA09A8069621780797637800900D240D9E01951A46CDF810A08C
+:205B6000204FCDF8148058188DF8204052188DF8216040195219039069463868029214F05A
+:205B8000D2FA23E0E078042821DB09BB684614F09BFA09A8069621780797637800900D248B
+:205BA0000D9E01951A46CDF810A00E4FCDF8148058188DF8204052188DF821604019521990
+:205BC000039069463868029214F0AAFA014609B15FFA81F90E9813F090FD48460FB0BDE8AB
+:205BE000F08FC04608DC00202DE9F04780463D49D8F80460C86CD1F808A07F2500220124BF
+:205C0000A946ADF1200DB0438446C86404FA02F01CEA000F10D05FEA0A074FF0000007D08C
+:205C2000BB789A4204BF401CC0B2BF69002FF7D18542C4BF051C9146521C1B2AE6DB002EC1
+:205C40000D4636D1284C5FEA0A0725D02168B5F848004FF6FF72254B3E88B04219D1BE78AB
+:205C6000B14516D19E1F3688B24208D114F07FFAA5F848003E88B0420ED057460AE000245C
+:205C800085F84A4009B1C4208847204612F074F824E0BF69002FDFD185F83C90FEF7CEFDA8
+:205CA000E0B10020216885F84A00B9B1C420884714E0EE64684600211C2208F047FE8DF8B1
+:205CC000044000268DF80760D8F80400009095F852708DF80570684608F09EFF08B0BDE821
+:205CE000F087C046E4FA002044040120E4FE00202DE9F04391460A68D9F8004016788046C7
+:205D000000271D463846ADF1140D242E02F101020A6058D11678521C4C2E0A600ED1AA6810
+:205D2000E41C24F00304241D54F8040C414614F0A3FB2968EF600127091A2960462E1AD16F
+:205D4000E41C24F00304241D54F8040CE41C029024F00304241D54F8040C00274146039000
+:205D6000AA68ADF8047001A814F082FB2968EF600127091A2960532E25D1E41C24F0030488
+:205D8000241D54F8040CE861C9F80040288B0090A968EA69D8F800004B4614F065FBD8F8E0
+:205DA0000040002744B1A9688142D8BF481ED8F800100918C8F80010D9F800402968EF60F4
+:205DC0000127091A2960662E0BD1298B012904D0E41D24F00704083403E0E41C24F0030473
+:205DE000241D1FB9E9690E700127EF60C9F8004005B0BDE8F083FEE73F482DE9F04F001F95
+:205E0000ADF1140D00F1A80100F1980B8046029100F1AC0103914FF4804013F001FDE8B16D
+:205E20004FF00450D0F89813D8F8046090F88503C3F38857C1F31501C0F38002C1F31501BA
+:205E4000B8050143B06841EAC2716A4602F0AAFAD8F804008168012012F090F900270226CD
+:205E60000DF10409234D049759F8044F236883B32068806913F0D4FC824620680023524658
+:205E80000FF034FB1AF00A0F08D1BAF1000F20D0206847F48047C8F8B0001AE02068144955
+:205EA000AB688069014023EA0100A8602068C1692A6822EA010028602168102012F05EF9A4
+:205EC00021680BF1080012F059F8049847F002072060761EC8D127B108F1E000394614F025
+:205EE00093F904F0D7FEF8F74FFA05B0BDE8F08FFDBFFFFF0C10044034F500202DE9F04F84
+:205F0000DFF8E8A0DFF8E88000244FF001096FF001064FF6FF7B2546ADF1240D01A80090DE
+:205F200029462246102303200FF084FC00284CD1BDF804109DF80970A80000EB45102AF88F
+:205F40000010504447719DF80A3083719DF80820027180F809900482BDF80610C4729DF8C5
+:205F60000B7041800623C771049A0372AA278772B2F1FF3FC46016D103798BB11E4A1F324A
+:205F80001778032B0CDA2FB958F82720C26158F8272009E058F827309A01A2EB830202E006
+:205FA000C661866103E0C261826180F820408B450BD08DF81490ADF8201005A80CF08EFF33
+:205FC00018B1BDF8040011F04FFF6D1C332DA5DB2046042111F090FD3328A4BF05480470EF
+:205FE00007F0DEFB09B0BDE8F08FC046E40D002048BC020035040120ACFE00202DE9F84362
+:206000001D463C4B9433089C1B68C3F38018DB0915D20388A3F6020343B141F21E069B1B65
+:2060200004D000F11A030B60C06903E000F112030B604069106000202860206056E0038894
+:20604000A3F60203F3B141F21E069B1B17D041F6E6769B1B05D0876AC36A90F82460BC46C0
+:2060600003E0D0F820C0436A002600F11A070F60C1691160C5F800C02360007E0DE0466A8B
+:20608000836A01E08669C36900F112070F60416911602E602360C67B007C00F00707286827
+:2060A00088B140F203714FF6FF72052311F060FD8146B9F1050F06DA3046394609F0BEFCB8
+:2060C000296841F82900206880B140F203714FF6FF72052311F04CFD0546052D06DA304673
+:2060E000FF2109F0ABFC216841F825004046BDE8F883C046402108402DE9F8433A4C364D4A
+:206100008146241D54F8040C800807D254F8080C05F14D01000C40F0F000087033484FF0B8
+:2061200001214FF080531838DFF8A880C0F804140088D3F8F0012668016803F5F8773046F4
+:206140008847B00E03D2700E24BF022028703868426831464846904710F010FD38B120681E
+:20616000810C2CBF002040F307200FF029F92048BC300068C0F3053188F80010410A39BF94
+:20618000402185F823104021E974800900F0380040F46050A8F85C003868816830468847D1
+:2061A0000E490F4A0AE0105C9478131D844299BF184410F8010C18444078086008684B686F
+:2061C0009842FCD10228EED1064901200860BDE8F883C0460EB00C400962084000600C40C8
+:2061E000B0C3020094046042B04F005018A00C40501300503D492DE9F04105464C310868E5
+:2062000000286CD1384CA7683E1C0BD068883988884203D12979BA78914218D03E46BF69C7
+:20622000002FF4D11C2006F015FDD4F80880071C58D000211C2208F089FB4FF6FE70FF23D7
+:206240003881B8F1000FFB720CBFA760B761687AB871287A78712879B87068883880287BCC
+:206260003875287A012806D107F10C00FF21082208F06CFB05E007F10C0005F10D0113F032
+:206280008BFFA97A06292DDD6879012802D013F079FE38B3B87A0026884202DAEA7A102A3B
+:2062A00005DB884204D1F87AE97A884200DD0126AB791BB9E08F2988884206D12EB1288874
+:2062C0003881A87AB872E87AF872E87908B101203871A87908B10120F870BDE8F08109681F
+:2062E00028468847BDE8F081E4FA002034FD00202DE9F0413A4D04462868ADF1200D18B9B8
+:206300000FF07EFF286840B330490978A14224DD4FF0FF3113F0FBFB2D490C2014FB001473
+:206320006768A668387801282ED0B268511EC843B86028683368844619420BD17068824235
+:2063400008D8B9680140814204D1706930BB308B042804DB604613F04FFF002431E0DFF8D6
+:20636000748058F82030A3B9684613F0A9FA00208DF80C00F1698DF80000307E0491694657
+:206380000EF0AAFC031C01D1002417E0308B48F82030114A815C491C815400E003687B606A
+:2063A0001048318C0D4B01607A681A60204612F04BF90120387020460FF0F2FF286813F055
+:2063C0001BFF204608B0BDE8F081C0464CBF020070C1020044130120D8130120A0130120D1
+:2063E000A8130120A413012038B505461446480817D2880872D31C20002113F0FBFB1D20B6
+:20640000002113F0F7FB1E20002113F0F3FB1C20002111F099FB00211D2011F095FB002114
+:2064200059E01C20002113F0E5FB1D20002113F0E1FB1E20002113F0DDFB284606F092FF77
+:2064400021460090C20F0888A0F6020068B141F21E03C01A09D041F6E773C01A09D191F85E
+:20646000240010F07F0F04D019E0C87B10F07F0F15D1012A0DD01C20002111F065FB1D20E3
+:20648000002111F061FB1E20002111F05DFB1C2014E01C202F2111F057FB3221BCE7012A96
+:2064A00010D01C20002111F04FFB1D20002111F04BFB1E20002111F047FB1E20012113F0AA
+:2064C00099FB38BD1C20002111F03EFB1D20322111F03AFB2F211E2011F036FB38BD70476A
+:2064E000F0B50E1C14460546ADF1140D04D0084613F022FE071C1ED1324F33203979FF2964
+:2065000005D0401E07F12407F8D100274BE001208DF80000ADF80250314601A813F050FCFE
+:206520006846FFF759FABDF80C00002678802846BE7111F099FC00200122014614B1052CD2
+:20654000B8BF04213D803C71797106263E727A72AA25BD723882F871F8728023F86087F87E
+:206560002130E4B118480678032C18DA17483EB900EB8601096B00EB8600F961006B0AE0DA
+:2065800000EB8600036B9901A1EB8301F961016B8801A0EB8100B86187F8202003E06FF0FD
+:2065A0000100F861B8610020042111F0A5FA332802DB07490020087007F0F2F8384605B04F
+:2065C000F0BDC046E40D0020CBFE002018BC020035040120F0B5364D384C0028ADF1140D4B
+:2065E000697820725ED129B9207818B9082012F0D5FE697831F0010051D16846002110228B
+:2066000008F0A4F913F0C6FA002848D0294D05F1240006463930074611F0A3FF20B9284963
+:2066200038461C3113F0B8FD06F1160153200EF0F3FF95F83200000934BF0020012004A9BD
+:206640008DF8100052200EF0E7FF082085F84A0007F0A6F808F068FA1A49486808B901207C
+:206660004860E0794FF440710BF09CFA684610F0FDFA6846002110F095FD95F8650010B9D3
+:20668000002004F093FD68460021102208F05EF909480078012802D0012011F06DFB012097
+:2066A00010F03AFFE07902210BF07CFA05B0F0BDACFE0020E4FA00208EFF002034FD00208C
+:2066C000FCDB0020480401202DE9F84F13F0D9FC364C374D84F82400E87984F82B004FF034
+:2066E000020B84F836B00F2784F8287084F8507084F85170002684F82C6084F82D604FF0F2
+:20670000010884F82F8084F890804FF0050984F83090A87984F82500687984F831804FF61B
+:20672000FE7A84F826002348A4F83AA0007884F83200E878A086A87C84F83C60082284F8D0
+:2067400037002879A4F83EA0314684F8380004F1400008F0FBF804F15D0005F14401A4F873
+:2067600048A013F019FD687A84F88E0084F86560314684F88A70287A84F88B905A4684F8A9
+:206780008D00E87C84F88C8004F1920384F88F00892013F021F908B1A4F8926030460FF069
+:2067A000C7FCA4F89460BDE8F88FC046E4FA0020ACFE0020E612012070B5324C0D46A808CD
+:2067C00050D2E8085DD301250420657010F08EF92D480068006B8047A060606804F1980667
+:2067E0000146306870B10069064649B18E4207D0B16AC90803D3436A0421002298477576C3
+:20680000314661604868214900780860022010F06DF9112003F058F91D48007884F824507C
+:2068200010B90E2003F050F960684168886808B9C86810B1174813F0FDF91749072000260D
+:2068400008601649174B0E60154D4E600A68A36245EA020008601A2013F0BCFC192013F050
+:20686000B9FC70BDFCF77EF8204600F1A001096811B909F0FBFC70BDE03045F0020113F032
+:20688000C3FC70BD30F500208C010010D021084052C30200510007060000046014100440B0
+:2068A0000240004039310100F8B5134602465468956808464FF0FF31203856D0401E5FD01C
+:2068C000401E33D0401E3FD0401E26D0401E1DD0401E52D1D4F8C070002F5AD094F8FE707B
+:2068E000002F56D02968486A40F003004862D4F8CC002A6941686F69096847EA02008862E9
+:206900002968486840F00200486026E0D4F8C070002F3ED10020014605E0D4F8C070002FA5
+:2069200037D10120002184F8FE0032E01E78FF2E15D094F8FB0010F063FC84F8FB6094F890
+:20694000FB00696B11F000F994F8FB00FF2804D010F056FCFF2084F8FB00002119E0104694
+:2069600023210022FFF7A0FF12E094F8F90001280FD1012084F8FC00EFE76FF0010108E0E4
+:2069800094F8FB00002110F051FC002084F8FC0001460846F8BD7047B0B504462079ADF183
+:2069A000580D042869D136480078002865D013F0F1F8002861D1AB20002113AA0CF0D4FDFD
+:2069C000276813A8874207D0002F56D013A8394612F00EFB002850D038460DF1550106AA69
+:2069E00007F036FF9DF85500002846D09DF82800012842D14FF48170002110220BAB12F00B
+:206A0000EBFF032008210BAA0FAB8DF8540015A80AF0B0FF002568460C228DF81450294639
+:206A200007F094FF41208DF80200ADF8005001278DF805701A238DF804306846FEF72CFD0B
+:206A40009DF81400C8B90398456C0F272F702079687012F0EFFB0146082213A812F01AFC4A
+:206A600013A9A81C13F098FB0FA9102205F10A0012F010FC68460DF08FFF16B0B0BDC04696
+:206A8000ADFE0020364AF8B52120742113F0B6FA0A2814BF002501250C2006F0DBF8071C0D
+:206AA00014D0FF210C2207F051FF2E4E002407E0214601200C223B460BF0EAFD641CA4B2E7
+:206AC0003088A042F4DC38460EF066F8102006F0C1F8071C10D0FF21102207F037FF0024ED
+:206AE0000320214610223B460BF0D2FD641C332CF6DB38460EF050F81B48006820B18047B8
+:206B00000A2808BF45F008050FF09BFE0A2808BF45F01005142006F09DF8071C1CD0002170
+:206B2000142207F013FF4C2014213A4613F066FA0446092C04D14C2014213A4613F064FABC
+:206B400038460EF029F8094A712008213F3213F055FA04430A2C01D145F020052846F8BDFC
+:206B600008FB0020300501200C030120B9FE00202DE9FF41384D95F83C00012101AA0446DA
+:206B800012F03EF80221204602AA12F039F89DF80A4095F83D10EA78002605F130074FF0A8
+:206BA000100C10E08C4214BF6346BDF80830880000EBC100491CC019838391FBF2F303FBAB
+:206BC00002F0091AC9B295F83E00401C90FBF2F35343C01A8842E5D195F83D40A84635E091
+:206BE000A00000EBC400C119898B10291AD03A180421022320461C320DF040F86870E86888
+:206C000061036A46042313F037FA009800F0FF007C2802D0FE280BD1FEE7204678210FF023
+:206C2000EDFE05E0204602F0F9FB761CF6B26870E97898F83E30641C94FBF1F04843241A0E
+:206C4000581CE4B290FBF1F24A43801AA042C7D130460090BDE8FF815CFC00202DE9F0472B
+:206C6000ADF1900D13F0B2FA2D4A1178002952D1114601240C7013F033FCFAF76DFB092032
+:206C800002F022FF20A812F0BDFF4FF0FF302190254A2448102120AB0EF07CFA2348244919
+:206CA00090F800800B7800274046054683421BD3DFF880A08600A1460DEB0600041FDAF847
+:206CC0000000315821F0FF0044F8040F880807D2E8B201F0010112F08DFF09FA05F0074306
+:206CE0006D1C361D9D42EAD91549134C4FEA8800C0EB830201F1D003121D1F600DEB0001FC
+:206D0000001904F0F3FE0D49086820F4F85040F40050086001E013F0E3FB24B0BDE8F087B5
+:206D200008060120241201207D2F02003BBF02003CBF0200D4C202000010084000300940BD
+:206D4000002002402DE9F04F09AF8046ADF11C0D9B460491386805923D7A06901946404658
+:206D600010F0D2FA0828A8BF4FF6FE7905DA2E4E410001EBC00136F801904FEA251A680903
+:206D800034BF0820102069110391A90924BF0830C0B28DF80100684611F036FC061C40D0C2
+:206DA0000124B47712F046FA706201A9484611F0D2F830B95FEA5A0006D3C14504D106988E
+:206DC00000E001A874773062346902202070657084F802B084F803804FEA28232371049AA6
+:206DE00062711012A07148460CF0A2FC05994018E0715FEA5A0038BF002005D3069904F1F8
+:206E0000080013F0C9F908200399490804D379680019083013F0C0F9A6F802903046F4F73A
+:206E20002BFF07B0BDE8F08FA80100202DE9D04781461E46924688460846ADF11C0DFDF77D
+:206E400069FC404610F034FF304807684FB103208DF8080041460822684612F01BFA684659
+:206E6000B847ADF80290CDF8048002208DF808000024ADF80040404613F05EF936BB28B929
+:206E8000484641460CF032FAAA281FD112F082FEE0B9AB20214603AA0CF066FB404605A968
+:206EA000224607F0D5FC1A4826300078012807D19DF8140020B98DF80940684608F001F981
+:206EC00001208DF80900684608F0FBF8404613F033F978B1007968B105280BDABAF1010F2D
+:206EE00003D0012818BF022801D113F081F940460BF080FD4846214611F052F9484610F079
+:206F0000B3FF11F037FE07B0BDE8D08708030120ADFE00202DE9F84F06467068B6F80A8026
+:206F2000447800F1020B042C10D0012C07D0062C05D090F81A9000F1120500270AE090F8A9
+:206F4000129000F1130700F11B0503E000F1120700F11A054FF0010A5FB1384611F064FD3C
+:206F6000012806D112F066F90146384612F040F88246BAF1010F1BD0B8F1000F36D1384606
+:206F800069460FF0F3FC012830D10021BDF800007172174F7081387820B17068007805281C
+:206FA00008BF0121317330460BF009F9BDE8F88F202011F092FA071C18D004203870A7F862
+:206FC0000280594610223C71B81D87F8059012F061F907F11600294612F0F2FE87F81E90D0
+:206FE0000448FC77007839460CF056FBBDE8F88FB8FE00203BFD0020F0B5344C054604F1CF
+:207000003A0000880026ADF12C0DA84228D0284613F062F8071C24D03879012818BF022812
+:207020001FD18DF818607888ADF8240006A80BF055FFB0B128483988001D01800DF10B0064
+:2070400007A913F0A9F812F005FE8DF81660ADF8140039790222684605F0B6FDFE6032E087
+:2070600025B986BB284610F0FFFE2CE00BF0BEFDADF82600BDF826000DF12601608753209F
+:207080000EF0CAFA1248BDF82640076810F0E8FD1048007810210AF085FD97B1D6257868C5
+:2070A000007858B1042011F018FA011C06D00D704C807868406800780CF0EEFA3F68002F22
+:2070C000EDD110F079F90BB0F0BDC046E4FA0020240501203BFD0020ECFB002030B50D4633
+:2070E00004463649E07AADF1140D401E4ED0401E37D0001F14D0401F5CD16868002859D01D
+:207100000846A27A2368E1680270981D0122009001A812F0C3FAE068401CE060696846E014
+:20712000E868002846D0E1680DF10200012212F0B5FAE068401CE06012F0E2FEE168ADF8F0
+:20714000040001220DF10600891CE16012F0A6FAE0682168401CE060498AADF80010E96836
+:2071600025E0A86830B3E1680DF10200012212F095FAE068401C0190E0602068817B0229F6
+:2071800004BFC088ADF80000A96811E0286888B10846A27A2368E1680270981D032200905A
+:2071A00001A812F07BFAE068C01CE060296802906846884705B0002030BDC046810301203E
+:2071C0002DE9F04180463448344C06AFADF1200DADF81E300578ADF81C1094F84A001646B3
+:2071E000042814BF0828C22052D0BDF81E004FF6FE71814208BFC3204AD0684600211C2241
+:2072000007F0A4FB032007A984F84A0050200EF003FA4B200DF11E010EF0FEF984F83C603F
+:20722000BDF81C00BDF81E3084F832504146A4F8480004F15D00E38712F0AEFF05F0CE05DE
+:2072400045F080058DF80B60022300268DF81A5038788DF81630BDF81E208DF80860BDF83A
+:207260001C70ADF80E2004F15101ADF81870401C84F85C000F250D7054200EF0CDF904F129
+:20728000500147200D700EF0C7F9684602F048FF08B0BDE8F081C046E6120120E4FA002029
+:2072A0002DE9F047334A32491768334A4E8E15784FF6F8798846ADF1200D01E012F0E1FE13
+:2072C0008145FBDD0028F9D02C4CE76409F107010F2784F85250824684F85070B14284F893
+:2072E00051704FF0000584F8535006D1B8F83200814201D112F0C5FE0646A4F8486008F1CE
+:207300003C0011F02EF908F13C06012804D104F15D00314612F040FF04F15D00064611F027
+:2073200020F918B9E220314610F0D6FCA4F83AA084F85070E58784F85170052084F85C5070
+:2073400029461C2284F84A00684607F0FFFA8DF804508DF80750E06C009094F852608DF8C8
+:207360000560684607F058FC08B0BDE8F087C046ACFE002040FD00208DFF0020E4FA002004
+:207380002DE97C430D460446A16A4878CA78897801EB0229217F042959D1DFF8C08002281E
+:2073A0004FF0010625D9C01E07283FD90838012818D9801E02D0401E38D036E04046A0F107
+:2073C000320191F83200800830D391F84A00082802D14846FFF710FE48460BF05FFFC528F8
+:2073E00024D11CE04046007880081FD30DF094F81CE040460078800818D34846002107F088
+:20740000F7FF70B1817911F0180F0AD0A1890091028843886189104600220BF04FFE002679
+:2074200004E0484612F05EF900E0002512F0F2FE60890DF051FB50B1A07C022807DBA18905
+:20744000404608300088884201D0012E02D00020BDE87C832846BDE87C83C04616FB00203D
+:207460002DE9F04116468846044612F0AFFE074631488325B8F1090F36D8DFE808F0554A07
+:207480004744402917053C37044694F82400E8B9D4F89800D0B9316804F1E00011F05AFF19
+:2074A000316804F58E7011F055FF3FE0044694F8240058B9D4F8980040B93168192012F08C
+:2074C0008DFE31681A2012F089FE2FE000252DE0306828B1012807D180200EF0ABFE25E0C6
+:2074E000802011F035FC21E003251FE02020314610F044FE1AE031781048017016E031689E
+:207500001030016012E03088A0850FE0308860830CE0012026696369607606F1600020615B
+:2075200003F16000606101E030682060384612F0D7FF2846BDE8F08130F5002070F7002097
+:2075400070B50546A87A0024ADF1180D60B9E87A400909D22D480078012804D12F4816306B
+:207560000078012800D0C824002C49D12888696805AA0FF063FFA87A50BB2548E97A007862
+:207580004A0902D2C80818D31EE0E8B900208DF81600204858C8694658C109C881E809001C
+:2075A00068686A460DF1160107F052F99DF8160018B19DF81000022806D0E87A000938BF79
+:2075C000AD2406D3002408E0284607F07EF904461CB1686810F06CFB94B90F4E306890B148
+:2075E000288869680822ADF800000DF1020011F051FE28893168ADF80A006846884702E093
+:20760000284604F03BF9204606B070BD56FE0020340401200CC1020094FD0020ACFE002074
+:207620002DE9F04FADF1140D04900EF07BF95FEA000861D0002427463D46B94623E008EBA5
+:20764000C500401C834612F077FDD0B10179012918BF022915D190F82000012811D10C20DE
+:2076600005F0F8FA061C0CD0594612F095FDC6F80890002C0CBF341CCAF808607F1CB24698
+:20768000FFB26D1CEDB298F80000A842D7DC002F2FD00220049E8DF80C007088ADF80400C0
+:2076A000F80005F0D7FA061C21D074B14D46A14606EBC500494612F06FFDA46848460DF010
+:2076C0006BFA6D1CEDB2002CF1D148F21F00009004983A4601A93346113002F065FB3046FE
+:2076E0000DF05AFA05E02046A4680DF055FA002CF9D140460DF050FA05B0BDE8F08F704743
+:20770000F0B50D464FF0B30C04460021ADF11C0D0E46DFF8C4E00027042238461EF80E3F44
+:20772000FF2B04D00346581C9942C0B202D0521EF4D100E0774627B17A799219D6B2B442A9
+:2077400003DB491C0429E4DB42E028460021182207F0FCF87879A41B2418E0B207EB400074
+:20776000C088688111F066FD0146284612F014FD7878012822D07888ADF80C0004218DF846
+:20778000001068460BF0AAFBE0B103208DF8160001A90DF10E0012F0FFFC9DF816609DF8E9
+:2077A0001600032E287518BFBDF80E0009D105F10C000DF10E0112F0EFFC03E001202875D4
+:2077C0007888A8813878287238794FF0000CA87507B06046F0BDC0465E0100202DE9F04741
+:2077E00088461546814600212022ADF1200D684607F0ACF84046103808D0083804D0083828
+:2078000014BF0026032602E0022600E00126012404FA05F7274D4FF0805000F5D87A2F60BD
+:20782000D0F8B001416927208847C5F87C430321C5F88013C5F8FC42C5F884136868B0420E
+:2078400018BF6E60B8F1180F45F8047C1CBF41464E4606D168464946182204F047F96E46CA
+:20786000202130460EF07EFC204612F06BFCD5F88C036FF39D000028F6D0D5F88C636FF3A3
+:207880009D06C5F88463DAF80000016A27208847DAF8000001692720884716F0404F04D192
+:2078A0002868074218BF002000D1204608B0BDE8F087C046044402402DE9FC4707460E1C8D
+:2078C00014BF4FF0000A4FF0E80A002F5BD0BAF1000F5AD17868401E78603F210170BD6D0B
+:2078E000002D0CBF802000207968DFF8A4900225083E491E7960A84608703889A7F85450CD
+:20790000801C388116F8080FFF2839D02A2834D1706890B3D9F80010D1F8B8108969884718
+:2079200005467868401B78607168CA0809D2D9F80020D2F8B820D46900233A46A04788B1D0
+:2079400013E0D9F8040080680078D9F800408DF80000D4F8B8007168C46978683A466B46CE
+:20796000A04710B9EB20BDE8FC873889B7F85440401938816019A7F85400B8F10108C1D15E
+:207980007868386501E04FF0E80A5046BDE8FC87140100202DE9F84F894600274FF6FE7B54
+:2079A0009046824601253946CDF800B00CE0012F08BF012106D012F064FBC1B291FBF7F0ED
+:2079C0007843091A00273D46274B322233F81C0F834517D0824515D0814513D0804511D059
+:2079E0005E7C7EB1082E0DDA072E0AD0012D05D07F1CFFB2B94205DCBDE8F88F7F1CFFB2AF
+:207A000000E00090521EE1D1184A332332F8240F83451CD082451AD0814518D0804516D001
+:207A2000567AA6B1082E12DA1479012C0FD0022C0DD0072E0AD0012D05D07F1CFFB2B94200
+:207A400005DCBDE8F88F7F1CFFB200E000905B1EDCD10FB10029AAD00099584688421CBFF8
+:207A6000081C80B2BDE8F88F50080020C00D0020844610460029624667D0422A0FDC412A35
+:207A80004EDA083A4FD0521E3ED0521E54D0521E2DD0521F47D0083A222A10D97047433AAB
+:207AA000012A37D99D3A022A21D9083A012A2BD9921E1CD0921F18D0521E14D07047DFE816
+:207AC00002F032233B163936341432233B163936341432233B163936341432234444444438
+:207AE0004444231614C0102222E0082220E0096800F8011B0A0A00F8012B0B0C00F8013B8B
+:207B00000A0E00F8012B70470A7800F8012B0988091218E04B780A7802EB0322921C07E03C
+:207B20000A78521C04E009780DE0072200E0062211F0B4BD0522FBE70A7800F8012B4A78EF
+:207B400000F8012B897800F8011B70472DE9F8430446994690460E1C44BF0020011C5CD44B
+:207B600012F04EFB05463146802220460DF0A0FC071C04D097F8331031F07F0106D12846A8
+:207B800012F06EFC02200021BDE8F8834FF0E0400A2107F1200640EA090941EA080896E879
+:207BA000030008EA000019EA010608BF00281CD0284612F055FC07F1200003C804F1B0069C
+:207BC00004F1B00508EA000809EA010986E8000395E80C0007F1200696E8030007F120054E
+:207BE0009943904385E8030014E00D48B968884203D0B968C4F8A810B86004F1A00080E8B5
+:207C00000003284612F02CFC04F150004FF0FF3111F07DFFB03494E80300BDE8F883C0460F
+:207C2000CB1302002DE9FE43144681460EF084FB88460646FF2E21D02E49B00000EB06100F
+:207C40000A5C4518520852D3EA884FF6FF7393424DD009180F698FB13B681888844203D012
+:207C60007F68002FF8D109E047B13BB14846414622466B4604F0EEF9012802D00220BDE88D
+:207C8000FE831D48007880210CF066FF002804BF0024A04604D00FF001F84FF00108044631
+:207CA000A88818B129890919884220DA9DF80200024611F082FA38B110463B68019A991DA4
+:207CC0009B1CFAF72FF890B111F0F4FF3046F5F779FFB8F1010F03D1204600210CF0EEF8D0
+:207CE000FF2130460A460CF027FD0EF0EFFF0020BDE8FE83080D01204DFF0020F8B52F4C82
+:207D0000334D6788BFB905F108000068D0F8F4002B4BC18F012606FA01F08102A1EB8011DC
+:207D200018784FF47A7201F570714843B0FBF2F081B2A18000E0A1882078B9421ADD214845
+:207D40000068214F016C386888472178C0B28142B8BF20706088401C608012F089F84FF4B0
+:207D60007A71B1FBF0F0194904F10803002204F0B7FFF8BDA968D1F8F46040B20FF043FE49
+:207D800096F84410B2695054A868D0F8F40090F84420012700EBE20002F0070207FA02F1A6
+:207DA000427900238A434271AE686380D6F8940023700078042109F0F5FEF8BDD004012044
+:207DC000D8000020E0FF002080000120FD7C01000C010020F8B50020314C8DF8000012F093
+:207DE00069F9A41EA2782F4D012191404FF6FF72521802402868D0F8B810628108780028C9
+:207E000029D08A6B3AB342F21A0069469047204867790678CEB1C7B99DF80060AEB128680A
+:207E2000D0F8B800C06D80B1804707461E48017857B16868406866890078083010FB01F056
+:207E4000B7FBF0F17018608167799DF80010608907FB01006081607810B905F013F801E052
+:207E600008F090FE2868006C006878B109480B49007840B90848007828B9832208460270CB
+:207E800010F0E4FAF8BD022208460270F8BDC046FC13012005140120071401200A140120CB
+:207EA0004E02012014010020D800002010B504462088ADF1180D0CF00FFE002859D111F04E
+:207EC00069FE002855D1A0782B4958BB207A04284FD1084600686A4605A906F0B9FC04465F
+:207EE0009DF81400002844D09DF81000012840D102209DF813308DF8100033F07F0003D0BA
+:207F00000DF113000FF0F2F80420214614226B460EF098FB002012F03BF801200146F0F7C0
+:207F200071FB26E0207A042823D1084600686A4605A906F08DFC01469DF81400C8B19DF884
+:207F40001000012815D1002201929DF81300009230F07F0003D101208DF81100FF228DF843
+:207F6000102004206B4614220EF06CFB03490220087006B010BDC046B80001206DFF00208D
+:207F800070B5334D06462868D0F83C03ADF1300D8047002818BFFC2057D16846314611221C
+:207FA00003F0A4FDB47C707CF37C8DF812402A688DF81100717D8DF81330D2F8D400B47D1E
+:207FC00090F853008DF815108DF81400002104B10121347E8DF8161096F825208DF818407E
+:207FE000F07D8DF8252096F824308DF81700F48C8DF8243006F119010B220DF11900ADF879
+:20800000264003F073FD707C002448B9812004F021FE0A9078B1FF21812206F097FC0CE0D7
+:208020009DF815000A9440B1810001EB401004F011FE0A9008B91A2406E02A6802F551727C
+:20804000126807206946904720460CB070BDC046140100209EB501468A695078137803EBA1
+:2080600000232E480088984212BF00272C4F3F1D2C48006857B948F202000090087C019069
+:20808000487C8022891C0FF0C3F99EBD002200F8012B00F8013B1C1200F8014B3A78D3103E
+:2080A00003F0020402F0070203F00103234342EAC30200F8012B7A7802F0F80302F0070280
+:2080C0001A4300F8012BBA7800F8012BFA7800F8012B3A7900F8012B7A7900F8012BBA7912
+:2080E00000F8012BFA7900F8012B3A7A00F8012B3A89121200F8012BBA7A00F8012BFA7A16
+:2081000000F8012B3A7B1023027001F11100891C48F2020208F002FD9EBDC04650FD002036
+:20812000E01201209CFD002070B5064600210C22ADF1380D06A806F009FC0FF058FF30F0B1
+:208140007F000CBF002501250024072021460C2206AB0AF09DFA30B92DB1072021460C22E5
+:2081600006AB0EF06FFA641C052CEEDB07A8FF21082206F0EBFB641EA4B207200C2206ABBA
+:2081800021460AF085FA30B92DB1214607200C2206AB0EF057FA68460021182206F0D6FBAC
+:2081A000822018216A4611F029FF30B9012E04D1822018216A4611F027FF09A80021112267
+:2081C00006F0C4FB3A20112109AA11F017FF30B9012E04D13A20112109AA11F015FF3B20F8
+:2081E000112109AA11F00AFF30B9012E04D13B20112109AA11F008FF0EB070BDC8B5071CD0
+:2082000065D097F84000433080B210F066F9061C5DD097F840200021433206F097FBE220F8
+:2082200000233070391D737091E80D00311D81E80D0038693061387D3075B87DB075F87D9D
+:2082400007F11803F0751A6806F118000260596841601A890281788C708497F8250086F801
+:20826000240097F8260086F8250097F8270086F8260097F8280086F8270097F8290086F896
+:208280002800F86AF06297F8300086F83000786B706397F8380086F83800F86BF06397F81D
+:2082A000400086F8400097F8402007F1410106F1410010F0EFFFF22010F00EFE18B930460C
+:2082C00010F0F2F9C8BD007931460BF0E5F9C8BD7FB500242E482D4D2F4E04702D482C7096
+:2082E00031680470D1F800016C70C089D1F850126C61103080B28847286120B93068D0F887
+:208300004C058047286900908DF804409DF8051004F0030221F003010A438DF805209DF817
+:20832000051064F383018DF805109DF8051064F307118DF805103168D1F80011C9896A468B
+:208340001031ADF80610296913680B6052684A60E8612C6202F042FD7068C168087838B9CB
+:208360003068D0F858242046014690477068C1680A4804700A4D2C70087828B93068D0F822
+:20838000582420460146904700907FBD681101200514012007140120140100200A1401208D
+:2083A000FC130120F0B50E460021ADF1140D0191029103911446049103AB02AA04A9009174
+:2083C00001A9FDF71BFE8325310824D2E0B1039F87B10499C6F3150271B1019840F22B21FE
+:2083E000028038460FF0BBFA0298049907F044FA039826E0C6F3150240B1019800884FF695
+:20840000FF71814202D132E0C6F31502019802806280102029E0002829D00399A9B104998A
+:20842000C6F3150699B101984FF6FF720280084632462B210FF093FA0298049907F0BEFCC7
+:20844000049815212180606012E0C6F3150670B102982B2132460FF082FAFF2807D0019892
+:208460004FF6FF71018066601420208000E00325284605B0F0BD70472DE9F84391468846A7
+:2084800007460CF029FB002818BF002058D1384600210DF049F8494606F0AAFF0025041CD7
+:2084A00019D1384610F070F911F016FE002846D041794A0843D389084FF0010606D3404640
+:2084C0003946324608F08EFD80B938E0417941F0020141710AE06079032806D001282ED145
+:2084E000608807210CF0D2F948BB02261CB1A07910F0180F19D1404629460DF015F811492A
+:208500003A31098881420AD040463946324608F069FDA0B9384649460FF042FE0EE03846D6
+:2085200049460822FCF7D4FB08E0608839462A464FF6FE73009040460AF0C0FD01252846EA
+:20854000BDE8F883E4FA00202DE9F04781463148006888464FF47A711E46ADF1280DB1FB29
+:20856000F0F080B202FB00F50FF0E4FD82464146484610F0B9F90824071C36D1142004F00A
+:2085800069FB071C3BD0684600212422234611F063FF012E1ABF0020059005950120ADF84B
+:2085A00010001A48069729466A46002311F050FF0346174882683B609BB187F80490C7F8CF
+:2085C000088000243E73002A3C6108BF876004D0164633691BB937613B68184609E01E4643
+:2085E000F7E738460CF0D8FA09E0386811F054FF3868294611F028FF386811F021FF5046E6
+:2086000011F07BF820460AB0BDE8F087412702008004012040C402002DE9F0438046002165
+:208620000822ADF1240D06A806F090F90021142201A806F08BF90025FF274FF001092E4692
+:20864000274C8DF8147004202946142201AB0AF01FF8002837D1B8F1000F27D101A80090FF
+:2086600029463246142304200DF0E4F803A806A9082210F009F858B90199A80000EBC50057
+:20868000231883F809900B3101912150029A5A6004202946142201AB0DF0D4FF01A8314691
+:2086A000142206F053F98DF814700CE004202946142201AB0DF0C6FFA80000EBC500265048
+:2086C0002018466046726D1C032DBCDBB8F1000F02D030460EF00AFD09B0BDE8F083C046D8
+:2086E00064FE00202DE9F04F0546287B0E46ADF1240D80460DF0C0FF071C30D06C694EB317
+:20870000414608220FF026F8031C27D03CB3A07893F800B0B3F802A097F80A90089011F024
+:20872000C1FA5FEA000819D008200FF0D6FE011C14D0FE2008704E70089B8B7081F803904A
+:2087400081F804B0A1F806A0D8F8040000780AF0A3FF03E0414604220EF0FCFF0CB9002057
+:2087600023E0A088ADF80A00E088ADF80C00207A8DF81800F8680590607B2E688DF81900CB
+:20878000306A4178007800EB0120801110F0030F00F0030208BF0422237801A803F0400105
+:2087A00003F020030097F4F7E7F909B0BDE8F08FF0B50F4629490978ADF1240D81422EDDDA
+:2087C0003FB9274938C96A4638C20AC96F4682E80A00244C04EBC00438682568666810F06C
+:2087E0008CF9A861786810F088F9E861B86810F084F9286238692B686861397B297473B9A0
+:2088000005A811F02AFC0021079405AA069116488DF814100CF020F92860286808B900206D
+:2088200019E0707800280CBF4FF4C0274FF4A0277168002908BF0D4D03D0002814BF0C4DE6
+:208840000C4D30780C4910F0E9FC30782F43394607F0D6FC204609B0F0BDC04657BF020091
+:20886000E8C10200C4C20200E9110100026000200240002002200020F10D02002DE9FE4F41
+:20888000DFF8C08098F8410200284FD0002501212C4698F8412201FA04F0104203D1641C66
+:2088A000032CF6D342E098F841221020A040104218BF0D1C11F08AFC98F841221121A140BC
+:2088C0008A4388F8412211F00BFEE0B210F0EEFF60B3877A57B390F9099019490768012D20
+:2088E000446851F82960019710D0017A02290DD100F1100191E8000C00274FF0805317EA3D
+:208900000B0703EA0A0108BF002901D105F0A8FE012D04D0009600224FF0006303E000228F
+:208920004FF00073009201984946A04798F8410220B108F58E70002111F066FCBDE8FE8F8F
+:208940009430044030F500202DE9F84F0646307810F06EFA002818BF022052D1142004F0A5
+:2089600079F9041C49D02A4841682160666044600025A5603227277301236373A373256193
+:208980003078002839D0F12837DA1F4866680460B168DFF87880C8798968182208F10A09DB
+:2089A0004B460DF01CFF012808BF0225B768D7F810B097F80CA018224B46594650460DF011
+:2089C0000EFF012808BF45F00105B968404600F13A08F879302243460DF001FF012808BF4C
+:2089E00045F0010530224346594650460DF0F7FE012808BF45F002057570002C0CBF102002
+:208A00000020BDE8F88FC04658FF0020A8B6020020050120F0B500240646ADF14C0D254670
+:208A2000ADF8001020460DF102010EF0CDFD0A2854D00D284FD00DF10D016846022210F0CA
+:208A400089F868B90DF139016846022210F082F830B90DF13D016846022210F07BF8B8B11D
+:208A60000C2011F019FC071C12D029460C2211F015FCBDF80000FF2108223880B81C11F074
+:208A80000DFCBD72384610F057FF384611F044FB0EB309A93046082210F05CF878B90DF176
+:208AA0002E013046082210F055F8A0B10DF1360768460222394610F04DF860B906E00BAFBF
+:208AC00068460222394610F045F820B938466946022210F0E3FD641C052CA3DB13B0F0BD5F
+:208AE000F8B5064614460D462C200FF0F6FC071C5AD000212C2205F029FF6220387000236D
+:208B00007B70BD802078B87160883881A07907F111010EF04EFFA08907F11C01420824BFF2
+:208B200001223A77820824BF01224A70C20824BF01228A70020924BF0122CA70420924BFD4
+:208B400001220A71820924BF01224A71C00924BF01208871207900F0070038732079C0F3DE
+:208B6000C00078732079C0F30010B873607900F00700F8736079C0103874E079217A00EB54
+:208B80000120F882607A3876E17AA07A00EB01207883A07BE17B00EB0120B884207C39465C
+:208BA000B862F0B20AF078FDF8BD70472F4870B534380468B4F1FF3F08BF00240FF0F6FFE8
+:208BC00004283CD10BF064FC142838DB28481C4E002510380560306C806C804719480068EE
+:208BE00020B1194800682046FDF786FA174818490560184C0A686FF35B4244EA020008606F
+:208C000015490868C0F30130012806D10A681348104040F400320A600860114D0124EC617D
+:208C20003068016A142088470E49086840F4E02008600D492C6008680028FCD170BDFEE772
+:208C4000B001001080012843800520438C210840482003400000390128000940EFFFFCFC4E
+:208C600000002443002009400C00684250130050940460422DE9FC410646022568468DF888
+:208C800001500FF0C1FC071C52D03869042260240270411C0C700124BC76BC7710F0CAFA9E
+:208CA00078622449F87E7E8038B908462F3890F82420531C80F82430FA76387E012806D126
+:208CC0000846007818B9387808B90020387638460DF10601FAF7B2FC5FEA000825D0242012
+:208CE00003F0B8FF061C1DD00021242205F02EFE502001A90EF0F0FFBDF8040070813573DA
+:208D00009DF8063035727888F3773080F481787DC6F8208008497073304602F0E7FA30460C
+:208D20000BF03AFF40460BF037FF38460BF034FFBDE8FC8113FB00208D5D02002DE9F04119
+:208D400011F0C0F84FF08058D8F8E8014068804711F0E8F8054605F00C000C283FD0E808BB
+:208D600022D20EF091FD234F3C680646012001460FF078FE39687143884215D21E4DF020B3
+:208D8000B0FBF4F0311A284611F05EFB284611F057FB00BF00BF0120F7F758FB00BF00BF12
+:208DA000284611F079FB20E000BF00BF280918D208F5EC74206880680146104888470428D0
+:208DC000F8D0690903D2002818BF002000D101200DF0E2F90A4801210160006803E000BFBC
+:208DE00000BF11F0DFF900BF00BF11F071F8BDE8F081C04640C402001C15002000400340FD
+:208E00002C2009402DE9F04115468046287A1F460E46012803D010460DF021F900E0288801
+:208E20004FF6FE71814221D0264C04210E3C14F80E2F904512D12A7A012A05D16378012B3C
+:208E400002D1638883420CD0012A07D063782BB96288824202D12279974202D0491EE6D10D
+:208E600004E0314620460FF0E3F910B9B420BDE8F081637927460025002B13D007F1060029
+:208E800010D0211D31F8022F964207D17A796D1C521EEDB2D2B27A7112B903E020F8022BBD
+:208EA0005B1EEFD10DB100F0D9FF0FB1787930B96588384610F00EFF28460BF06BF80020F5
+:208EC000BDE8F0816C010020F8B5071C0C4604D0387A022803D0032801D0E820F8BD384613
+:208EE00004F016F8FF2818BF1E2046D1387A054610F0C0FA01210246002001FA00F31A4292
+:208F000002D0401C0528F8DB052804D1022D14BF032D1A2031D0022D07D01A4A7B6808322D
+:208F200002EBC00253603B4610E03A8826128DF80020154D8DF802406B468DF803601212D9
+:208F40008DF8012005F1080202EB80021B680B4D0B4C13603B7A022B19BF2A1C1268221C9F
+:208F6000126801FA00F6022B42EA060214BF2A6022603A7A0BF0D0FF0020F8BDBC10012006
+:208F800098120120B810012094120120F0B505462E4C6878ADF1140DF32850D0DF284ED0ED
+:208FA000E8284CD0DB284AD02068D0F8FC1128468847071C42D1687C00283FD095F83400BC
+:208FC00000283BD12268B83210680078002835D1D2F87C2105F1120109209047061C2DD03C
+:208FE0002068D0F8302405F10B01E72090472068D0F8302405F10801502090472068D0F8B3
+:20900000302405F10A01E12090474FF6FF7202202368ADF80420A97A8DF80C00D3F8C07147
+:2090200000912B89304601A9B8470746F32F05D0DF2F03D0E82F18BFDB2F05D16F70206872
+:20904000D0F804122846884705B0F0BD140100202DE9F0412E4C2068E03081680D68002D7A
+:2090600054D001686A680968914206DAD0F86C0480472068D0F8E80005685DB10DF07AFA4A
+:209080006968884206D2083CA068D0F8D4048047BDE8F0812168D1F8E80000680AE0206880
+:2090A000D0F80015404688473846A8472168D1F8E800006850B34668002E0BD5D1F84C0596
+:2090C000804721682068D1F8E810D0F8E800096800684E68077B856880460DF04BFAB0424F
+:2090E000DDD22168E0318868006840B1096840680968814203DD0BF04FFFBDE8F08110F052
+:20910000DDF92168D1F8E81000200860BDE8F081140100202DE9F04F2E4C09AF94F80080C9
+:209120003E798B4692460546994600212C22ADF12C0D684605F00AFC2B7A032B8DF800302E
+:2091400004D013B12888ADF8020005E00DF102002946082210F09EF8687A8DF80A006B89A7
+:20916000ADF80C30B00824BF01208DF81C00700924BF01208DF81D00300924BF01208DF8D0
+:209180001E00B00924BF01208DF81F00F00924BF01208DF8200036F07F001CBF01208DF888
+:2091A0002100ADF816A08DF82280ADF82490A41C069439680A919BF800008DF814000FF0F2
+:2091C00057F922216A46082308F038F80BB0BDE8F08FC046800301202DE9F04705466988E7
+:2091E000686800273B463C468846064619E0B2787F1CE41CF61CFFB2A4B29AB916F8010B17
+:2092000031460DF06DFA641CA4B221188845B8BF002040DB361824181B1869886868A4B211
+:209220009BB24018B042E2D8012000EBC700C4B2E01880B211F030F85FEA00082AD06D6821
+:2092400008EB040688F8007027B3B94600276978287808EBC704AD1C641C00EB01202080ED
+:2092600015F8010BA070A07878B915F8010BE070E07829460DF034FA82460246294630462C
+:2092800010F00CFA554466605644B9F1010907F10107DCD14046BDE8F08770472DE9F041CE
+:2092A000244D0646287886423AD000283ED1224F3868D0F838038047002837D010F086FFB9
+:2092C0001E4C8046207818B13868D0F84C0580471B48007818B13868D0F84C0580471948F8
+:2092E000007800BB18480078E8B918480078D0B917480078B8B917480078A0B91648007813
+:2093000088B90DF003F92670404611F0E9F8012E05D0022E03D03868D0F84C0580472E70F0
+:209320000020BDE8F081404611F0DAF8E220BDE8F081C04604140120140100200B060120E0
+:209340006811012005140120071401200A1401200014012006140120081401202D4BB0B534
+:20936000144607460A4680384FF000014CD0C01F15D0294D001F32D00D382ED0001F29D02C
+:20938000401E19D0401E12D0812F41DBD82F3FDC184636383F1817F85D0C01460AE0104636
+:2093A0000EF0ACF9002833D01C22074627E01846143001782170B0BD284696224FF6FE7358
+:2093C000083030F8085BAB421CBF491CC9B2521EF7D1EFE70EF0CEFFDFE71846E9E72F46E0
+:2093E00096204FF6FE7337F8085FAB4203D08A4204D0491CC9B2401EF5D1B0BD082220460A
+:2094000039460FF047FFB0BD1846123000882080B0BDC0461AFB0020B40300202DE9FC4181
+:209420002D4C05466069002710B1804700284CD0002F4AD1E068226A690310F013FE0028E9
+:2094400041D40C2004F1300815FB00F026184044173001783036FE29AEBF0121491CC9B220
+:209460000170009840F0FF0061F31F2019496A46042301430091284639460AF0FFFB607062
+:2094800038B9A800FF2100EBC50040448175032444762846FF214FF0FF323B460EF090FB00
+:2094A0002846FF214FF0FF3201230EF089FB2846FF214FF0FF3202230EF082FB1020B08307
+:2094C000FF24347602E0012700E00B273846BDE8FC81C04600000F965CFC00202DE9B043D7
+:2094E000044610F073FE28498146621892F84A01401EC7B2002F82F84A713ED1264800EB87
+:2095000084000478408834F07F07804614D1E0090BD21E480068806901464046884740468F
+:2095200009F0BCFA0228FAD121E001EB8801D1F86011002088471AE04FF08055D5F8B80154
+:20954000006A014640468847D5F8B801806A014640468847D5F8B801006B0146404688476C
+:2095600001210B4A0B48116001688908FCD304F03F00152801DAFFF7B1FF484610F0B0FFB9
+:209580000020BDE8B083C04610150020B80100102820086028200840F0BC02002DE9F84380
+:2095A00005462C684FF0FF36E66210F00FFEDFF89CC094F830E08146BEF1040F09D1624629
+:2095C000177837B1224903204860086820F003000860204A204F63691168002090469F42FE
+:2095E00004D019B96246177807B10120BEF1040F4FF0000703D111B1624613780BB93843A5
+:2096000001D00DF0C3FE94F8320028B1484610F067FF3046BDE8F88394F83000042804D0DE
+:20962000404621460EF0AAFC03E0404621460EF0B8FC012084F83200484610F051FF02F078
+:20964000BDFC284609F08AFDBDE8F883050601200C8002406005012080A9030038B52B4C33
+:209660002068D0F8AC00007808B909F0C7FD00F05FFE2068D0F8B800007820B124480830B6
+:209680000168012088472348007810B91D48007818B12068D0F84C05804710F097FD1E49BC
+:2096A0000A78022A1FD10122174D0A706A78022A03D0032A18BF062A01D183220A7010F005
+:2096C0000FFF697831F0010018BF042902D1FEF781FB6978022903D0032918BF062904D14B
+:2096E0000EF0B4FE01E010F0FBFE2168B8310A68107828B1506918B1D1F8701210208847CF
+:2097000038BDC046071401204C02012014010020E0FF0020051401200A1401202DE9F041AF
+:2097200000248846061CADF1180D8DF8144014BFB8F1000F022049D008466A4605A905F012
+:2097400087F805464FF6FF70A84214D09DF8140060B19DF8100048B99DF81310052010224E
+:20976000334601F07F010CF06DFF2EE0274601E07F1CBFB20FB1B22028E0394605201022BF
+:20978000334608F085FF0928F2D102A8414608220FF080FD47F08007204601942946009051
+:2097A00014228DF810006B468DF8137004200CF049FF0849A80000EBC5000C224518214622
+:2097C000284605F0C3F801206872204606B0BDE8F081C04664FE00202DE9F04F09AF9B46C8
+:2097E00092468946ADF1240DBC8897F800800790242003F02FFA10260028009044D0002186
+:20980000242205F0A3F8484610F066FC002540B10079012818BF032803D1E00938BF44F4DC
+:209820008064E00A28BF01251949009809884181ADF818A080F81FB002230373079A0262BC
+:209840000372A0F800908DF80C8080F80D80F968ADF80A4006C904AB83E80600387A2946F5
+:209860008DF81A006846F5F757F8012809D1012D05D140460FF084FB08B105F0BDFA0026CA
+:2098800002E000980BF088F9304609B0BDE8F08F2CFB0020034630B50020ADF1140D01909A
+:2098A00002460292039298685C7E428001880492A1F60201C9B141F21E05491B15D041F692
+:2098C000E675491B012920D8417E012C62F38201417606D0018B21F47C7141F4347101836A
+:2098E00013E0018B62F30911F9E7417C012C62F38201417405D0018A21F47C7141F43471E7
+:2099000002E0018A62F3091101825A7604A902AA03AB009101A9FCF771FB50B10198008855
+:209920004FF6FF71814204D10298049906F046FA03E00298049905F09FFF044818300168C3
+:2099400009B10298884705B030BDC04630F50020F0B52C4E054630680127ADF13C0D0DA930
+:20996000D0F830248DF83470522090470024342268466C75214685F8204004F0E7FF2868A2
+:209980000090A888ADF80400A8798DF80600287A8DF80900687A8DF80A00A87A214600B1D7
+:2099A0003946E87A8DF80B10214600B13946287B8DF80C10214600B139468DF808400F20B8
+:2099C0008DF80740104B8DF8240043F6FF778DF80D101878ADF8267001280BD13068D0F836
+:2099E0003024291D502090473068D0F83024A91DE12090473068D0F82812684688472046B7
+:209A00000FB0F0BD14010020ADFE0020F8B52D4C06462068D0F828240D4669464F20904784
+:209A20002168D1F8D40090F85300D1F818148847234F04282DD02168D1F8D40090F85300C5
+:209A4000D1F818148847C0B9397806F10800400080B235B14FF47A7292FBF1F28018163044
+:209A600080B29DF80030676801229A407B681B78521E083312FB030018E03978F0006030C9
+:209A800080B2A5B14FF47A7292FBF1F2801898300CE03978700100F5867080B23DB14FF4E3
+:209AA0007A7292FBF1F2801800F5F67080B2122E8CBF28220C22801880B241438800F8BD97
+:209AC000D800002014010020F8B5064610F07EFB264D0746711991F84A01421C002881F8CA
+:209AE0004A213DD1224C04EB8604267806F03F00152801DAFFF7E8FF648836F07F0014D1C8
+:209B0000F0090BD21B4800684069014620468847204609F075FD0128FAD121E005EB840540
+:209B2000D5F86011012088471AE04FF08055D5F8B801C069014620468847D5F8B801406A8E
+:209B4000014620468847D5F8B801C06A0146204688470121084A0948116001688908FCD35E
+:209B6000384610F0BDFC0020F8BDC04610150020F0BC0200B80100102820086028200840D7
+:209B80002DE9FE4F0D4601900BF006FF174600284CD1019841688668254B002F4A683468BF
+:209BA0002448318C1A602C4401603ED04FF6FF7980464FF0D80B4FF0200A019808F0B8FCD0
+:209BC00038BB01980CF006FC18BBB94507D219EA040F04BF8DF800B04FF4803502D0B5685C
+:209BE0008DF800A0210C8DF80110200A8DF80200B8F8001001988DF803400FF064FF68469B
+:209C0000042109F0D3FA40B1B8F8001001980FF063FF4FF0FF30BDE8FE8FB8F800100198B5
+:209C20000FF05AFF64197F1BC7D10020BDE8FE8FA0130120A41301202A480168D1F8B020AB
+:209C4000D1F888031060D1F89C03D1F8B0205060D1F8A003D1F8B0209060D1F88002D1F886
+:209C6000B020D060D1F8A403D1F8B0201061D1F87C02D1F8B0205061D1F88402D1F8B020F1
+:209C80009061D1F8B0200020D061D1F8B030D1F88C231A62D1F8B020134B5062D1F8B0200A
+:209CA0009362124BD1F8B020D362D1F84824D1F8B4301A60D1F8A823D1F8B4305A60D1F864
+:209CC000AC23D1F8B4309A60D1F8B423D1F8B430DA60D1F8B023D1F8B4301A61D1F8AC103E
+:209CE000087070471401002081A1020059A202003EB52C4C94F84A10032903D0012918BF8E
+:209D000009294BD1417800293FD141886187811C53200BF081FC94F84A00092801D00EF0F4
+:209D20008FF80125422002A98DF808500BF074FC0420694684F84A004A200DF0CDFF04F160
+:209D40004000694610F028FA154801780B2905D0B4F8480000210AF045FC01E0062101704A
+:209D6000E08F4FF6FE71814203D069460022FCF7B7FB94F83200000938BF002502A95220B4
+:209D80008DF808500BF048FC06E0B4F848000AF029FC002084F84A000EF006FE3EBDC046C5
+:209DA00034FD0020E4FA00202DE9FE4F294E00900CAF0191301D097A3F8800689A469046E8
+:209DC0000F2903D1019A4FF6FC71118048F21F01B9421CBF4FF0000B012504D14FF0000BDA
+:209DE000022500F801BB814689F8008071785C46401C0AEBC10110F0CFF971780835EDB295
+:209E0000491CC9B2884505D1641C89F8004086F801B017E0641C71700A2CEADB0A24884501
+:209E200089F800400EDD1F2F01D10EF0CDFC48F21F00B84206D1084800784FF48041224631
+:209E400010F089F9009801993A462B4606F066FEBDE8FE8F98FD00203BFD00202B492948DF
+:209E60002DE9F84F491E077891F801800026344631E0254B142014FB00F909EB0305B5F88F
+:209E800002A095F801B00022514658460BF01EFC78B91D4810F8090040081AD358460122D9
+:209EA000FF230DF041FF1648164D2F7890F801800FE0287840080AD2687869880022FF230A
+:209EC0000DF032FF0E480F4D90F801802F78761CF6B2641CE4B2A742CBDC404680210AF0F1
+:209EE0003BFE20B94EB10CF0F1FEBDE8F88F26B903484078802108F013FABDE8F88FC04680
+:209F00004CFF0020F00C0120080D01204DFF00202DE9F04704462848B0F80090207D98465D
+:209F200015468A463830C0B20EF0D7FA08AF061C40D00120307021461C2206F11C000FF0EC
+:209F4000A9F9B01C51460A220FF0A4F9A6F80C902878307495F90200B0746878002370741B
+:209F60003878F362F0747868706186F818806089F081387A7076207D40B106F13800F062B0
+:209F80002169227D06F138000FF084F90B48727F816A807812F0030F09D021B930460EF08B
+:209FA00083FBBDE8F08730468847BDE8F087314609F072FBBDE8F0872CFB0020AC00012099
+:209FC000BCB5054669680C462078401F4AD0801E2CD0801E42D0401F02D0801E3AD0BCBDF5
+:209FE000481C01A90CF0C2FC093401283DD1502000238DF800002F7A8DF80230A7F109000C
+:20A000008DF8010068460BF0E4F8071C2DD0BDF80400788020783A7D87F838003869214656
+:20A020000FF038F93846F1F727FEBCBD6D890C200EF053FA071C18D006203870611C0822FF
+:20A040007D80381D0FF026F908480078394609F023FBBCBD28460DF06BFFBCBD28460DF000
+:20A06000FBFCBCBD2846FCF755FFBCBD3BFD002070B50646012E14BF01200320244C0121A1
+:20A0800004F10902607285200FF0BEFF41F288300DF0C0FF1F4D28784FF4807108F040F975
+:20A0A00028784FF4807106F039FF1B480078022804D14FF40050012100F0E2FE012E04D03C
+:20A0C00041F288300EF070FB70BD022603202670012305F15D01607004F11400637110F0F9
+:20A0E0005BF885F84A600CF009F80C4C0026A6700DF0FCF96078042108F012F96078042166
+:20A1000006F00CFF304684F83F60ECF761FF70BD34FD0020E4FA0020ADFE00204CFF0020B8
+:20A12000B0B5002405462022ADF1200D21462C72684604F00BFC0B22684629460FF0AAF8A5
+:20A14000E87A0A228DF80B00287B8DF80D4005F10E018DF80C000DF10E000FF09BF8AF7E0B
+:20A1600006220DF11A00214604F0F0FB780824BF01208DF81A00B80824BF01208DF81B00D2
+:20A18000F80824BF01208DF81C00380924BF01208DF81D00F80924BF01208DF81E0037F064
+:20A1A0007F001CBF01208DF81F00288B074FADF8180038688DF80D40D0F8F4128DF80C40A9
+:20A1C00068468847204608B0B0BDC04614010020B0B5294C04F124010878ADF1780D74220F
+:20A1E0006B46401C0870212000210FF0F5FB94F8240074216A468DF8000021200FF004FFCC
+:20A200001E4D28790027032805DA0AF0C9F9012808BF042000D00D200FF0C0F8618F4FF648
+:20A22000FE70884208BF0127B4F84810401C88421ED0F7B9012452201DA98DF874400BF09E
+:20A24000EBF9287903280DDA0AF0AAF9012809D1002068712046F6F719FC2979491C074612
+:20A26000297106E06C710020F6F710FC0021F6E7012738461EB0B0BDE4FA00204CFF002020
+:20A28000B0B50546294C297D012905D0152903D0252918BF35291FD1287E00091CD2226849
+:20A2A000D432106890F8820080B168781B280DD16068816A012088472068D0F82C134FF46F
+:20A2C00080608847002022686870D432D2F85C22697828469047B0BD287EC2091ED20129E1
+:20A2E00018BF152901D100090ED26F781B2F09D01FB920683430026802E0206834304268DE
+:20A30000895C04E0232100E03121206834302970006E0078294609F0BFF9B0BD2068006D11
+:20A32000016809B168788847B0BDC04614010020FEB50FF04BFF244CA16962698A4240D086
+:20A34000224A1778002F3CD1214A177837F07F0737D1204A1778002F33D1616110F0C0F871
+:20A3600060691D4E01907068416D20698847019F1A4D0090F90FB1EBD07F16D02868D0F872
+:20A38000D40090F8830001280FD00CF0BFF87068826D206939469047832803D02868D0F8A7
+:20A3A0004C0580470FF05AF8FEBD7068826D206939469047832806D02868D0F84C058047E2
+:20A3C000FEBD10F08DF8FEBD70000120071401200A14012000140120DCFF00201401002011
+:20A3E0002DE9F04704466188606800273B463D468846064615E0B61C16F8010B31460CF07C
+:20A400006FF9ED1CADB229188845B8BF00203DDB36182D181B18618860687F1CADB29BB2F1
+:20A42000FFB24018B042E6D8072017FB00F0401CC6B2F01880B20FF02FFF5FEA000824D0BA
+:20A440006568464488F80070FFB14FF000096978287808EB0904AD1C641C00EB0120208047
+:20A4600015F8010BA070A07829460CF039F982460246294630460FF011F909F1070955445D
+:20A48000C4F803607F1E5644E1D14046BDE8F0872DE9F04704466188606800273B463D469F
+:20A4A0008846064615E0B61C16F8010B31460CF017F9ED1CADB229188845B8BF00203DDBF9
+:20A4C00036182D181B18618860687F1CADB29BB2FFB24018B042E6D8072017FB00F0401C80
+:20A4E000C6B2F01880B20FF0D7FE5FEA000824D06568464488F80070FFB14FF00009697871
+:20A50000287808EB0904AD1C641C00EB0120208015F8010BA070A07829460CF0E1F8824659
+:20A520000246294630460FF0B9F809F107095544C4F803607F1E5644E1D14046BDE8F087F1
+:20A5400030B50C466168ADF1240D00294AD0A068002847D00A780270491C401C08220EF0C5
+:20A5600099FE60680178E9B9401C07A90EF05CF90028607038D1079840880021182201AB93
+:20A580000FF02AFA002860702ED10698A16808620598A168C861A068102201A909300EF0A6
+:20A5A00079FE21E0002501A80090A9B20022142304200BF03FF9607068B9606803A908222B
+:20A5C000401C0EF061F830B90298A16808620198A168C86102E06D1C032DE4DB032D03D1A9
+:20A5E000002000E00220607009B0012030BD7047F0B5294C06462078ADF11C0D032848D1E2
+:20A6000000256846182225700823657029460FF007FD684629460CF009FD20613A222946BB
+:20A6200004F1300004F092F904F13C00FF210A2204F08CF90CF03CFE3146284609F066FB0B
+:20A6400004F11801E0600FF012FD226AE169B1FBF2F0C0B284F830000428A4BF032084F8EE
+:20A660003000E070B2F5005F04D1E768B1EB403F00D317B9012020700CE084F83550FF20B5
+:20A6800084F833004FF40050E086EBF795FE607800E0607007B0F0BD5CFC002003B42DE96C
+:20A6A000F04F09AFD7F808A0BC69D7F814903D8ABE894FF6FF709846ADF12C0DBAF1000F63
+:20A6C000208009D0B8F1000F06D0B9F1000F03D016B1B5F5005F01DD04202DE0194638462B
+:20A6E00001AA04F0A9F9174F034607F110000068002B18BFD8B21FD102F050FCCDF81890D3
+:20A70000ADF81C60ADF81E508346CDF820A006A8009097F83300F98EADF8248001AA122307
+:20A72000F8F776F8C6B216B9BDF8080020803869594605F02DF830460BB0BDE8F04F02B0F7
+:20A740007047C0465CFC002030B5264C054694F82000ADF12C0D012841D10FF01BFA002828
+:20A760003DD1688800283AD11F4905A8122201F0BDF960784FF4805107F0D2FD284605A9EA
+:20A7800000F0E4F8BDF82000B0F5285F23D2174800680DF126016A4604F05AF80446032C9C
+:20A7A00011DA9DF8100010B1FD208DF81000214614226B4604200BF045FF0D4AA0000121CC
+:20A7C00000EBC400115400200FF0E2FB01200146EDF718FF03E0012002210BF0F7F90BB039
+:20A7E00030BDC0464CFF00205EC20200B80001206DFE0020F0B5294E05463068D0F8FC11A1
+:20A80000ADF1140D28468847041C3FD13068D0F82C1128468847041C38D1687C002835D0F8
+:20A8200095F8340090BB3268B8321068007868BBD2F87C2105F1120109209047071C25D0ED
+:20A840003068D0F8302405F10B01E72090473068D0F8302405F10801502090473068D0F80A
+:20A86000302405F10A01E12090474FF6FF7202203368ADF80420A97A8DF80C00D3F8C041EF
+:20A8800000912B89384601A9A04705E030686C70D0F844112846884705B0F0BD140100201A
+:20A8A0007CB50646284D96F8300003283FD196F83A0003283BD12C68D434216806F128006A
+:20A8C000082216310DF032FD78BBD4F85C2306F128014A20904774682B6861782078D3F851
+:20A8E000302400EB0120ADF80000694650209047A41C2B6861782078D3F8302400EB01206E
+:20A90000ADF8000069464B209047E41C2B6861782078D3F8302400EB0120ADF8000069461E
+:20A92000532090472C68002003E0EA2002E02C68E820D434216A48702A253570D4F86C1225
+:20A94000304688477CBDC0461401002080B5806910F8017B0F7043780278002F02EB0322A7
+:20A960004A8047D10A7910F8023F02F0F80203F0070313434F790B7103F0F702037803F04C
+:20A980000803134303F0EF020B7110F8013B03F0100313430B71037807F0070203F0F80371
+:20A9A000134303F0F8024B7110F8013B03F0070313434B7110F8012B8A7110F8012BCA71A7
+:20A9C00010F8012B0A7210F8012B4A7210F8012B8A7210F8012BCA7243780278871C02EB72
+:20A9E00003228A8117F8012B8A7317F8012BCA733878087480BD7047F8B5284E3468103454
+:20AA00006568287EFF2840D0D4F8C47097F88310022927D0AB7E7BB102280DD1D4F8F40427
+:20AA2000804771682C6949683A7909780546083112FB01F1084612E0D4F8F40480476D69D8
+:20AA4000E76AD4F8C43022682D1A93F82C10388977682D1A32F81140D7F8B40080472D1B59
+:20AA60002D1A10E0D4F8F40480476969D4F8C460E76A2568081A96F82C203989401A35F82F
+:20AA80001210A0EB0115002D01D50020F8BD4FF6FF70A842C8BFA8B2F8BDC04614010020AC
+:20AAA00070B5284C2068D0F8D4104D7B4069002141772068C16891F83000401C81F8300010
+:20AAC00020680C30016891F83010042931D06068C16B202088472368D3F8D41091F84F60DD
+:20AAE0000F2E0CD058694A7B807F824207DD4873D3F81415884723683546D3F8D4101A695A
+:20AB0000D86832F8154090F830200126550006FA05F24E7B4FF47075624305FA06F18C080B
+:20AB2000944238BF221CA1EB4201D3F8F024904770BDD0F8580180472068D0F86C018047EC
+:20AB400070BDC0461401002030B50546E889ADF11C0D213801281CD947F6DF71401A01289E
+:20AB600043D8284605F0EEFB041C3ED0207860B9608800218DF80010ADF80200211D01A863
+:20AB80000FF01EF96846FAF727FF20460AF004F82BE0287B48BBA96968460C460FF0FCFAC6
+:20ABA000083414F8010B8DF8080061782078A41C00EB0120ADF80A0014F8010B03288DF800
+:20ABC000140006D06178207800EB0120ADF80C0007E003A821460FF0DFFA14F8080F8DF8E4
+:20ABE000160028466946F6F713F807B030BDFEE7D0B50446607D164601220CF0EBFA071C72
+:20AC000044D0002E42D1E07D97F8351081423DD197F839103B7A0A18934211DD207EFF28A6
+:20AC200011D1FF20884087F8360087F8370097F83500401887F83500002687F8386007E0EC
+:20AC4000207EFF2818D087F83700207E87F836000FF04AFC04460FF00BF997F83A600C4B2C
+:20AC60004FF47A716043B0FBF1F03880012118787E8006F097FFD0BDB87E97F82A10FA8B72
+:20AC800033460AF033FF38460BF058FED0BDC046DC0401202DE9F047254EDFF898900025C8
+:20ACA00001244FF0020A4FF01108E8B20EF0FEFD071C38D0B87A012835D197F909001130D3
+:20ACC00004FA00F0C14346F8041C31680843306097F9090004FA00F0C0B20EF039F807F190
+:20ACE000100000210CF0FAFA0146812909D1B86918B100210CF0F2FA0146812908BF87F83E
+:20AD00000AA081290FD0A9F1040097F9091090F8412208FA01F1114380F84112002100F5A5
+:20AD20008E700FF071FA6D1C032DBED3BDE8F0870C10044034F500202DE9F84F04460AAF3C
+:20AD4000207DD4F810A03D689946934688463030C0B20DF0C2FB061C3ED01A203070A088F1
+:20AD60007080E0885946B080B01D0DF06DFDE078F07398F800003075207B70752878B07543
+:20AD80006878F07595F902003076387A7076F868F061387986F82000608BB08560897082A5
+:20ADA000A6F81090207DB084387C86F82E00B08C002804BF0020B06208D006F13000B062BA
+:20ADC000B28C514606F130000EF064FAD8F804000078314608F060FCBDE8F88F25482649FC
+:20ADE000EE381831C0F8CC1024491E39C0F8D01090F8CB1041F0010180F8CB1090F8CB2098
+:20AE0000012161F3410280F8CB2090F8CB2061F3820280F8CB2090F8CB2022F0080280F861
+:20AE2000CB2090F8CB2061F3041280F8CB2090F8CB30002262F3451380F8CB3090F8CB20AF
+:20AE400061F3861280F8CB2090F8CB2061F3C712052180F8DA1080F8DB100449C0F8DC1027
+:20AE60000349C0F8E01080F8CB207047B8100120941201203E1900206C11012022000120BC
+:20AE8000BCB5244A1278022A04BF234A1040234CB4F86C2000290CBF82430243D00BA4F881
+:20AEA0006C20C70308D001208DF80000694652200AF0B2FBB4F86C20900B07D2D00BC703A5
+:20AEC00004D0D00B28BF04F1580000D20020144D2978C8B1A76E1FB13A6803689A4218D06C
+:20AEE000A066006801280AD00846012107F018FAA16E28780A6801210FF02AF9BCBD08463C
+:20AF0000012106F04FFEBCBDA0660846012107F007FABCBDADFE0020C0CFFFFFECFB00200D
+:20AF2000E4FA002010B50446E089ADF1300DADF80200208AADF80400A07A8DF80F00A089EF
+:20AF4000ADF81000207802288DF80E000CD001280AD00F2808D0032809D10DF10600A11C33
+:20AF600008220EF097F902E06088ADF80600237D8DF81430627D8DF81520E17D8DF8161099
+:20AF8000237E8DF8173094F919208DF81820A17D8DF81910608AADF81200E369079394F8E2
+:20AFA00020208DF82020618CADF82C1094F82430E28C8DF82E30A16AADF8242068460A9150
+:20AFC000EFF750FF0CB010BD2DE9F84F0AAF3C7BBD683E79994690468A468346002C0EBFC3
+:20AFE0000220042000EB46008DF8010068460DF00BFB031C37D0A3F802B083F81A90A3F870
+:20B0000004A03878D876987F01280BD10EF04EFF9988884206D0B8F1000F06BF00209877BA
+:20B02000C3F824801969052001F8010BBCB1701C01F8010B66B13046891E2A7801F8022F07
+:20B0400035F8022B401E4FEA22224A70F5D1891C0EF02CFF01F8010B0EF028FF06120E70AD
+:20B060001846F0F709FEBDE8F88F7047DFF898C0F8B50B1C04464FF000050FD0DCF8987055
+:20B080002E466FB1F868007B00F00F00022803D03F68002FF6D103E03E4601E0DCF8986094
+:20B0A0006EB302B11660F168087B012500F00F00022824D1012B14D0098840F60300884282
+:20B0C00005D0401C88421CBF3069016901D130694169408B9CF842321922091813FB021132
+:20B0E00003E03169888DC9680918706B0CF090FD20600EF0BDFE2168B1FBF0F000E00020BA
+:20B1000020602846F8BDC04630F500202DE9F84F0E46074630684FEA9009224848452CBFF7
+:20B12000002503250FF052F800901F48D0F8BC1000F1B80AB94214BF00240124A10081F012
+:20B1400004015AF80180834627B107F1B8000EF039FDC8B9B8F1000F04D008F1B8000EF0D6
+:20B1600031FD88B93168A00000EBC40050448160317A01740EF07CFEB9FBF0F107F1B80026
+:20B180000EF0C6FA832507E09BF8DC0040F002008BF8DC00CBF8D87000980FF0A1F92846B8
+:20B1A000BDE8F88F40420F0030F50020D0B504461120ADF1180D01F04DFD071C3FD03B2002
+:20B1C000002111223B460EF007FC80BB387884422DD1112001F03EFD061C28D03A200021F8
+:20B1E000112233460EF0F8FBC8B93A2011213A460EF00AFF13490120087013484468B4F17D
+:20B20000004F84BF002444601122394668460EF041F8822018216A4605940EF0F5FE3046B2
+:20B220000021112203F092FB304609F0B5FC38460021112203F08AFB384609F0ADFC06B0FA
+:20B24000D0BDC04649FB002048040120264890B5503800688088ADF11C0D0EF03DFF071CBB
+:20B260003DD020480078012806D1787900F0EF00787140F00800787100248DF80C40788812
+:20B28000ADF8180003A807F029FE04AB38880193ADF800000EF00AFEADF80800787900EAF2
+:20B2A0005001890928BF01248DF80A408DF80B000EF070FC18B9684601F058FD02E0684681
+:20B2C00004F09CFC20B9787900F0FB00787106E004AC20460CF0ECFC204607F08BFB07B0CA
+:20B2E00090BDC046B8FE002094FD002030B50C4605463C220021ADF13C0D684603F026FBCA
+:20B300000A22684629460DF0C5FF6889ADF80A00287B8DF80C00687BE9898DF80D000DF16A
+:20B320000E000CF05BFB287C8DF81600687C8DF81700A87C8DF83700E87C8DF83800E87F86
+:20B34000ADF8280001F086FC099070B1296AEA7F0DF0A0FF4CB19DF828000999A04720B147
+:20B36000099809F019FC1A200BE007480068D0F88812684688470446099808B109F00CFCBE
+:20B3800020460FB030BDC04614010020F0B520480127F84201D008F0D5FA204D204F214E0E
+:20B3A000BD4206D203CD0478A4003459401CA047F6E71D48002800D08047164D164FBD422E
+:20B3C00002D210CDA047FAE7F0BD03251BE0416808300A1C2A400BD11A1C2A40AB4305D074
+:20B3E000046804300C600431043BF9D1131C05D0047801300C700131013BF9D1021C2A4016
+:20B4000001D0A84304300368002BE0D17047C046FFFFFFFF0000000000000000C0C90200B1
+:20B4200038CA020050C9020075F4021030B50C466068ADF1240D002841D002258DF814505B
+:20B440000188ADF80C10817B02298DF81E100DD001290BD00F2909D003290BD100F11001CB
+:20B4600008220DF116000DF015FF03E06068008AADF816001449BDF80C2060680988914223
+:20B480000FD100F10C010091027E817A012308460DF11601EEF7F2FF00280CBF281C00200E
+:20B4A0000EE0818900910DF116050195017E0291837A821C03A9212002F040FB00E002208B
+:20B4C000607009B0012030BD1EFB00202DE9F041204D6868416EADF1280D02A8884768684D
+:20B4E000C06B80471C4CA060217B21F00F0141F002012173029000260596668001208DF88E
+:20B500000C000EF063FE1849091D0968896980460220087069680F6D31468DE803000F48E3
+:20B520000F4B006802AA2146B847064640460EF0D7FF002E06D40B4991F90000AC60401C43
+:20B54000087004E0032041F2883105F0AFFD0AB0BDE8F081DCFF00205018002080000120EB
+:20B5600065E3010012050120140100202DE9F0470F4606460EF060FFEFF311898246202046
+:20B5800080F31188D6F80880474533D01D481E4B0068002F05D49C690125BD4004EBC7049A
+:20B5A00001E01C180025307D01281AD130460EF03FFF306C0EF038FF18B1F1685868884360
+:20B5C00058601869864204D0204631460EF028FF04E020685C6131460EF028FD58682843A6
+:20B5E0005860B760F5603464002F44BF002058610120188189F3118850460EF00DFF40468F
+:20B60000BDE8F0873CAB02000017002070B5064600210C22ADF1180D684603F097F9308882
+:20B6200001211F4C1F4DADF8000009208DF80400307A8DF80510012810D1212063788DF8CB
+:20B6400002006BB90EF0EAFD50B9716805F11C0008220DF01FFE3088288001E08DF80210CF
+:20B660006846F9F719FF9DF8140050B90398406C072101707168401C0EF08EFD684609F01D
+:20B680008BF9607850B90EF0C9FD38B905F11C000021082203F05AF90020288006B070BD42
+:20B6A000ACFE002070020120B0B504460125ADF1200D607927688DF8080020798DF80B501F
+:20B6C0008DF80A006FB338460DF0AEF948B338460DF11A010BF038F8BDF81A004FF6FE7157
+:20B6E000814214BF0027C827A07930B92FB9BDF81A1020688DF809501AE08DF81650BDF8D5
+:20B700001A008DF818706379ADF80C0021688DF817300DF10E000EF03FFD03A809F022FF15
+:20B720000DE000208DF809000DF084FD4FF6FD7101906846ADF8001001F050F80746384645
+:20B7400008B0B0BD7CB506462448006814460D4607236A4605EB46310EF08EFC9DF8000068
+:20B760009DF80010A58183109DF802209DF801009DF8045001F0030140EA012026749DF8C6
+:20B780000310E080891141EA82019DF80320237240EA03309206120D42EAA502E2819DF8C2
+:20B7A00005509DF80420A18041EA003102F00302920142EAA50262729DF806509DF8052028
+:20B7C0002160962DA57202F0030206BF42F00402101C42F00100E0727CBDC04668FC0020A6
+:20B7E0002DE9F04105462C686E680F460EF0EEFC94F8311019B91D490978012904D00EF08E
+:20B800006FFE0020BDE8F081012184F831104FF0000884F832800EF063FE07B9144F94F823
+:20B820003000012806D1786820B9B868002808BF454618D0387884F83000F868206278687F
+:20B84000E060B868A5602061B068010A04D00949814288BF011C00D80749616104F134007F
+:20B8600041460BF067FD2846BDE8F0810406012010C202000100000180A9030030B5054601
+:20B880002989ADF1240D0EF011FB884222D06868ADF8081005AA03900021AB2007F064FE4D
+:20B8A00005A807A9002202F0D3FF1A4827300078012808D19DF81C0028B900208DF81000CB
+:20B8C00002A8FFF7A3FE01208DF8100002A8FFF79DFE1DE000248DF804408DF805406868B2
+:20B8E00000900EF029FC18B1017909B1052906DB0EF0DCFA298888420AD1009403E040792F
+:20B90000000938BF01248DF806406846FFF7CCFE09B030BDACFE0020B0B5244C2068B83014
+:20B9200001680F781E4917B90F783FB909E00F7837F07F0702D11B490F7817B1D0F894045E
+:20B9400080470EF043FC6168174D09692A780978914207D116490978C90803D20EF0C0FD35
+:20B960000120B0BD0EF0BCFD0AF0D0FD0EF020F8012811D12D7808F09DFB18B96068006963
+:20B98000057009E06068006905702068D0F8D40090F942000DF04AFD0DF060FDB0BDC046A3
+:20B9A0000A14012000140120700001201401002006140120B0B5234C2068B83001680F78DE
+:20B9C0001E4917B90F783FB909E00F7837F07F0702D11D490F7817B1D0F8940480470EF0E7
+:20B9E000F5FB6168194D09692A780978914206D113490978C90802D20EF072FD19E00EF003
+:20BA00006FFD0AF083FD0DF0D3FF012811D12D7808F050FB18B960680069057009E0606856
+:20BA2000006905702068D0F8D40090F942000DF0FDFC0DF013FD0120B0BDC0460A14012063
+:20BA40000614012014010020001401207000012070B5254C216840310868006828B9D1F89E
+:20BA60000C0580472068006C006840681B4D007800F0200028710EF0A9FB19490646087891
+:20BA8000832826D12879D8B1216840310868006890F8780010B9D1F80C05804730460EF02A
+:20BAA0001FFD1048008842F20341401A0DD0401E18BFE9200AD101200BF0B2FD1B2005E0D7
+:20BAC0008520087030460EF00BFD002001F0ACFA70BD30460EF004FD70BDC0464C020120D2
+:20BAE0000A1401207218002014010020002A4AD05FEA000C8B071CD1830722D1102A08D37E
+:20BB000070B4103A78C978C0103AFBD270BC103238D0042A2CD3082A05D30C2A24BF08C990
+:20BB200008C008C908C008C908C092072AD0920F22E00B780370491C401C521E22D08B072A
+:20BB4000F7D1C30714D18307D8D0121F12D308C903801B0C4380001D121FF8D20AE008C915
+:20BB600003701B0A43701B0A83701B0AC370001D121FF4D2121D05D00B780370491C401C3B
+:20BB8000521EF9D1604670472DE9F047824624480D460024ADF1280D06786868ADF82040F0
+:20BBA000002808BF271C06D00746022208A839460DF074FDBF1CBDF82000001D80B28146A9
+:20BBC0000EF06AFB5FEA000826D0297800F8011B697800F8011BA97800F8011BE97801700A
+:20BBE0006D682DB1BDF82020401C39460DF056FD0120009001940290039404965146CDF80D
+:20BC000014902122CDF818800B230790F220F4F74FFB40460EF080FA0AB0BDE8F087C046FA
+:20BC20008103012098B5044620200CF056FC071C31D03420231D387093E80500391D81E89B
+:20BC4000050020688088B88121680C2207F10E00891DFFF74BFF2068007DB8766069F8611E
+:20BC6000F87A062805D10097B87E0CF001FCD72106E008280CD10097B87E0CF0F9FBD821E7
+:20BC80006A46082305F0DAFA38460CF00DFD12E038460CF009FD0948006860B121680A7D30
+:20BCA00001798A4204D1816811B12046884798BD00680028F4D1012098BDC046FCFD00204A
+:20BCC000F0B516460C460546ADF1240D08F004FF002840D12846002109F026FC314603F0AF
+:20BCE00087FB071C37D0B879400834D320460DF07DFA012819D0B979C8082CD30EF0D6F85F
+:20BD0000A0420BD1002000902146019005AA02900F2303902846FFF757F9B97988081AD255
+:20BD2000B87900F0FB00B87115E004208DF81000ADF8124004A802F043FE01280BD1002015
+:20BD400000900127214605AA01900F23029028460397FFF739F909B0F0BD2DE9F04180461D
+:20BD600014460E4620200CF0B8FB071C40D00021202202F0EBFD6420387000257D70BE803A
+:20BD80002078B8716088388120893882A07A00F00F00B87420793873E088F881E07AF874AE
+:20BDA000207C3876E07A400000F054FF786188B128460CE0616968006D1C415AFA69815264
+:20BDC0000EE0E2684100401C8A5A7B69CA52F97C8142F6DC207C400000F03CFFF86110B17F
+:20BDE000387EA842E6DC5FFA88F0394607F054FCBDE8F0812DE9F0410D46234998461746F3
+:20BE0000ADF1180D50BB00260C4601A810228DF8166004F12001FFF769FE05A82121202262
+:20BE20000DF116030090F22009F0D3FD9DF81600A8420BD101A8214610220CF08BFE28B967
+:20BE40004046214610220DF029FC18E0012D14D130466221424603F0B3FB10E001A810319A
+:20BE60001022FFF743FE042D18BF072D05D1404601A910220CF06EFE08B1002000E0384646
+:20BE800006B0BDE8F081C046CCB3020003B41046F0B51E1C05AFADF11C0D14BF00280420C9
+:20BEA00038D081B201AA384602F0C6FD1C4C074604F114000068002F2BD110B1804700B9D7
+:20BEC0000B2720692FBB01F069F805460020009094F83300E18E01AA0323F6F799FCC0B27D
+:20BEE00078B901A831460222F1F76CFB071C0CD1BDF8101049B19DF8140007F0A7FB67788E
+:20BF000003E00A280CBF0A2701272069294603F03FFCF8B207B0BDE8F04002B07047C0461D
+:20BF20005CFC00202DE9F84F8146002100200A46C9F800006846FFF799F8DFF87C800026E5
+:20BF40004FF0FF354FF0190A34460746E0B20DF0ADFCC8B1837ABBB1017A0126022917D077
+:20BF60004246516892F8423240694A8B0969891813FB0A110BF04CFE83460DF079FFBBFB8F
+:20BF8000F0F0854288BF051C641C032CDED300E000251FB1012E04D0012F05D0012E04D052
+:20BFA00005E00098854200D9009DC9F800503E43F0B2BDE8F88FC04630F500202DE9F041D5
+:20BFC0000EF004F9204C80462078002650B11F480322083801688260480803D30AF0E6FD5B
+:20BFE0000BF0D4F9164D2868071C0ED008F094FEB86A796A884207D8284639460BF0E4FF82
+:20C000003046012687F832002868217801290ED050B90F480DF0FEFE48B90A4A4FF0FF3085
+:20C02000012105F057FB02E080680DF09FF940460EF056FA16B1B86809F028F9BDE8F0814D
+:20C040006005012080A903000506012010800240081201202DE9FE4F814623480D46904637
+:20C060001C4600210422083083460EF017F91D480768AFB14FF00C0A7868007881450CD184
+:20C080000CF0E0FF48B1037C3BB146692EB1002001E0401CC0B2834205DC3F68002FEBD1CC
+:20C0A0000020BDE8FE8F10FB0AF1725A9542F0D189198A889045ECD122808879A070C97989
+:20C0C000E17001F03DF85B462946ADF8040001A80090484609F07DFCC4F804B00120BDE8C1
+:20C0E000FE8FC04624050120F00C01209EB5477E37F07F0743D0017D012903D0032918BFF0
+:20C1000004293CD11E4C2168D1F89810098901F0020201F00801114331D041684878C0F38F
+:20C12000810002288DF8080006D003280ED1491D68460EF031F809E08A79487940EA0220B3
+:20C14000ADF800000879C97841EA00216068426F684690471E2809D040B16068006D804722
+:20C16000FF280CD16068416D012007E06068006D8047FE2803D16068416D002088479EBD87
+:20C1800014010020F0B51F4D1D4C002124220823ADF1240D6846A5620EF092F9002604F136
+:20C1A0004C07384631466A468DF818600EF084F93C2208232763314604F1680738460EF0A5
+:20C1C00067F94FF44060C4F888000521A5673A46334604F1800004F1A405016074300A4942
+:20C1E000C4F8840028460EF04FF90848E56208490160084981600849C16009B0F0BDC046F2
+:20C20000D4DB00201CE9002065E401000C01002084BC0200F0A4020000B302008B4208BF92
+:20C22000824204D90B1C021C002100207047002B08BF002A0BD10B1C021C00210020002B77
+:20C2400008BF002A1CBFC943C043FDF726B8F0B51C4615460B46024600200021B4FA84F6CD
+:20C26000202E04BFB5FA85F62036B3FA83F7202F04BFB2FA82F72037F61BB6F1200727BFB3
+:20C2800005FA07F400257F42B4403EBF25FA07F73C43B540A34208BFAA4201D3521BA3417F
+:20C2A000404149416D0845EAC4756408761EF1D5F0BD704730B501250446ADF11C0D8DF8CB
+:20C2C0001450F9F705FB206918B11E48016820468847207D50BB684600210C2202F036FBEC
+:20C2E000A0688DF802500088E368ADF80000187D8DF8055009308DF804006846F9F7CCF854
+:20C300009DF8140090B90398456C0E232B70A1684968681C0DF040FFE2681169127D05F150
+:20C3200009000CF0B7FF684608F036FBE06808B108F032FC20460DF08BFE9DF8140007B0F8
+:20C34000207530BD780201202DE9FC47224D81466D1E95F83340E8784FF0FF08002642F2A6
+:20C36000010A0AE0204678210AF048FBE878641C94FBF0F14143641AE4B2B04228DD95F820
+:20C380003200761CA042B6B2F0D0E86861036A4604230DF071FE009800F0FF007828E5D0FC
+:20C3A00005F13007FF2818BF7E2803D120467C210AF024FBA00085F8334000EBC400C019A4
+:20C3C000818BE986808B48448245CBDD95F833804046BDE8FC87C0465DFC00202DE9FE4F0C
+:20C3E0000CAF3E793C888DF800001D4693468A4606F10A00C0B20190401C00F02BFC5FEAB6
+:20C4000000092ED009F101008046594688F800A0401C0CF033FF00F8015B291200F8011B68
+:20C4200000F8014B231200F8013B067026B1B968401C32460CF02EFF0C4C0B49C4F80480F8
+:20C44000E51C48F23802387B019B2870684604F065FB484608F0A0FB05F10A066660002071
+:20C46000E070BDE8FE8FC0460801012098FD00202DE9F0411D4F7868C068012101701C49A2
+:20C480006FF0010008701B480068C06B80471A4C054621786068A2688B002E1AB6FBF3F084
+:20C4A0005843361A8800154902FB03F8B1FBF0F0904203D23868D0F84C058047AD1B1048E0
+:20C4C000656008EB0501F8F7D1FE3868D0F8E40480470DF07BFE0EF003F80BF003FF79687C
+:20C4E000C96800200870BDE8F081C046140100200C050120E0FF0020D8000020FFF6C2FF43
+:20C5000071C40100F0B50546214804782878ADF1240D0BF0BFFF002835D11E48052147687F
+:20C520006FBB1A4A4CCA05A981E84C00047029784560AA688DF800105088ADF802009088FC
+:20C54000ADF80400907900F00F008DF80600D0798DF8070090680290107B8DF814100027E5
+:20C560008DF80C0008238DF81C7020211069CDF818D005AA0490204604F060FE03E0491E42
+:20C5800000F10800CBD109B0F0BDC04604B602007CFB002000FE002070B50E4610F8011B8C
+:20C5A000317042780178801C01EB0221718001784278851C01EB0221B18015F8010B0011CD
+:20C5C000B07115F8014BF4718CB1600000F042FBB06048B35CB1014620466B782A78401E0A
+:20C5E00005F1020502EB032221F8022BF5D12C783473CCB1600000F02DFB306130B9B0684E
+:20C6000090B108F0C9FA0020B06070BD64B101466D1C20466B782A78401E05F1020502EBA9
+:20C62000032221F8022BF5D170BD70B50C4621780646ADF1180D01F00C0531F07F0018BF04
+:20C6400045F0800501F0030045F00205012808BF45F01005880928BF45F020050C22684608
+:20C66000002102F073F98DF80250ADF8006060788DF80300012568468DF80550F8F70CFF57
+:20C680009DF81400C0B903984576A17880F83A10E17880F83B10E188C1872189A0F84010E8
+:20C6A000617D80F84910217E80F84C10E17D80F84B10684608F070F906B070BDFEB50C4630
+:20C6C00001A90BF061F900283DD11F4D0C3DE868002838D0871F00210320BDF8042037F8FE
+:20C6E000063F9A4204D0401E01F10101F5D1FEBD7980182000F0AEFA061C24D000967988FC
+:20C7000006200022182309F095F83046214610220CF0C0FD00247461346179880620182259
+:20C72000334609F08FFF30461822214602F00EF9304608F031FA79883435880000EBC100B2
+:20C740002C5040194460FEBD60FE002038B5224C083CE068D0F8880080470DF037FD0546AD
+:20C76000E068C06D8047E068416AA068D0F8D40090F942008847E068816CA068D0F8AC009B
+:20C7800000788847E068016EA068D0F8D400C08C8847E068A368416ED3F8D400408D88479F
+:20C7A000E068A368816ED3F8D4004430884728460DF096FEE068A568016BD5F8D40090F86C
+:20C7C00043008847A268D2F8D410D2F8302452202931904738BDC0461401002098B5044607
+:20C7E00002208DF8010068460BF00EFF071C3BD038690422411C027000200870227A012AB8
+:20C8000004BF40F020000870607A012803D1087840F040000870A07A01281CBF0123BB76DB
+:20C8200004D10878012340F080000870607A012804D1606808B17B7760683862E07A012827
+:20C8400008BFFB82208808F047F918B1F88A40F00400F882BB770CF0EDFC7862208878802A
+:20C860003846EFF709FA98BD102098BD2DE9FE4F0190214800F198063768994692460D46E2
+:20C880000024804600E03F6897B3BD42FBD1D7F800B0019839460DF0D5F918B33846002245
+:20C8A0004FF0805308F022FE06F10800B9F1000F00900ED0384600224FF0807308F016FE4A
+:20C8C000286998F8DC30C8F8D80043F0010088F8DC00304639460BF077FB009839460BF08F
+:20C8E0004DFB641CBAF1000F18BF5FEA0B07CED12046BDE8FE8FC04630F50020F8B51546FA
+:20C900000C460DF063FC84461E491D488326A4B1641E2CD0641E22D0A41E19D0641E15D1D0
+:20C9200010300768002F0CBF0021F96829604768002F0CBF0021F9680FE00768002F08BFC4
+:20C94000802617D0D1F8A800018E12E0032611E0D1F8B8002860D1F8BC1069600AE0843831
+:20C9600000780021022808BF0121297002E006480178298060460DF0B3FD3046F8BDC0469C
+:20C98000D8F5002030F5002070F70020B0B50024ADF1180D009403F0D5FC071C37D007F019
+:20C9A000D5FA1C48798800780BF0D2F90D46009050B3007B802827DD387810BBADF8065082
+:20C9C00004208DF80400391D02A80DF0F9F901A8F9F702F880B9104D402168782C7005F0C0
+:20C9E0009FFC0BF013FC68784FF4804105F098FC0C200DF067F90AE0798801206A46F6F7F3
+:20CA0000F7FA0098FF210173384608F0C5F806B0B0BDC046E80201204CFF0020F0B5054637
+:20CA2000ADF1340D0DF0D2FB1F4C074608342068D0F8080100686968836B102209A8984717
+:20CA4000061C28D12068D0F808010068016968468847AE682B8B019609A80693EA68009084
+:20CA6000A98B02926E8B0392731A07936B698DF82110701A0493801805900D2325688DF81F
+:20CA80002030D5F80811D5F80401096800688A6969469047064638460DF022FD002E14BF55
+:20CAA000E42000200DB0F0BD0C01002010B5044600213822ADF1900D68460DF0EFFB2046FB
+:20CAC0006946F2F7A1FB009841090DD2C0F3411000282FD06846EDF74DFF17480078C008B9
+:20CAE00028D306F07BFF25E010F0070F0CD000F0070002280DD102208DF8380002A9082221
+:20CB00000FA80CF0CBFD04E000208DF83800019C0F940EA80DF1460111AA03F017F948B9DF
+:20CB20000DF146000BF0CBFFBDF844000DF1460106F07CFC24B010BD220401201CB51E4B1E
+:20CB400003F1D4042078012202F0010120F001000143217093F8D40062F3820083F8D400EF
+:20CB600093F8D40062F3041083F8D40093F8D40062F3861083F8D40010480068406903F1A8
+:20CB8000D401027042F20200ADF8000009880DF10200018003F1D601097801A80170B3F850
+:20CBA000BE00022806D107480068054C426A2068694690471CBDC046501800201801002054
+:20CBC00080000120E0FF00202DE9F84304460420904689468DF8010068460BF015FD1C4DA7
+:20CBE000071C2ED03869072100F8011B217D00F8011BA18A091200F8011BA17D0170012675
+:20CC00007E7704F10B033B62BE770CF013FB7862B9F1030FBE7604D0B9F1010F18BF4020B1
+:20CC200001D14FF48860F8822C46201D0088B8F1010F788004BF002038763846EFF71CF88C
+:20CC400000E010204FF6FE71A980BDE8F883C046ECFB0020F8B5041D14F003001CBF241ACC
+:20CC6000241D0BF067FA1D4A054697685560112C28BFD768386800231E46010821D226B94C
+:20CC8000844209D93B4601261EE0196809188C42196019D81F460846DFB11169001B032869
+:20CCA00007D83868091A1161386840F00040386005E0385144F000403860091B11613F1D4C
+:20CCC00007E080F0004000263F1838680028D4D1002728460CF011FD3846F8BD501A002077
+:20CCE0002DE9F04114460D4680461E1CADF1280D08BF022034D03768EFB90C20FFF7AAFF6E
+:20CD0000071C14D068460021242208230DF0A4FB0023069741466A4605931348ADF8103061
+:20CD20000DF096FB38607D60BC60386808B9082016E037600CE00BF0FDF9044638680DF0FA
+:20CD40009DFA10B138680DF0A7FB20460CF0D5FC386841460DF078FB38680DF071FB002049
+:20CD60000AB0BDE8F081C0460D9F020030B50188ADF11C0DADF802100024ADF80040416891
+:20CD8000C27A019132F07F010AD1D10905D3807A012814BF0320201C0BE00125284609E0D9
+:20CDA000D10905D3807A012814BF0720042000E0052001258DF80800214603AAAB2006F0F3
+:20CDC000D3FB03A805A9224601F042FD09480078012807D19DF8140020B98DF809406846CC
+:20CDE00002F06FF98DF80950684602F06AF907B030BDC046D3FE0020F0B50546ADF1340D8E
+:20CE00000DF0E4F91E4C074608342068D0F8080100686968836B102209A89847061C26D1EA
+:20CE20002068D0F808010068016968468847AE6801962B8B0693698B0791EA68029209A82B
+:20CE400003926E6900900D230496297F8DF820302A698DF8211026680592D6F80811D6F86C
+:20CE60000401096800684A6969469047064638460DF036FB002E14BFE42000200DB0F0BD14
+:20CE80000C01002070B51E4C2068D0F85C0280471C490B781C490D7818B91C2000F0C4F8D6
+:20CEA00070BD0021194E2268A6F8AA10D2F8D42092F8314086F8AC4092F8242086F8AD209F
+:20CEC00096F8AE2042F0200286F8AE2096F8AE206843800022F01F0242F0020286F8AE201A
+:20CEE00096F8AE20C6F8B80061F3871286F8AE2086F8B03086F8AF1086F8B11070BDC0461A
+:20CF0000140100204E020120D8000020501800202DE9FF47067A022E1CBF804608240DD134
+:20CF200000880F128DF80A100DF108088DF8080004248DF80B7000128DF80900DFF854908B
+:20CF4000154F00254FF0010A30460CF093FA0AFA05F1014216D0022E19BF09F1080101EBE5
+:20CF6000C50107F1080101EB850122466846FEF7BDFD4046694622460BF086FB012808BFAA
+:20CF8000281C03D06D1C052DDEDBFF200090BDE8FF87C046B8100120941201202DE9F0432D
+:20CFA000054620480068ADF1140D05EB00090DF07FFA071C16D00DF063F906460DF03CFA47
+:20CFC00080466868012807D100246C60EF604046AE600DF021FA21E0E868874204D140465A
+:20CFE0000DF01AFA01201AE038460CF0C8FB02970024C7F818D0484669463246039409F01F
+:20D000006BFCE8680DF03CF9B04203DAE8683146FEF7ACFA40460DF0FFF9BC61204605B043
+:20D02000BDE8F0831CC40200B0B5074600251D481D4C05701E4805704FB92068006C00689D
+:20D04000C08AC00803D20DF04FFA184908602268AC32D168087808B1496C61B91068007841
+:20D0600008B906F0CBF8FDF763F92068D0F87012384688470BE0384688476068C068007827
+:20D0800028B92068D0F858242846014690472068006C006810B1007D352801D00CF0DEF9BC
+:20D0A000B0BDC046FC13012014010020E40501200A1401202DE9F04F1D4682462878032408
+:20D0C00009AF91468B46ADF1240D10FB04F006460DF0E2F85FEA00082FD0014600200EE05A
+:20D0E00010FB04F2AB185B780B70AB189B78AA184B705288401CC0B212128A70C91C2A787E
+:20D100008242EDDC012A02D1687800B90126002100913878019001250295039139794A463E
+:20D120000491042305965046CDF8188059460795F3F7BEF840460CF0EFFF09B0BDE8F08F7D
+:20D140003A280CDC182817DA083834D0401E30D0401E38D0401E2AD0401F2CD021E0E03880
+:20D16000022824D90838012823D9801E1FD0801F1BD0401E17D014E01838DFE800F01C1A96
+:20D180002418121212121C1A241822201E161C1A241822201E161C1A1212121212121A1867
+:20D1A00016C00020704710207047082070470420704702207047012070470720704706206C
+:20D1C0007047052070470320704770472DE9FF411D4D1F4F1D4C33264FF001082B79002B24
+:20D1E0002AD0032B28DAE9692269F1B982B13868022B4FEA8011A1EB800107D12888904748
+:20D20000012805D161692888884701E0288890478DF800806888ADF80C00684605F05EFEB9
+:20D2200050B101A805F0E6FB06E0A86910F1020F02D0E869401EE861761E05F12405CDD14A
+:20D240000090BDE8FF81C046E40D0020ECFB00206CBC0200F8B51C4ED6F860010168012001
+:20D26000884701282ED0D6F82401184DC4683C21012200232846A047002808BF002022D03B
+:20D280002F8817F0010704D14FF00120C5F80404288830688047012F04BF4FF08070C5F8E0
+:20D2A00004040D4A0A480B4F936901681069D161A0EB9000C91A07FB01F3190C814228BF90
+:20D2C000081C10610120F8BD8000001000A00C403020094040420F009402012003B40021AE
+:20D2E000F0B505AF3846ADF11C0D01AA01F0A4FB1B4C054604F1140000682DB910B18047C4
+:20D3000000B90B2520690DB1E8B224E0FFF746FE002506460095E18E94F8330001AA032300
+:20D32000F5F776FAC7B28FB99DF81400BDF8101006F08CF9009594F83300E18E01AA032343
+:20D34000F5F766FA0A2814BF012767782069314602F01EFA384607B0BDE8F04002B07047F8
+:20D360005CFC002030B5204D45EA0401ADF11C0DC1F315040021019102910391049104A9FF
+:20D380000091806802AA03AB01A9F8F737FE0146019802884FF6FF7090421DD101B30398BF
+:20D3A00008B1049840B9D9B102982B2105AA0BF0B3FCFF2806D113E02B2105AA0BF0ACFCC7
+:20D3C000FF280DD0C4F38850059C80056FF39F54044344F0004403E0A805204042EA000460
+:20D3E000204607B030BDC046FFFF3F00F8B51F4CA0F5C060D4F81011C4F82C010029B8BF9D
+:20D4000049420028B8BF404281422BDA4FF08057D7F8A401B4F81411154D40684FF47F422F
+:20D4200008230646009128463021B047D7F8A401B4F8181140684FF4F802122306460091EE
+:20D4400004212846B047D7F8A401B4F8281140684FF440620A230646009120212846B047AC
+:20D46000012000E0002084F83001F8BD1015002000A00C407CB5204C3C3CE06B00680146E9
+:20D48000042088471B4D02281AD0032818D001282FD12068406803214FF040521C23064631
+:20D4A000009128460021B0472068406801214FF4007209230446009128460021A0477CBD98
+:20D4C0002068406803214FF040521C230646009128460021B0472068406801214FF400727E
+:20D4E00009230446009128460021A047022009F0E5FA7CBD00A00C40E0010010B0B50546EF
+:20D500001E484268184C9269217817783FBB174B8A00B3FBF2F2AA4204D20068D0F84C05B9
+:20D5200080472178164B042011FB00F001B2181D00686768C06B05FB01748047211AA1F5B3
+:20D540004871090806D30A4A011B891A090828BF00F5487407482146F7F788FEB0BD064986
+:20D5600001200870B0BDC046D8000020FFF6C2FF00093D0071C40100081401201401002003
+:20D58000DCFF00207FB51F4C4FF47000E0600025A560656065701C4805700AF0CBFD064653
+:20D5A000206940B10CF00EFB10B120690CF006FE20690CF057FC68460CF04FFD8DF80050FF
+:20D5C0000E48019501216A4607F046FA0C4D206120B92868D0F84C05804720690CF0ECFDC5
+:20D5E00030460CF08AF82868D0F814150F208847E06800F077FE00907FBDC0468D6D02003D
+:20D6000014010020D8000020081401201B49B0B509684BF2F52250430027040A01F44021F4
+:20D62000B1F5802F03D116480068800C00D38FB14FF08055D5F8EC010068804707F06CFA02
+:20D64000D5F8E011C96888472111C01000B2484304EBE0340B48007830B90B48006820F04B
+:20D660007F402418640802E0084880F8407108480460210C416001278760B0BDB44F005097
+:20D680008C1300505016002010200940101500207C600C4010B58B4201D1824233D052EAC8
+:20D6A000000404D143EA01046400002C2BD052EA430401D18C4226E05C006415641C07D17E
+:20D6C0004C006415641C03D1CC0FB4EBD3741AE000290CD4002B16D48B4214D192EA000426
+:20D6E00001D482420FE000280DD101240BE0002B09DC994207D192EA000401D4904202E0C0
+:20D70000002A00D10124EFF3008454BF44F0005424F0005484F3008810BDF8B506AF3E789C
+:20D7200094468E46002E3AD0002735461B1F4FF6FF713C4633F8042F91422BD017B13F8835
+:20D74000B84201DD824205DC6D1E1F4604F10104F0D1F8BDA6421A4608DD361B121F32F813
+:20D76000044FA14202D0761EF9D1121D934203D2D11AC91C8F1000E0012732F8041C12F89F
+:20D78000026C118012F8015C96707F1ED570A2F10402F2D1188083F802C083F803E0F8BDF7
+:20D7A0001E4830B5ADF1140D94386A461430054604F0C4FB002404218DF8044020468DF8A4
+:20D7C00006400AF099F9332807DA0AF081F920B901208DF804008DF80600684603F0FCFC20
+:20D7E0004520294607F018FF9DF8060010B99DF8040000B101248DF8134009499DF8132082
+:20D80000091F08784978104001408DF8131041200DF1130107F000FF05B030BD78FB0020C8
+:20D820003804012003B41046F0B51E1C05AFADF11C0D14BF002804202FD081B201AA3846AA
+:20D8400001F0FAF8174C074604F1140000681FBB10B1804700B90B272069EFB9FFF79EFBB7
+:20D8600005460020009094F83300E18E01AA0323F4F7CEFFC0B250B10A2806D101A831465A
+:20D880000122EFF79FFE071C02D0012700E00D272069294601F07CFFF8B207B0BDE8F04017
+:20D8A00002B070475CFC00202DE9F0411D4C804620684FF0FF310CF02AF9D8F808601A4D5C
+:20D8C000D8F80470144A308C7369796828601160B3B9124A318B89180A78521ED3B20A701E
+:20D8E00073B9404604F024FE404609F041FE78680CF0D1FB0022318B094B286843F82120BC
+:20D9000081B24046F1F7A3FB0020387020680CF073FCBDE8F081C046A0130120D813012011
+:20D9200044130120A8130120A4130120F8B505460CF04CFC1D4C064604F1DC010878A8438D
+:20D9400004F1B80508702868002808BF002706D02868B8300CF036F9002700B101276868AE
+:20D9600038B1B8300CF02EF90025384318BF01252F4694F8DC00A0B9012F12D0D4F8D8002A
+:20D9800078B1816A89080CD3456A30460CF0A8FDD4F8D80002210022A8470020C4F8D800B1
+:20D9A000F8BD30460CF09CFDF8BDC04630F50020F8B507460024081C08BF0124002302B99B
+:20D9C0000123002F33D01AB197F84460002E2ED080B190F844606EB17D6B016CAD08A5EBB1
+:20D9E000910539460CF00FFA2D1AB5F1704F04DB002D02DC012C01D019E00124BAB1D068B8
+:20DA0000007B00F00F00022811D1516B386C8D081146A5EB900538460CF0F5F901262D1A39
+:20DA2000B5F1704F02DB002DD8BF002633431C40E0B2F8BD70B53A2000211122ADF1280DFB
+:20DA400001AB0BF0C9FF1A4D10B9A81C006806908220182101AA0CF0D7FA164E002407A8DB
+:20DA60000090214600220C23072007F0E3FE06F15D0008A908220AF007FE48B9641C052C7F
+:20DA8000EDDB08A8FF21082200F060FF641EA4B2069821460C2207AB0790072008F0D2FD33
+:20DAA000002101A81822298000F050FF0AB070BD4A040120E4FA00208CB501468A695078E3
+:20DAC000137803EB00231A480088984214BF0027184F1948006857B948F203000090087C5B
+:20DAE0000190487C8022891C09F092FC8CBD002200F8012B00F8013B1A1200F8012B3A684E
+:20DB000002F0F00302F00F021A4300F8012B3A68120A02F0F00302F00F021A4305230270FF
+:20DB200001F1110048F20302891C02F0F7FF8CBD50FD0020E01201209CFD00202DE9F84F37
+:20DB400099461E4B82460AAF98467C6858683E88237A8B46032B04D0012B0CBF0E250C25E9
+:20DB600000E0152511460CF017FB00F8019B00F8016B311200F8011B217A00F8011B217A8D
+:20DB8000032907D001290AD1217800F8011B2188091203E021460CF0FFFA397A0170102079
+:20DBA00088F80300524659462B46404602F0B6FF002188F80310BDE8F88FC04698FD002072
+:20DBC0002DE9F04100250446ADF1180D009506F0BDF91A48006840684078400828D3A26913
+:20DBE0009178507800EB012081B21079ADF808100AF0AEF88846071C00901BD00AF006FBC8
+:20DC00000F49A0690E46001DFEF7C6FC388804A90AF0A1F918B900980661284600E001203B
+:20DC200041466A46F5F7E4F90098007BFF2801D10AF0ECFA06B0BDE8F081C0465CFF0020AB
+:20DC4000E8020120BCB51D4D686A50B307460124032085F822400BF0A1FBB87908F038FBA2
+:20DC6000F87A00903988BA783B8907F10C00F9F7A7FA70B913480078000904D210480078AB
+:20DC8000D8B9082001E04FF400402146FDF7F8F8BCBD686A8DF8044008F068FB214601AB9A
+:20DCA00007E00020012185F822000DF105038DF805000A46032006F01DFDBCBD4CFF0020A5
+:20DCC00035FD0020E61201202DE9FC4180461E4808AF1B4CADF804100C303E7ABDF80410C6
+:20DCE000057846B93034302634F8020F81420AD0761EF9D10EE0182034F8026FB14202D02E
+:20DD0000401EF9D106E010461946012201AB08F066FD10B9B120BDE8FC81387950B1094857
+:20DD200004683CB101A8009039682A4601234046A04710B10020BDE8FC81B220BDE8FC81B8
+:20DD4000B0B6020000030120DC02012070B506467568B46895F8F900012816D094F8380075
+:20DD6000A16A09F0F1FE94F83900E16A09F0ECFE94F83A00216B09F0E7FE95F8FB00FF28DE
+:20DD800023D0616B09F0E0FE70BD94F83800E16A09F0DAFE94F83900A16A09F0D5FE94F8B8
+:20DDA0003A00216B09F0D0FE95F8FB00FF280CD0616B09F0C9FE95F8FB0004490BF02EFAC7
+:20DDC00095F8FB0031460BF00DFF70BD1D040200B0B507461A4C1B4D207818B12868D0F8B4
+:20DDE0004C0580472868D4300168194BCA8C991C0A800FB3032F1BD0052F06D0012F04D028
+:20DE0000022F02D0D0F87804804702202070FCF7E5FF2868D0F8D4104FF6FF72CA84D0F863
+:20DE2000D400094FC18C094C3980C08C2080B0BDFCF7D4FF032000E001202070B0BDC04615
+:20DE40006811012014010020220001203E19002070000120F8B51F4C2068D0F8E800002533
+:20DE600005602068D83001680F68A7B181687A68096891420FDD08F07DFB2168D8310A6806
+:20DE800012685368984202DD506008680268086902602068D83041680F684FB101690E68A7
+:20DEA0001EB172687B689A4202DD0F602068D83001690F683FB1806879680068884202DD71
+:20DEC00007F06AF8F8BD0BF0F9FA2068D0F8E8000560F8BD140100202DE9F0411D4CC668E1
+:20DEE000E76C00210125ADF1200DA04605FA01F23A4209D0735C0BF0CDFF984204DAE06CF6
+:20DF00009043E064D8F84C70491C1B29EEDB47B9114F0020396884F84A00C1B1C4208847E0
+:20DF200015E0684600211C2200F010FD8DF8045000268DF80760E06C009094F852708DF848
+:20DF40000570684600F068FE062084F84A0008B0BDE8F081E4FA00204404012010B5044618
+:20DF600000210C22ADF1180D68468DF8141000F0EDFC6078012809D0042807D002281CBF7D
+:20DF8000B3208DF8140004D10A2000E002208DF804009DF8140000BB2078ADF800002123A6
+:20DFA0008DF8023001228DF805206846F7F774FA9DF8140088B90398406C0821017061782F
+:20DFC00041706178022903D16168801C0CF0E4F8684606F0E1FC9DF8140006B010BD2DE9B8
+:20DFE000F04F1D4690466A68834600268A464FF0010909AF3046ADF1140D09FA00F10A42A2
+:20E000001CBF761CF6B2401C1B28F6DBA6B13046FEF720FE041C10D0002001466A6809FA5F
+:20E0200001F3134204D04A19127A431C2254D8B2491C1B29F2DB00E00024CDF8008001961F
+:20E04000029438780390A9786A6853465846FEF7C5F914B1204606F09FFD05B0BDE8F08F74
+:20E060002DE9F843DDF82480089C164689460AF0F7FF071C15D097F805C0002001E0401C5E
+:20E08000C0B284450DDDBD6882005119AA5A9145F5D122788D78AA42F1DC112E0ED0132EF4
+:20E0A00002D00020BDE8F88313B9CA7852080FD2012BE4D1CA789208E1D309E0012B02D1AC
+:20E0C000CA78120904D2002BD9D1CA78D208D6D30868C8F8000098F8020020700120BDE85B
+:20E0E000F8830000C8B50AF061FD01461C4803680429C3F34062C3F3C056C3F300674FF00D
+:20E10000FF302BD1C3F30331491F1BD0C91E24D0491E1DD0891F21D1180E0ED2980E07D348
+:20E12000580E03D2980E03D30F20C8BD1120C8BD002F14BF10200B20C8BD002A14BF0E20B1
+:20E140000D20C8BD56B1002A14BF26202520C8BD002A14BF0A200920C8BD0C20C8BDC0466D
+:20E1600094120050F8B51C4D0446286818B904F0E9FC286818B116490978A14201DC0024F2
+:20E1800023E0144A0C2114FB01246668A7684FF0FF310BF0BCFC114831780268012908BF61
+:20E1A00028680CD039682868531E0B4207D10C497B6809689A4202D81940994201D00024A4
+:20E1C00001E0012131700CF017F82046F8BDC0464CBF020070C1020094130120981301209B
+:20E1E0009C130120F8B50C46054609F0A3FF1C490E78002784466EB31C31BE463846A1F10C
+:20E20000180212F8183F9D4204D0761E00F10100F7D11FE09768EFB13A78944205D0BE4683
+:20E2200057F80C7C002FF7D114E0BEF1000F07D157F80C6CC20002EB00125218966003E0BB
+:20E2400057F80C0C4EF80C0C002047F80C0CFF2607F8026C60460BF050FA3846F8BDC046CC
+:20E26000501A00202DE9F0471D4D9C4608AF143DD7F810A07B68EE68AC78894696460146A5
+:20E2800066B3E878A04229DD162000FB04F28046B15408FB0460A0F80290A0F804E0A0F886
+:20E2A00006C03988018143B1AA78E96808FB02100E30194604220AF0EDFF398908FB046007
+:20E2C0004181B989BAF1000F818104D01230514604220AF0DFFF641CE0B2A870BDE8F0878D
+:20E2E000040D01201D4998B54A68926917783FBB154B1A78154F5B68042412FB04F424B2E7
+:20E30000920000FB0434B7FBF2F2824203D20868D0F84C05804712480068C06B8047211ACA
+:20E32000A1F54871090806D3094A011B891A090828BF00F5487407482146F6F797FF98BD5B
+:20E3400005490120087098BDD8000020FFF6C2FF00093D00D94E02000814012014010020F2
+:20E36000E0FF0020F8B51D4D6868C068012101706868806900781E461746022803D028687D
+:20E38000D0F84C058047002402204FF0807304EA070104EA0602384033400143134308BFED
+:20E3A00000290CD14FF0805304EA0700334008BF002804D12868D0F84C05804709E008496F
+:20E3C0006F6891F90000401E0870B86904700BF069F86868C0680470F8BDC04614010020B9
+:20E3E00012050120BFB50AF0CBFD002835D0417B062932D101680A7A44898DF8082009889C
+:20E40000ADF8001005F036FB200B26D3BDF80010002009F047F900BB114CB4F84810684615
+:20E4200009F073FA0020014609F03CF9071C11D04FF6FF75386801888D420ED0B4F848104A
+:20E44000FAF742FD1A2808D03846002109F02AF9071CEFD108460BF0DFFE0090BFBDC0469C
+:20E46000E4FA00202DE9F041E4F7CEFE1B4C1A49DFF86C802078002608704FF48040486042
+:20E48000206B4FF0FF310CF023F8206C35460921001F50F8042F17681FB9491E05F10105E6
+:20E4A000F7D1082DECDC09F045FE216CAF0079580D680E600BF021F958F8072030462946FA
+:20E4C0009047054609F036FE216C79580A6815430D600BF012F9D3E780040120D4DB002024
+:20E4E0000CBF02002DE9F8438146EFF31188202080F311880124164E164DF461164F6C60FE
+:20E50000F86A016A14208847D9F81000810C14BF000C0420A861386802682321002090476C
+:20E520000E480068C6F8804200280CBF211C03210B4807680FB141F00401286820F4E020ED
+:20E5400040EA01402860346088F31188BDE8F88300002443002009408401001078AB020076
+:20E56000D8AB020010B50246D07A401E2BD0C01E21D0C01F15D0801E15D0401F0ED0801E75
+:20E580000CD0801E1CBF5069002425D15069427800218A421FDD491CC9B2FAE710460BF0E5
+:20E5A000C8FA506917E05069427800218A4212DD491CC9B2FAE75069027800218A420ADDD2
+:20E5C000491CC9B2FAE750690278002101E0491CC9B28A42FBDC012408B106F0DDFA2046B1
+:20E5E00010BD000003B42DE9F04307AFBD681E469046ADF11C0D002D14BF002E042027D029
+:20E600001946384601AA00F017FA144C04F110010968002818BF071C19D10846FEF7BEFC91
+:20E6200081460020009094F83300E18E01AA0323F4F7EEF8C7B237B94146324601A82B4611
+:20E6400003F054FA07462069494601F0A1F8F8B207B0BDE8F04302B07047C0465CFC00206A
+:20E66000F8B507460BF0B2FD044677B3B87A60B397F909200AF068F8012303FA02F1CDB297
+:20E6800040B1144E30681132934098433060DA4346F8042C0020B8610346BB723B7207F12F
+:20E6A00010063B60024686E80C000B4A7B6002F5107003781943017092F8420210B1401E0B
+:20E6C00082F84202284607F0B5FD20460BF008FFF8BDC0460C10044030F50020F8B51D4C87
+:20E6E0000546E07904211E4606F036FA002818BF01202DD109F0B4FA36F0010018BF022ED4
+:20E7000025D10820FEF7A6FA07462069002F08BF10201DD010B9276104E008460168002948
+:20E72000FBD10760E079402106F016FA002180B23960C0F51670BD8080B2B0F5167FF8809E
+:20E7400005D1E07940214FF416720BF004FD0020F8BDC04634FD0020B0B50546AC69ADF1D3
+:20E76000180D20460AF060F948B10AF063FD014620460AF03DFC012818BF201C00D100205B
+:20E780000290277AF80939BF0024201C012000248DF80C0037F07F070CBF201C01208DF8BD
+:20E7A0000D008DF80E4002A8FCF77EFF8DF81000A91C48F23402012304A8009005F111002E
+:20E7C000019405F053FF1FB9029808B90BF0A8F906B0B0BD2DE9FC470646884691469A4641
+:20E7E0001A487168184DB2684B681468118C03603046296003F09CFE07464046241807BBD3
+:20E8000003218DF80010200C8DF80340220A8DF8010029888DF8022030460BF054F96846D5
+:20E82000042104F0C3FC002818BF4FF0FF3704D14846514608F0B2FE0746298830460BF07B
+:20E840004BF93846BDE8FC87A4130120A0130120F0B50F46014616464FF6FF70002FADF104
+:20E86000240DADF818002ED000292CD0002401AA3C7003A80091801A83B201A908221D46CA
+:20E8800006A805F043F9002804BF012038700ED00DF11A002146082200F058F80DF11A0006
+:20E8A0002B4601A90822009006A805F02FF9BDF81800032805DA26B1304601A914220AF0BA
+:20E8C000E9FCBDF8180009B0F0BD30B5044620880125ADF1340D3A22ADF8080060688DF8EE
+:20E8E0000A5007A9049011200BF07FFA20B107A80021112200F02AF80DF11D038DF81550E7
+:20E900009DF81C00039321898DF80B000BF0CEFA884207D08DF81650ADF800106068019019
+:20E92000684602E000208DF81600069002A8F0F7FBFE04460021112207A800F007F82046CA
+:20E940000DB030BD002213460A46194671B510F0030F0BD0002A82BF00F8011BB2F10102AB
+:20E9600010F0030FF6D1002A08BF71BD11F0FF0141EA0121042A18D341EA0141082A0FD3B7
+:20E980000E46102A08D30C460D46B2F10F0312F00F0272C0103BFCD812F0080F18BF42C05E
+:20E9A00012F0040F18BF40F8041B12F0020F18BF20F8021B12F0010F18BF017071BD00006D
+:20E9C0002DE9F04705460021281D0BF0F9F905F104094FF6FE7100206A88A981914227D08F
+:20E9E00014490F884E68044688461FE0A10001EBC401725C12F00F0F16D071186B884A88E2
+:20EA00009A4211D101F1040A50460AF00DF8012807D1484651460BF0D3F9B8F80070D8F8C6
+:20EA20000460AC8101203C46641CA4B2A742DDDCBDE8F0873005012010B5B1F5805FA8BF07
+:20EA4000052031DA0378402BA8BF09202CDA4388B3F5806FA8BF072026DA8388B3F5806F78
+:20EA6000A8BF082020DA114B5B1E1B78032B08BF032019D0D181017801F03F0441880023B9
+:20EA80006FF39F2141EA0431848893816FF39F2444EA01341460818891804488D480017825
+:20EAA000117296249472184610BDC0465DFC0020FEB5044602208DF8080019480D46018880
+:20EAC000ADF800406846FAF7FFF91A281DD01549FF2600224FF6FF77891C081F30F8043FF4
+:20EAE0009F4203D1FF2E08BF161C01E09C4211D0521C052AF2DB052A0DD1FF2E07D10748D0
+:20EB0000B0F84810684608F000FF0020FEBDB0000C52401845800120FEBDC046E4FA00206A
+:20EB20002CFB002020010020BFB519490EC901A880E80E00174D0024274601A800902146EC
+:20EB40003A460C23072006F075FE02A92846082209F09AFD38B9641C052CEEDB019808B9DE
+:20EB60000FB912E004240C49887970B9012088710A4D01990C2201F2E240019001AB6860E1
+:20EB80002146072007F05EFD6F800090BFBDC04620C3020041FB002034FD00204804012095
+:20EBA00010B500211822ADF1300D6846FFF7CEFE822018216A460BF027FA0021112206A841
+:20EBC000FFF7C4FE3A20112106AA0BF01DFA3B20112106AA0BF018FA0C49002008700C48A4
+:20EBE0000078012818BF02280DD10A4A4FF48170102114460BF002FA28B94FF48170102145
+:20EC000022460BF001FA0CB010BDC04649FB0020ADFE002038BC020030B500240546282244
+:20EC2000ADF12C0D2146AC716846FFF78FFE0B220DF1190005F10B010AF02CFB12482968F6
+:20EC4000016068460AF01AFB28798DF8110068798DF81200E8798DF81500287A8DF81600AF
+:20EC6000687A8DF81700A87A8DF81800074800688DF81440D0F87C148DF81340684688471A
+:20EC800020460BB030BDC046E4130120140100202DE9F84F0AAF7C6897F808803E68814695
+:20ECA000184692468B46234658B3074600259C4207D10BEB050148463246FFF78BFD00BB76
+:20ECC0000023B8F1010F05EB0A0103EB060005D00278097800208A4208D006E009780078F6
+:20ECE00001EA000200208A4200D00120002818BF6FF0060006D17F1E03F1010305F101057E
+:20ED0000D5D10020BDE8F88F2DE9F04104460BF05DFA194D29688046D1F8EC00D1F8E010F3
+:20ED200050F8240008602968D1F8E410134C08601048083C00682678C06B80476768B100D6
+:20ED4000B0FBF1F177B92868D0F8E0000068884208D2B1FBF0F10427484316FB07F109B2AB
+:20ED60004143616008F072FC40460BF0B9FBBDE8F081C046E0FF002014010020E000002063
+:20ED800038B51B4D28684069012444772868A830C16A497B0F2927D0006804706868016C66
+:20EDA000202088472B681349D868816103F1D400D96802681B69527B91F8305033F81230F9
+:20EDC0006D00AC404FF470755C43034605FA02F08008A04238BF041CD3F81C2401F110004B
+:20EDE0004B346100904738BDD0F8BC00804738BD14010020A1AA0100B0B51B4903680F68FB
+:20EE00001C8800210A466FB17D7B052D07D13D682D88521CD2B2AC4204BF491CC9B27F68F7
+:20EE2000002FF1D1032905DA092A03DA0F493431098800E00121018105214173418941F41B
+:20EE40000061418118884FF6FF77874206D0054801881846FAF738F81A2802D101200BF00F
+:20EE6000DBF9B0BD2CFB002038050120E4FA002030B54968ADF12C0D81B308208DF8000060
+:20EE800000258DF8015008788DF8020048780A1D8DF8030092E8190001AA82E81900087CBC
+:20EEA00001F114058DF8100095E8090005AC10221C3184E8090007A80AF0ECF92C2009F0B4
+:20EEC0000CFB04460748057844B1204669462C220AF0E0F92846214604F0DEFB0BB001206C
+:20EEE00030BDC0469C030120F8B50B4601464C69601E024218BF221C651E184610EA0507A7
+:20EF00001CBF2044C01B834213D8CF6801F10C0C7FB1531E796803EA070613EA070518BF8A
+:20EF2000561B84198C4206D9BC46DCF80070002FF0D10020F8BD091ABA198D1B3EB98E42A6
+:20EF400004BF3868674608D03968674602E07E6025B1396810180160456038601046F8BD73
+:20EF60002DE9FF4105460420984616460C468DF80100684609F048FB071C28D0B8F1000FFD
+:20EF800008D00120BC800023B8773878FB7640F080003870396903220A70481C06704470A2
+:20EFA00021128170284605F097FD48B9284601A908F0D1FF20B10120787701AE3E6201E044
+:20EFC000002078777D803846ECF756FE00E001200090BDE8FF8198B517460C46521E2CD052
+:20EFE000521E26D0921E0AD0121F03D0083A29D1102200E0082221680AF050FB22E022684B
+:20F00000036852F8011B01F0FF011943016052F8013B1B0641EA1341016052F8013B03F071
+:20F02000FF0341EA03410160126841EA0261016008E0216809F05EFF04E021680278097866
+:20F04000114301702068C019206098BDF8B505460C461A2009F041FA071C31D000211A227C
+:20F06000FFF774FC79203870002078702188B9806188F980217939726679014606B1012159
+:20F080007972A679014606B10121B9720146E07900B10121F972207A3873607A7873A07A19
+:20F0A000B873E07AF873207B082204F10D01387407F111000AF0EEF8E8B2394604F0ECFA10
+:20F0C000F8BD30B5044600210C22ADF11C0D6846FFF73CFC20880121ADF800000C208DF83A
+:20F0E0000400607A8DF8051000280CBF081C21208DF802006846F6F7CFF99DF8141099B94B
+:20F100000398456C06232B706168681C0BF044F8A078687260880012A872207AE8726846B3
+:20F1200005F03AFC9DF81410207A002814BF081C002007B030BD00001B4910B504463422A5
+:20F14000ADF1380D6846FCF7D1FCA088ADF80C006088ADF80A00207D8DF81C0020690A908D
+:20F16000207F8DF80500208DADF81000207E8DF80600607E8DF80400608DADF82E0094F828
+:20F180002C0000228DF83000FF208DF834000DA98DF835004FF0FF308DF836006846E7F76F
+:20F1A00029FB00200EB010BDD0BE020003B41046F0B51E1C05AFADF1140D14BF0028042072
+:20F1C00027D0114638466A46FFF736FC134D044605F114000068DCB910B1804700B90B246A
+:20F1E0002869ACB9FDF7DAFE0746314600226846EEF7E8F9041C07D1BDF80C1021B19DF8C3
+:20F20000100004F023FA6C782869394600F0C0FAE0B205B0BDE8F04002B070475CFC002032
+:20F220002DE9FE43194C1A4D05264FF6FF790A274FF00208A41E34F8040F814521D06388A6
+:20F240008BB15B1E9BB293FBF7F0638078431B1A17D120888DF808802988ADF800006846C3
+:20F26000F9F732FE0DE020888DF808802988ADF80000684608F049FB2046FF210422FFF7EA
+:20F2800065FB761ED7D1BDE8FE83C046200100202CFB002038B51B4C184A0023164994F85A
+:20F2A0003A01136020B3012817D0022807D003281ED151F8350CFEF799F8062016E051F82D
+:20F2C000355C2846F1F78EF940F2FE50A84202D2001DA842F1D8042008E051F8350CFEF727
+:20F2E00095F9074800780028E7D00220C4F83C010AF0A0FA38BDC0463D400C403C500C408F
+:20F300000AC2020010150020F8B50D4606460AF05DFF0446E8B20AF0C9FA8025071C23D0DC
+:20F32000B87A08B3386886421ED11349486891F82410022906D03846FFF792F900F096FF3B
+:20F34000812511E097F909100A4E4FF4A06202EB012202F47F4246EA0201002206F084FF3B
+:20F3600005463846FFF77CF920460BF0B9F82846F8BDC0460100080430F5002070B505465C
+:20F380000AF024FF194C06464FF0FF30E06205F1B8000AF013FFB4F9B400B4F9B610884297
+:20F3A0000FD194F8240002280BD094F8DC0040B130460BF095F80720FEF7B8FA0AF006FF94
+:20F3C0000646B4F9B400B4F9B61088421CBF012085F8FC0006D104F5CE700AF0EFFE0820B1
+:20F3E00006F028FF30460BF07BF870BD30F50020F8B51B4C01F0400C002296264FF6FE75B3
+:20F40000A4F1080737F8081F884208D185420AD0BB790CF0400103F04003994203D0761EC5
+:20F4200002F10102EED11646962E12D1854210D1214696220026087928B1521E01F1080162
+:20F4400006F10106F7D1962E08DA0888614608F0A7FE962EB8BF04EBC60000DB0020F8BDCC
+:20F46000BC0300207CB502281E4614460D4612D0042818BF012829D108461A46012101F078
+:20F48000DBF818B33CB1284602F0E8FB0C28BCBF012020701ADB28460021FFF7A9FF78B1F3
+:20F4A000817911F0180F0BD04FF6FE710091094E0288438831881046002203F0FFFD07E057
+:20F4C000284631460822F5F703FC08B100207CBD01207CBD1EFB00202DE9F84308AF3F78CE
+:20F4E00099461446064607F00FFFDFF858800D46082816DB4FF6FE70002107F005FF082860
+:20F5000008BF02201CD0D7B14100424601EBC000FF23155411184E800B4F8B713878087217
+:20F520000AE04100424601EBC0008118C879A042D8BF032004DD17B1CC71A1F804900020C3
+:20F54000BDE8F883A40100201BFB0020F0B5024691694878097801EB002117480768ADF1EF
+:20F56000140D0AF0A3FC154C88421CBF0020812314D13B46002002E01B68401CC0B2002B23
+:20F58000FAD1401E0023C0B247B1A4467D682E780EB10CF8016B3F68002FF7D10091019051
+:20F5A0000294107C0390517C48F20500921C01F019FA05B0F0BDC04624050120A8FF00205F
+:20F5C00008B513460A4618BB3A2A14BF3B2A012114D0174940F20310904205D12031184654
+:20F5E000102209F057FE08BD10480078682A0AD0B2F5817F18BF622A16D1002110461022F0
+:20F600000AF0EAF908BD0128E9D002280CD1E6E7052808BF052002D0062805D106200093EA
+:20F620000022102306F006F908BDC046ADFE002018BC02002DE9F0470D46298890460446A3
+:20F6400007F03EFF002818BFB82028D109F0CAFE1028A8BFB22022DA1820FDF7FBFADFF880
+:20F660004490D9F80060071C08BF102017D04FF0000AC7F800A0B81D294612223C7109F0BE
+:20F6800009FE16B94E4603E0064630680028FBD1B8F1000F376001D005F07EFB5046BDE87C
+:20F6A000F087C0461C030120DCB504460027211D6846ADF8007009F01DFCBDF800603846E5
+:20F6C00046B1BDF800104FF6F8728A42C8BFBDF8000022DC267826B1022E04BF6779E07A17
+:20F6E0000DE06068070C00F47F4607F47F4100F0FF0407F0FF0744EA06000F4380B287425D
+:20F7000087EA000103D04FF6F8728A4204DC00280EBF0721083881B20846DCBD90B51B4C26
+:20F7200022687032116891F82B70ADF1140D57BB516E8F783FB3037AC168D2F81821184670
+:20F740009047071C1FD02068016F91F82B0040F0040081F82B002068D0F85C1302A8884704
+:20F760006068816A01208847012024680090206F20300190D4F8D400C38CD4F87843394644
+:20F7800002AA0520A04705B090BDC04614010020F8B504461A48006825180AF089FE0B46A4
+:20F7A000071C2BD00AF048FE064623BB38460AF067FDA168884203DDA1683846FBF7D6FEE5
+:20F7C00028460AF031FEA0B928460AF021FE8168E16008460AF054FDEFF31187A060202035
+:20F7E00080F31188084639460AF00EFE87F3118801E00120606030460AF00EFEF8BDC0461E
+:20F800001CC40200F8B51A4C2578064608F092FC84461848037800278BB1001D10F8181F20
+:20F820008E4202D05B1EF9D109E08068074630B13878D12803D057F80C7C002FF8D16046F3
+:20F8400009F05BFF381C10D1022008F046FE0146E07931B1D12008704D70304603F01CFF96
+:20F86000F8BD102102F09EF9F8BD4570F8BDC04634FD0020501A0020002980B534D00F0E9A
+:20F88000202F1BD0212F08BF022218D0A02F08BF032214D087B1102F08BF05220FD0112FE8
+:20F8A00008BF06220BD0402F08BF072207D0502F0CBF0822092202E0042200E00122C1F3EA
+:20F8C0009701090241EA02110268B2F1FF3F41F00F0106D0914204D050F8042FB2F1FF3FE2
+:20F8E000F8D14FF0FF31016080BD00001FB504681748617A012913D000686169806891F808
+:20F9000021100246684690476069416990F82120684605F020FC10B96FF00200606006E01E
+:20F92000006861698268486991F821109047094840210160802404600021C0F8FC12022045
+:20F9400007F0BCF804480AF057FC00901FBDC046FC01001004440240B80E0120B0B50446C4
+:20F96000E16891F8380000F00300012810D12069077C77B9496C0A78052A0AD14978012918
+:20F9800004D006291CBF0321017402D102210174206900210170E068216990F848008870D0
+:20F9A000E068216990F84200C870E068216900694860256909F03EFC014605F108000AF090
+:20F9C000EBFB2069F5F7F0FD2075B0BD2DE9F04380460E464FF6F870ADF1140DB04202DC3E
+:20F9E000B8F1000F24D0144C332500F1070901272079FF2818D0B8F1000F05D1B14513D06B
+:20FA00002088B0420ED00FE08DF800706088ADF80C00684603F062FA30B101A9404609F0EA
+:20FA2000E7FA08B1204604E06D1E04F12404DFD1002005B0BDE8F083E40D0020062809DC79
+:20FA4000062814D0C8B1801E14D0801E0FD0401E0AD007E00A3807D0801E08D0C01E03D0BD
+:20FA60000F3801D000200AE041F2011007E04FF2011004E04FF4817001E040F20250FF2942
+:20FA800004BF40F0C00121F480610AD031B149082CBF40F0100040F0200001E040F03000F3
+:20FAA000014640F2037040EA01407047F8B51A4C6069002510B1804700B90B2520694DBB35
+:20FAC000FDF76CFA65780026074606E03046F9F7A5FC761CF6B205436570E178B142F5DC1B
+:20FAE000002084F83100491E84F832100C2684F8330010FB0641B1F84C10E1867E2106F0E0
+:20FB00007DFF94F83200FE2106F078FF20693946FFF73EFE2846F8BD5CFC002010B50AF08B
+:20FB200055FB154991F82420022A1ED091F8241004291AD00AF0D4FC10480068006B8047A0
+:20FB40000F4A002309F002FD0E4C4FF090531B1820684FF07A044FEA000244EB01040021AD
+:20FB60005B1844EB0204241C04E0074990390C680AF0B6FC204610BD30F500208C0100106B
+:20FB800000093D000413012094300440184930B58422ADF1BC0D02A8FBF7A8FF15490EC914
+:20FBA0002CA880E80E0002A800902CA8019004208DF88C0002F038FC684623A9FBF710FE87
+:20FBC000051C10D00C4928A814220AF000F9284628A907F003F80446284609F08FFE002C3B
+:20FBE00008BF002001D04FF0FF302FB030BDC0465CB802002CC302000813012030B504469B
+:20FC0000A07AADF11C0D50BB606805A96A46FEF71FFE0146E07A400921D29DF81400012811
+:20FC20001DD19DF81000022819D19DF81250FF208A000D4B8DF81000681C02EBC10200F06C
+:20FC40000F008DF81200002001900E330090D5186860985014226B46042006F0F3FC204689
+:20FC6000F7F76EFC07B030BD56FE0020F8B50446102141F221054FF6FF7000F0010742089D
+:20FC800024BF684080B2401017B140F4004080B2491EF2D1641E10274FF6FF7614F8010F30
+:20FCA000082108F0F1FD802106F400437200014296B21CBF83F400439BB213B185EA06023D
+:20FCC00096B24910F0D17F1EE8D13046102108F0DBFD4FF6FF71484080B2F8BD2DE9F04388
+:20FCE0008046ADF14C0D02A808F0E9FE164D4FF00709022600242F68FFB1B868E8B18DF83B
+:20FD000000903A6AADF80260ADF804402AB19DE8030090472F68412808D0BF689DE80300FE
+:20FD2000412202ABB847012807D109E0B8F1010F03D1204602A903F079FB641C052CDADB5F
+:20FD400013B0BDE8F083C046F8FD00202DE9F0410F1C904606460AD04EB1B8F1000F06D0B2
+:20FD600000242046394607F02FFC0A2802D10120BDE8F0810D281BD03578387805F00701A2
+:20FD800000F00700884213D12DB9301DB91D042208F0E0FE38B9022D0AD1301DB91C082272
+:20FDA00008F0D8FE20B1A8F800400020BDE8F081641C052CD5DB0220BDE8F081002980B597
+:20FDC00032D00F0E202F1BD0212F08BF022218D0A02F08BF032214D087B1102F08BF0522A3
+:20FDE0000FD0112F08BF06220BD0402F08BF072207D0502F0CBF0822092202E0042200E05D
+:20FE00000122C1F39701090241EA02110268B2F1FF3F41F00F0106D0914204D050F8042FA6
+:20FE2000B2F1FF3FF8D1016080BD98B504466FF002001F688DF800003A462046FDF7B8FDE7
+:20FE400010B101208DF800009DF9000010F1030F13D1E068007B00F00F0002280DD167B1CC
+:20FE60003A6820463946FDF7A3FD18B9002A1746F6D102E002208DF800009DF9000010F128
+:20FE8000030F04D1E06B10B104208DF80000059807609DF9000098BD10B50C466068ADF15A
+:20FEA000200D58B302218DF814100188ADF80C10817B02298DF81E100DD001290BD00F2900
+:20FEC00009D003290BD100F1100108220DF1160009F0E0F903E06068008AADF81600606877
+:20FEE000818900910DF116030193017E0291837A821C03A92220FDF721FE00E0022060703C
+:20FF000008B0012010BD002B08BF002A0FD10B1C021C002908BF002807BF002000210020BB
+:20FF20004FF00041C4BFC043C943F9F7B6B910B55C0894EA610404D55FF0000E40426EEB33
+:20FF4000010113F0004F04D05FF0000E52426EEB0303FCF763F9241C04D55FF0000E5242D0
+:20FF60006EEB0303640004D55FF0000E40426EEB010110BD2DE9F8430024002B16460F468D
+:20FF80008046254606D5002FC3F1000302D57F42761E2D2599463846494605F03DF80CA02F
+:20FFA000405CB7FBF9F7002F04F1010408F8010DF1D1A64205DD3021301B401E08F8011D28
+:20FFC000FBD10DB108F8015D4046BDE8F883C046303132333435363738396162636465662B
+:20FFE00000000000F8B505462C680F460AF0EEF816490978012902D194F8221019B10AF0E1
+:020000040002F8
+:200000006FFA0020F8BD012684F822600AF068FA07B90D4F387884F8200078686060387869
+:20002000022814BF0021B96884F82360002084F82400A16084F8250084F826000B20F9F763
+:2000400043FD2846F8BDC046A4C202001F05012070B5064635680AF0B9F8002195F82120E2
+:2000600085F82410032A1CBF042A85F825100AF037FA0F4800F108010968090824BF4FF0C7
+:20008000FF31E9610B490160304606F003F895F82000022807D06C68E9692A6895F8213086
+:2000A0003046A04770BD04480AF0A6F870BDC0468847024001000080080F012010B50446C6
+:2000C0006089ADF1200D05A900F064F805A807A96A46FEF7BDFB9DF81C0070B19DF8100041
+:2000E000FD2818BF002808D10D48007828B9607A48B96068007806280FD0607A18B96068BA
+:200100000078072809D0207B18B960680078052803D1044801682046884708B010BDC0463D
+:20012000D4FE0020840201201CB50C46217F052907D104F1080100F02DF8002808BFC82073
+:2001400024D004F10800694608F0A6FFBDF800004FF6FF71814218D02078012810D1BDF8F6
+:2001600000100B4B880000EBC10003F12C014018A16902688A4288BFA22007D8491C01607E
+:20018000BDF80000A08200201CBDA1201CBDC04660FE0020D0B50746184800880C4601263E
+:2001A00087421ED009F070FE874216D0384607F0D2FE06460F480078C8B90AF02FF8B0B907
+:2001C000AEB90D490888B84211D187B11C312046082209F05FF8012609E0084609F080FFBB
+:2001E00005E009F027F80146204609F0D5FF3046D0BDC046ADFE0020700201201EFB0020E8
+:200200002DE9F041174D804605EB880528680C46660824F0FF0186F0010606F0010610F012
+:20022000FF0F0AD109F0D2FF210A6970270CAF70210EE9700AF054F900E02960002706B19F
+:20024000012727B1404604F0010109F0D3FC09F0BDFF054941EA88010F600AF041F90020E0
+:20026000BDE8F08100100840001A4442194838B590F82410022928D0044694F82400012820
+:2002800026D094F82400042822D009F09FFF05466846FBF747FE80B1009949B904F5AC70F2
+:2002A00009F08CFF04F1E000042109F0ADFF08E004F5AC7009F02CFA03E004F5AC7009F00E
+:2002C0007DFF28460AF00CF938BD192009F084FF38BDC04630F5002010B504461848017863
+:2002E0002078ADF1180D001F21D0801E0BD0801E24D1012918BF022920D12079FAF756FF8B
+:2003000007F0AEFC1AE0012918D16088B0B9201D694606F02BFB012810D109F0C7FDADF86A
+:200320000800241D01946846FBF7A8FA06E0012918BF022902D12046ECF714FB06B010BDDD
+:20034000ADFE0020F8B50446A07C0C28B2BF0026A069C67AF01D4000FCF77CFC071C25D0DB
+:20036000A46925783D700DBB641C381D214609F013FF083461782078002500EB0120788041
+:200380003D739EB1A41C14F8010B387314F8010B07F10E01787362782078761EF6B2A41C63
+:2003A000002E00EB022021F8020BF4D13846F8BD2DE9FC410020ADF800001420FCF74AFC5F
+:2003C000071C27D01448006808B38046032402254FF6FE76A8B241460622C01908F05AFF84
+:2003E00038F8060B864204D0BDF80000401CADF80000641E05F10605ECD1384669460222D9
+:2004000008F048FF4C2014213A4609F0FDFD384604F0C2FBBDE8FC8160FE002070B5064649
+:2004200009F0D8FB05466C68304608F0B1FBA0B909F0CCFE0546D4F8C00040B994F8FB0044
+:20044000002106F0F3FE012084F8FC0001E00121017428460AF044F870BD09F0B7FE0646B8
+:2004600094F8FB00002106F0E1FE0121D4F8C00084F8FC1008B10421017430460AF030F8DE
+:200480002846F0F7F9FD70BDF8B5194C6068C06800780E4628B92068D0F858240021012027
+:2004A000904709F093FE054609F008F804F054FD07462068D0F8EC1051F82610D0F8E00092
+:2004C00001602068D0F8E400016007F0BFF82268D2F8D8000168D2F8E02438469047206838
+:2004E000D0F8D4048047284609F0FAFFF8BDC04614010020194898B501684969FF220A76DB
+:20050000016814310B68DC7E012C0CD0D1F8C0104A7B91F82C108A421ED04068406C80475F
+:2005200007F0E0FE98BD0020D876886AC77A9FB1D1F8C00090F843308DF8003090F852305D
+:200540008DF8013090F853008DF80320D1F8C0138DF802006846884798BDC0461401002032
+:200560001949420828BF081C21D2020924BF081C001D1CD2420924BF081C083017D28209B6
+:2005800024BF081C0C3012D2420B24BF081C14300DD2820824BF081C183008D2C20824BF5D
+:2005A000081C1C3003D2C20B03D30846103000687047C11300F40050C903084314BF002084
+:2005C0004FF0FF307047C04634FC002010B50C460146ADF1880D684609F0DBFD11A8214670
+:2005E00009F0D7FD9DF87A00800828BF002021D29DF87A0040080BD30DF17F000DF13701B5
+:20060000042209F04BF89DF87A0040F002000AE00DF17B000DF13701042209F03FF89DF8B3
+:200620007A0040F001008DF87A0011A9204609F0B0FD012022B010BDF8B50F4614460546E3
+:200640004FF6FE76012F03D1032104F01FF920BB2846002104F068FF2146FEF7C9FE012F95
+:2006600017D110B14179012903D0E00938BF2E1C00E046884FF6FE74B44210D0304603211B
+:2006800004F004F948B9B54209D0AC422E46F5D105E020B14079022801D10020F8BD01200F
+:2006A000F8BD000070B505462C6894F8200004280AD0022818BF00261FD113484FF0FF31EE
+:2006C00009F025FAE66918E00D480068806901460C488847000824BF4FF0FF30E061E669C2
+:2006E000002094F8211084F8240003291CBF042984F82500284605F0CDFC304670BDC046D3
+:20070000FC01001001000080080F01202DE9F04706464FF6FE70708006F1040AB08150460B
+:2007200008F082F94FF0000801281DD110480788D0F80490C7B14446A50005EBC4054D44B4
+:20074000287810F00F0F0BD0291D504608F050FC012805D16888B4814FF001083C46708002
+:20076000641CA4B2A742E7DC4046BDE8F087C04630050120B0B5154DD5F860014268002139
+:2007800001209047D5F8600101680120884788B10F4C278817F0010704D14FF00120C4F897
+:2007A0000404208828688047012F04BF4FF08070C4F804040748084CD5F86C710068183C43
+:2007C0006061386880472062B0BDC0468000001000A00C4030200940AC020120F8B5184D06
+:2007E0000C3DE97895F8334000273E4624E095F83200761CA042B6B217D0E86861036A46BA
+:20080000042309F039FC009800F0FF00FF2803D07E2818BF7C2808D1A00000EBC400401960
+:20082000B0F84C003F1A07F50057E978641C94FBF1F04843241AE4B2B142D8DC3846F8BD8E
+:2008400068FC0020E1291CB528D10189154C491C89B20181E9B112480078F8B1943CB4F8A2
+:20086000941088421ADA002001F0BAFEB4F894206421414391FBF2F11A290FDB0A49091FCD
+:20088000096859B1ADF80200ADF80020684688471CBD00202080012001F0A2FE1CBDC046CA
+:2008A000D7FE002078FB0020FC000120F8B5184B1C780F2C25DA1F78E50005EB0415ED182B
+:2008C0002C77FD0005EB07151F7803F11C06AD196860F80000EB071080191F78C160197855
+:2008E000F800CD0000EB071000278019876005EB01101D7880190774E80000EB051080195F
+:200900004261641CE0B21870401EC0B2F8BDC046501A0020F8B5184C1548D4F8A86009F04A
+:2009200081F91449054608680F6800F02000284007F460270DD066B10300C4F8B0600022CF
+:20094000304604F0D3FD04F1E0004FF4804109F05BFC17EA05000AD094F8411241EA5040BA
+:2009600084F84102002104F58E7009F04DFCF8BD20000E000C10044030F50020F0B5184CCD
+:2009800000250526ADF1140D5D3401A80090294600220C23072004F04DFF02AF2046082216
+:2009A000394607F071FE48B93846002108F09BFB18B96D1C052DE8DB00E02E46052E0CDA68
+:2009C00002A82146082208F065FC002031460C2201AB0190072005F035FE05B0F0BDC046CA
+:2009E000E4FA00202DE9F843DFF85C900446904608AF8DF8001009F104003A79398800689F
+:200A000048F20605A5420CBF1025002500F8013B00F8011B0E1200F8016B002A027008BF56
+:200A2000042605D0111DCEB2B968401C08F032FC4F462246684641463346FD7000F06EF8F8
+:200A40000020F870BDE8F88398FD0020F8B50746387A012804D0384605F001FB064600E0F5
+:200A60003E884FF6FE70B04221D0114C0025397A012909D12801A0EB450000194278012AEA
+:200A800002D1428896420AD001290AD02801A0EB45000019437823B941888E4201D109F0F6
+:200AA00019F96D1C042DE2DB304603F073FAF8BD6C010020F8B5844640F6FF741CF8013B25
+:200AC000002210E0481B401E10F8015B7F1E01F8015BF9D103E01CF8010B01F8010B521CAD
+:200AE0005B08082AEADA5808F5D21CF8010B1CF8015B05F00F07FF1CC5F30315122F45EA80
+:200B0000001508D11CF8016B300A24BF1CF8010B60F3DF16BF19AC42D4D1F8BDF0B50E46C9
+:200B2000174604461D4600210C22ADF11C0D04A8FDF70CFF00208DF81900307A0F498DF8A5
+:200B4000180030884A68ADF81000207802F8010C48686B1C401E3A460090881C0190C878A5
+:200B6000074902900F20039004A8EDF7E9FD10B92178491C217007B0F0BDC04698FD0020E4
+:200B800064FD00201649174A00200968A2F8AA00D1F8D41091F8313082F8AC3091F8241095
+:200BA00082F8AD1092F8AE1021F0200182F8AE1092F8AE1021F01F0141F0010182F8AE1068
+:200BC00092F8AE1060F3871182F8AE1082F8AF00054982F8B100097882F8B0107047C04690
+:200BE00014010020501800204E02012070B5154E154C706928B12068D0F8541206F114006B
+:200C0000884709F0E3FAF1690A68002515710968F16109F065FC0D4A0D49107810B908464F
+:200C2000007870B1157008460570F8F717FD6068C068007828B92068D0F858242846014606
+:200C4000904770BD68110120140100200514012007140120F8B509F0B9FA164D164C2E7887
+:200C6000297801290ED001272F7009F039FC6068C068007840B92068D0F85824002138460A
+:200C8000904701E009F02CFCEBF70EF9074609F09DFA07B92E7009F023FC6068C0680078D7
+:200CA00028B92068D0F858240020014690473846F8BDC0460E05012014010020B0B5477883
+:200CC000144D17BB082095F85C4085F84A0034B91148016809B13846884707F0B1F8104C17
+:200CE000601C0078012802D1384607F06BFA0B48006868B1207D01280AD128784FF4804111
+:200D00004FF47A7209F024FAB0BD00204A352870B0BDC046E4FA00204404012010FC0020E3
+:200D2000ACFE002030B50C466068ADF11C0D38B3017819B9401CF3F7EDFC22E0002501A8EE
+:200D40000090A9B200221423042004F073FD607090B9606803A90822401C07F095FC58B91B
+:200D600001A800211422FDF7F1FDA9B20420142201AB05F067FC04E06D1C032DDFDB01E0A0
+:200D80000220607007B0012030BD000038B505462C6801206070207A042809D0022805D140
+:200DA00011484FF0FF3108F0B2FE15E0002038BD0A480068806901460C48801E8847000806
+:200DC00024BF4FF0FF306060002106486170044908602846FEF78AFD606838BDFC01001059
+:200DE0008847024003000080080F01200300008038B505461548007838B31549083951F8C4
+:200E0000084F4A681278954202D0401EF7D138BD2068A16909F0CEF9206809F0CDF9207949
+:200E2000401E02280CD9C01E08D0001F04D0801E14BF01200B2004E0092002E0062000E0EA
+:200E400005202071284608F0DDF938BD57BF0200C4C2020070B504F0C1FB04F080FD08F0CD
+:200E6000A9FE124C606828B1606803F095FE0020208060600E4D2C687CB120686668006A22
+:200E800003F08AFE206803F087FE606903F084FE204603F081FE341CEFD10020286007F012
+:200EA00083FD04480078F3F777FA70BD3005012038050120E4FA00202DE9F0410E4634885D
+:200EC000ADF1200D162C22DDDFF84C804703362CDABFA4F1160085B22025D8F800006A4677
+:200EE000641B2B46A4B2391909F0C6F80DEB050010F8011D962904D16419A0B2308001204C
+:200F000006E06D1EADB2002DF2D1162CDFDC002008B0BDE8F081C04668FC00202DE9F0474F
+:200F2000164E074630788A4600244FF01808B14603E099F80000641CE4B2A0421CDDFF2F7B
+:200F400007D006F11C0114FB08F04518085C874209D0FF2FEDD109F0ABFA14FB08651C35E5
+:200F600069688842E5D107F0E5F86A69116821EA0A01116008F0C1FBBDE8F087501A00201F
+:200F8000F8B5174C2678002786B1221D12F8183F984203D1002301B101231374157C0023C3
+:200FA0002F4318BF0123761E1F46EFD1A0784FB198B9012005F09AFD022005F097FDA07832
+:200FC000401C09E0012808D1012005F077FD022005F074FDA078401EA0703846F8BDC046F9
+:200FE000501A0020F8B5174C064604F13A0000880F46B04208BF012504D030460023FDF7BF
+:20100000AFFF05463046002104F08EFA618F814216D138460021FEF7EBF970B1817911F096
+:20102000180F0AD04FF6FE71009102884388618F1046002202F042F802E0384608F052FBDC
+:201040002846F8BDE4FA0020BFB50546A8690778FF2F08BFFE271348134C0770207880219C
+:2010600001F05EF902F0C2FD00248DF8084008F091FD30B1002F0CBF201C0120084988707F
+:20108000C870287B50B902A80090A91C48F236020123019405F1110003F0E8FA0090BFBD5A
+:2010A00054FE002036040120E4FA002070B50E46054607F03FF8044608F0DAFE012DB6FB7A
+:2010C000F0F00ED0022D07D00B4B18B9186808F023FF0DE0094908E0094B0028F6D00949D0
+:2010E00003E0094B0028F1D008490022FBF7F8FD204608F002FB70BDFCFF00202D8F020015
+:20110000F8FF002045940200F4FF0020ED94020098B5174C2268D2F8DC00D2F8D810076846
+:20112000D2F8E00009680068D2F8E024404290475FB12168E0310868026878688242DCBF42
+:20114000801A78603F68002FF5D1226802F1E4000168D2F8E02009681368994204D01160E1
+:2011600006F074FA2068E430D0F8F003804798BD140100202DE9F041164E0D4604460021FA
+:2011800070682160C068007820B93068D0F858240120904709F01AF880462946204607F00C
+:2011A000E1FE2F682A463FB161687868884203DC3A463F68002FF8D1146027602868844297
+:2011C00003D13068D0F8D4048047404609F088F9BDE8F08114010020F8B5174E054606F19D
+:2011E00014042878A978207068780822707540EA011070752979E878B778B07540EA810076
+:20120000C0B26979B07540EAC100C0B2A979B07540EAC110E91DB07506F1170008F03AF853
+:20122000032205F10F0106F11F0008F033F80E2FC4BFA87CA073F8BDE4FA00202DE9F04159
+:20124000082B90460E46044638BF082398B207F044F91025071C1DD03E7000260F487E70E9
+:201260003946BC700078C7F8048002F015FA70B9304609E009F01CF904F0FCF83978204672
+:20128000FCF7B0FF00B10126002EF3D04578384607F00AFA2846BDE8F081C0460D140120E1
+:2012A0002DE9F041069C1646884607F0CBFE071C07D097F810C0002001E0401C80B28445AA
+:2012C00002DC0020BDE8F0817D69820002EBC0025119AA5A9045F0D11A888D88AA42ECDC74
+:2012E000CD79002235F07F0E18BF0122964201D0EA09E2D307C984E80700A0881880012065
+:20130000BDE8F08170B5174C0546A41EAA7823780021B420012BA27003D12B88E688B34248
+:201320001ED153081AD3930807D3686808F0E8FD6968A278891C696001212B889209E38028
+:2013400003D200220125E27001E00125E570A36825702BB182B22846984770BD02F03EFB6D
+:2013600070BDC04622040120FEB5057C012300221C460EE000EBC206367F770806D316F063
+:201380000C0F03D0F60828BF002300E00024521CD2B29542EEDC077AAFB9012C18BF0129A9
+:2013A00011D141798DF80310012404728DF80830C788ADF80670817A8DF80410684608F0FD
+:2013C000F8FC2046FEBD0020FEBD2DE9F0410446D4F8A8501F461646884605B1A84704F19F
+:2013E000A00003C806400F4008BF002E1CD041462046802204F05CF804F1B00181E8C00066
+:2014000058B100F1200106C900F12003BA43B14383E80600D4F8A81081600020C4F8A80083
+:2014200004F1500008F0E8FEBDE8F081F8B506461446182007F051F8071C27D00021182233
+:20144000FDF784FA6120387000257D70207838716088211D0822F881781D07F01BFF207B94
+:20146000787478B1207B4000FBF7F4FB786148B105E0680001196D1CC9897A698152787CDD
+:20148000A842F6DCF0B2394602F006F9F8BDF8B506461446182007F020F8071C27D00021F4
+:2014A0001822FDF753FA6020387000257D70207838716088211D0822F881781D07F0EAFEF9
+:2014C000207B787478B1207B4000FBF7C3FB786148B105E0680001196D1CC9897A69815207
+:2014E000787CA842F6DCF0B2394602F0D5F8F8BDF8B50646708875680024022807DB032284
+:20150000B0FBF2F15143411A18BF201C20D1401C80B208F0C1FED8B17188012914D003234F
+:2015200072685218AA4212D9297814FB03F287187970AF786978821801EB072151807188E3
+:20154000641CE4B2ED1CEBE72978417001240470F8BD000070B50646356808F037FEA9789E
+:20156000F9B90021697008F0BBFF0F4800F108010968090824BF4FF0FF3169600B4901606A
+:201580003046FEF7B3F9287A022806D02C6969686A696B7A3046A04770BD054808F02CFE7B
+:2015A00070BD08F09DFF70BD8847024003000080080F01207FB508F009FE114C06462078FD
+:2015C000012818D0684608F01DFB00254FF0FF3027216B4601900C4A0A488DF8085003F0A7
+:2015E000D9FD0B48012105F0A5FE0848294605F0A1FE01202070304608F072FF00907FBD59
+:201600000306012040120120F75D0100080F0120B80E012030B5164C05466068ADF11C0D98
+:2016200018BB0820FBF716FB6060002808BF10201CD0296801602979017169794171A97925
+:201640001C22817168460021FDF780F900228DF80720286800902C798DF805406B798DF858
+:2016600004306846FDF7D8FA00E0012007B030BD340401202DE9F04180461548006840684A
+:20168000124F46688568C468B8F1000F0AD0002D08BF002C03D03846503008F0CBFA36B1FB
+:2016A000ECF783FC1EB1B8F1010F00D0B047002D08BF002C08D008F0DBF805B1A84704B15C
+:2016C000A047384606F024FDBDE8F0810100070634F50020F8B507461248012416460D46F9
+:2016E00004700820F8F7F0F9022005F0FFF93120394608F073FD0C490320012D486019BF09
+:20170000086820F00300086840F00300074A086010680068314603460020024698470448B7
+:201720000460F8BD050601200C800240CC010010A80250422DE9FF41154D8046281D06684C
+:2017400011480F461446414607F052FC002804BF0F214FF6FD7002D00C48022100888DF892
+:201760000810ADF800004146304608F015FD6946002200F8017B0A2304702846FFF7CEF994
+:201780000090BDE8FF81C04620FC002050FD002098FD0020024610B54FF6FF70ADF1300D94
+:2017A000ADF8200002208DF82800FF208DF8290008F048FC012300930021019102930391F9
+:2017C000049008460590069008A9079010460322EEF76EFD041C07D1054800784FF4804128
+:2017E00041F2883208F0B7FC20460CB010BDC0464DFF002010B504460A22ADF1180D684644
+:2018000007F04CFF0A21204603AA03F065FC48B99DF800109DF80C2001F0070102F0070299
+:201820008A4201D0002013E09DF8002012F0070F07D002290CD10DF102000DF10E01082215
+:2018400004E00DF106000DF11201042207F082F906B010BD98B5154CE768014697B114488C
+:20186000001D006800693B78007883420ADC7A78D218824206DD7A68C01AC0B210568842C3
+:20188000B8BF011C07480068026EA06890470090054A00996FF39F518A4214BFA0614FF005
+:2018A000FF3098BDE0FF0020FFFF3F00700001201401002070B5164C05466068C068007868
+:2018C00028B92068D0F8582400210120904708F07DFC2268D2F8D810D2F8F82406462846F5
+:2018E000904730B92268D2F8DC10D2F8F824284690472068D0F8E8000068A84203D104F06B
+:20190000EBFDFCF7A7FA304608F0EAFD70BDC0461401002098B5164C2068D0F8E800002186
+:2019200001602068D83001680F68A7B181687A68096891420FDD04F01DFE2168D8310A6870
+:2019400012685368984202DD506008680268086902602068D83041680F683FB101690868C2
+:2019600018B140687A68904200DD0F6098BDC04614010020F0B514461D4610270246ADF1E7
+:20198000240D264601AB16F8010B7F1E80F0360003F8010BF7D10B46009501A80121ECF73E
+:2019A000E1FD05A82946102207F074FC102001AA14F8011B401E81F05C0102F8011BF7D187
+:2019C000009501A8012105AA8023ECF7CBFD09B0F0BD03B480B502AF39780020012908BFE5
+:2019E00001207978012908BF40F00400B978012908BF40F00800F978012908BF40F01000B4
+:201A00003979012908BF40F020007979012908BF40F04000B979012908BF40F08000F9793B
+:201A2000012908BF40F48070BDE8804002B07047C8B5061C2AD0202006F04FFD071C25D090
+:201A400000212022FCF782FFE32000233870311D7B7091E80D00391D81E80D00307C06F1B3
+:201A60001403387493E8050007F1140181E80500307F3877F22007F02FFA18B9384606F0D3
+:201A800013FEC8BD0079394601F006FEC8BDF8B506460C460C2006F020FD071C25D000217B
+:201AA0000C22FCF753FF7620387000257D70A0784000FBF7CFF8B860A0B12088B880A078F1
+:201AC000B871A07810B1A078A84204DCF0B2394601F0E2FDF8BD616868006D1C415ABA6805
+:201AE0008152F0E7384606F0DFFDF8BD2DE9F84314468846064600229946F189B08900922C
+:201B0000727A337C401A80B2054604F05FFB071C14D10C48B28900684544A9B20B199A4222
+:201B200005DAF089A042ACBF0627052706E0327C234601EB42314A4608F09EFA3846BDE808
+:201B4000F883C04668FC00202DE9F047144D8046287800274FF018093C4605F11C0A19E04E
+:201B600014FB09A63178884512D106F1080005F0D4FA0746B06828B920464FF40041FFF766
+:201B8000CDF904E020464FF4004100F00BF82878641CE4B2A042E3DC3846BDE8F087C046C7
+:201BA000501A0020154A2DE9F84F0F461178804600244FF0180A032002F11C06914618E0AF
+:201BC00014FB0AF5725D904511D106F0B3FA83467119486902683A430260C86808B108F0A0
+:201BE0000FFC584607F089FD99F800100020641CE4B2A142E4DCBDE8F88FC046501A002089
+:201C000038B54FF0FF3007F00BFE05460F4C1049A06A81420FD10F4904F16000002206F0F8
+:201C2000D3FC022084F8240003F00CFF18B9F9F731F8ECF7A9FB0848284205D004F1E00040
+:201C40004FF0005108F0E0FA38BDC04630F50020F95E0000F95D010002000040B0B5154C2C
+:201C600001460C20002504F108025388994205D0401E02F1080205F10105F6D10C2D16D104
+:201C80004FF6FE70884212D10C21002514F8087F27B1491E05F10105F8D108340C2D06DAA6
+:201CA0006080606818B102F077FF002060602846B0BDC046EC010020DFB5171C0C46064618
+:201CC00026D02EB340F20110002110226B4607F083FE04F00F0438460DEB0401C4F1100225
+:201CE00007F0D8FA381B69462246103007F0D2FA7F1E3046082617F8012F01783C7A51406E
+:201D0000397010F8011B761E81EA04013972F2D10090DFBD2DE9F84384680D4603F0F4FCE5
+:201D2000174600BB246802F059F964198046002F08BF00250FD00D4E08F048FA81462046BC
+:201D400006F050FF0546484608F0CAFB1DB930683F1A0444F0D1404606F0AEF8002D14BFB6
+:201D60004FF0FF300020BDE8F883C0469813012030B584684568ADF1140D204606F024F82E
+:201D80002168486820F0020048602168486920F00F00486120680321016202A808F006FA9D
+:201DA00009480068D5F8E42001680092D5F8E8000190206895F8F93095F8FA200C46039985
+:201DC000A04705B030BDC046C4010010B0B5124C0546802D03DD2068D0F84C05804708F0A4
+:201DE000F5F90F4927680D70D7F8B8100F780B4917B90F783FB90AE00F7837F07F0702D1DF
+:201E000008490F781FB108F06BFB0120B0BD08F067FBF9F781FDB0BD140100200A14012085
+:201E20007000012000140120B0B5124C0546802D03DD2068D0F84C05804708F0C7F90E49CA
+:201E400027680D70D7F8B8100F780C4917B90F783FB90AE00F7837F07F0702D108490F78EB
+:201E60001FB108F03DFB0120B0BD08F039FBF9F7A1FDB0BD14010020700001200A140120A8
+:201E800000140120154838B508300168D1F8D40090F85300D1F818148847042814BF40F6B1
+:201EA000387443F66C4406F045F9054607F0E0FF074A084B127821464A430749B2FBF0F039
+:201EC0000022FAF70DFF284607F017FC38BDC046D800002000000120498902000C01002056
+:201EE0001CB50E21F8288DF8001023D1124CA268D432116891F8840050B991F942000E283A
+:201F000015D0D2F85C23E02069469047A2680DE014208DF8000091F94200142807D0D2F8B4
+:201F20005C23E0206946904708342268D432D2F8F80280471CBDC0460C01002038B5044602
+:201F400014F8010B15462870207800F00F00687014F8010B0011A870207800F00300E870E3
+:201F60002078C0F3800028712078C0F3C300687114F8010B08222146C011A871E81D07F087
+:201F800089F90834032205F10F00214607F082F914F8030FA87438BD90B50C466768ADF14D
+:201FA000140D07B3124968461222F9F79FFD7888ADF80000397979B1B86868B1084610283D
+:201FC000A8BF0F2061680DF1030389688DF802000246184607F05EF9606800786946012220
+:201FE000FDF728FB00E00220607005B0012090BD4CC202002DE9F041804614460E461020DA
+:2020000006F06BFA071C21D000211022FCF79EFC6520387000257D70BE802078B87160884B
+:2020200038812079B8722079FAF714FEF86040B104E02819F968407968546D1CB87AA8429F
+:20204000F7DC5FFA88F0394601F026FBBDE8F0812DE9F041804614460E46102006F03DFA1D
+:20206000071C21D000211022FCF770FC6620387000257D70BE802078B87160883881207921
+:20208000B8722079FAF7E6FDF86040B104E02819F968407968546D1CB87AA842F7DC5FFA94
+:2020A00088F0394601F0F8FABDE8F081154909681E280ADC1E2819D00C380FD00A380FD0C2
+:2020C000001F0FD0C01E0FD01AE0243810D0001F10D0401E10D0801E10D011E0086870473C
+:2020E0004868704788687047C8687047086970474869704788697047C8697047086A7047A2
+:2021000000207047B016002000B54FF6FF70ADF11C0DADF80E0001218DF810108DF80C10B7
+:202120008DF812108DF804108DF814100B48029004208DF811000020009008238DF81500A2
+:2021400007488DF8161003216A4600788DF81310B621FFF773F807B000BDC04600F8FF07E1
+:202160007CFB0020B0B544684088401E10F0030F18BF002022D180080225C7B205EB8700F6
+:2021800080B208F089F8C8B1217847700170AFB1641C0023657821789A0001EB0521851898
+:2021A0006980A17885182971E1787F1E03F1010300EB020504F104046971EBD1B0BD10B541
+:2021C000044600210C22ADF1180D6846FCF7BEFB6089ADF80000207A8DF80400207B8DF878
+:2021E0000500607A012814BF012021208DF802006846F3F751F99DF8140050B90398616823
+:20220000227A406C07F046F8684602F0C5FB9DF8140006B010BD0000F8B507464FF6FE7008
+:202220003E78B881002006B3104E32887568044619E0A10001EBC4016B5C13F00F0F10D183
+:202240003878685478886D18391D6880281D07F0B7FDBC81284607F0FFFD32887568012009
+:202260001446641CA4B2A242E3DCF8BD3005012030B5ADF1140D684607F0AAFA00206946C4
+:20228000F6F796FA0E4C6946A0600120F6F790FA60604068007806F07BFC28B92078B52184
+:2022A00000220823FEF7CAFF064DA068294607F046FF6068294607F042FF05B030BDC046F6
+:2022C0007CFB0020098A020003B40021F0B505AF3846ADF11C0D01AAFCF7AEFB002818BF16
+:2022E000002015D10D4C2069FAF758FE002506460095E18E94F8330001AA0323F0F788FA41
+:2023000008B9BDF8125020693146FDF741FA284607B0BDE8F04002B07047C0465CFC0020D5
+:20232000F8B50D46064605F005FF04462946304606F0DAFA071C18D0386808F0ADF8384699
+:2023400008F0B2F80B4901F108000068B84207D000E0084601698F42FBD13969016101E03A
+:2023600038698860384602F017FC204607F0C5F9F8BDC0468004012038B5134D95F83901C2
+:20238000002410B91148007860B107F01FFF95F83B11002906BF012185F83B11012408F08A
+:2023A0009FF80CB1002038BD022004F09FFB0E20F7F78AFB05F04EFF01280EBF01200020EA
+:2023C00085F83A0138BDC046101500200AC20200144BB0B511F1800F43EA0202C2F31502E5
+:2023E00008BF071C19D090F9004000277F2C0FD00546D5F801406FF39F54A34208D095F997
+:202400000040A14204DB15F9054F7F1C7F2CF0D137B107EB87077F1F3F18D7F80100B0BDB7
+:202420001046B0BDFFFF3F0038B507F0CFFE0E4C05462078012813D00C480D4A3121002382
+:2024400002F0A8FE0B480C490422082307F042FA0A4A4FF0FF300121FFF73CF901202070F8
+:20246000284608F03DF838BD04060120EC110120BDBF0100081201202003012080A903005B
+:202480003EB5144C05466068017060684270287A022818BF0F2816D129884FF6FF708842FB
+:2024A00005D0C21E8A4202D0801E88420BD102238DF8083007F0FAFC69463622ADF800000A
+:2024C0002046FEF72BFB2046294636220223FEF725FB3EBD98FD00204EF68851CEF2000186
+:2024E00008684FF0F00340EA034008600C4885460C4885446F4607208743BD460A486F4679
+:2025000007600A48002803D07946491D8E460047F8F73CFF06F05AFF07F06EFFFEE7C046FF
+:20252000003A012000060000EC05012085A20200FEB506461248B5680078124C8DF800002E
+:2025400003E0686A08B107F04DF92188304607F0BAFA6846012100F029FE01A8012105F05F
+:202560001DF821880746304607F0B6FA002F18BF381C04D19DF804004008E2D20020FEBD94
+:202580005BBF0200A413012010480078A0B91048007888B90F48007870B90F48007858B935
+:2025A0000E48007840B90648007828B90548007810B90548007808B10020704701207047F2
+:2025C0000E0501200F0501201005012005140120071401200A140120001401200614012037
+:2025E000F8B505461348002133230A460479FF2C06D0078A27B1002D06BF0F44B9B20282A6
+:202600005B1E00F12400F1D1094832234FF6FE7430F81C6FB44206D0078B27B1002D06BF32
+:202620000F44B9B202835B1EF2D10846F8BDC04650080020E40D002038B504461248007880
+:202640000D4640B11149608908310988814203D101F062FF38BD60890021FCF7C9FE60B176
+:20266000807910F0180F08D0688E00906189627F2B8DA08900F022FD38BDA08961890022F7
+:20268000FEF7B0FC38BDC046B4FE002016FB0020FEB5144C154604F1280217681E46FFB17B
+:2026A0003A69EAB101228DF80020BA6AADF80200002AADF8041008BF002003D09DE8030024
+:2026C0009047A76A854208BF00200AD03C699DE803002A463346A047012808BF0A2000D0A3
+:2026E0000920FEBDD4DB00202DE9FE43134C06462068984617460D4607F07AFE814629466A
+:202700003A463046FCF7F0FB07462068494607F06BFE5FB90848006800900196054C029542
+:2027200021880022DD23404607F05AFE3846BDE8FE83C04610AC0200D4AD0200ACAB0200B5
+:2027400098B50446A1682079FFF72CFA207B00BB206807F0A1FE0F498868A04207D000E0CF
+:20276000104602699442FBD12269026101E020698860C86800222261CF6817B9CC6004E0CA
+:2027800010460269002AFBD1046108784968FFF709FA98BD8004012098B5426802F003010C
+:2027A000012920D1D1081ED2104903680F681C7DCFB139798C4203D03F68002FF9D112E0FC
+:2027C000B96881B19F8817B1FF1E09D00BE0120904D2C07A38B9086800B18047002098BD5D
+:2027E000EFF710FE98BD012098BDC0460C18002038B505460021142007F0FCF900240A2009
+:20280000002107F0F7F9C4F1070045FA00F1092001F0010107F0EEF90A20012107F0EAF9A4
+:20282000082007F08FFC641C082CE8DB0A20002107F0E0F91420012107F0DCF94FF42F7058
+:2028400007F080FC38BD7FB506460020029008981D46009002A801903046FDF7E6FA04467C
+:20286000012C03D12846314605F09BFB022C0CD102980268006820B92846314605F07EFB44
+:2028800003E02846314605F02BF8042C03D12846314605F073FB204600907FBD1FB50446BC
+:2028A0000021AB200DF1060200F05EFE06F0C2FC01460DF1060006F09BFBA8B120460DF192
+:2028C000060105F048FB88B10DF10600694605F0ABFF18B90098007930B907E00DF1060078
+:2028E00001A905F051F808B9012000E0002000901FBDD0B51F46144606460B461FB30520CA
+:202900003873187880B95968381D06F0B7FC012E04D05968384606F0B1FC0FE03846002111
+:202920000422FCF713F809E002280CD1191D3846082206F0AFFC0EB1C520387307F10800B5
+:20294000214606F09BFCD0BD70B5418846680325B1FBF5F06843081A18BF00201ED1B1FB42
+:20296000F5F0C0B2044600EB4000401C80B207F093FC98B1047000210DE0327811FB05F3FE
+:20298000C4186270B4787278491CC9B2C318F61C02EB04225A8002788A42EEDC70BD00007C
+:2029A000B0B505462C680F4607F010FC10490978012901D1217819B107F092FD0020B0BD2F
+:2029C0000121217007F08CFD07B9084F38782072786820613878022814BF0020B868E060DD
+:2029E0000B20F7F771F82846B0BDC04694C202001505012090B5ADF1140D07F09DFB071C2B
+:202A000008BF002410D001248DF800407888FF212422ADF80C003846FBF798FF802087F8C4
+:202A20002100684603F0BAFF0020042105F064F8332804DA034901200870FAF7B1FE204661
+:202A400005B090BD3504012010B503F0BFFF114C14202146491CFDF7D3FB0A202146FDF700
+:202A6000CFFB09202146FDF7CBFB0B490820FDF7C7FBB920FFF7BCFE142004F0C1FB0A2079
+:202A800004F0BEFB092004F0BBFB082004F0B8FB10BDC046006200200220002002461348AD
+:202AA00098B570300168476D01F00103002007F004071F4318BF0120930802EA000006D33B
+:202AC00001F002040023204318BF01231846D20806D301F004010022084318BF01221046BA
+:202AE000002814BF0120022098BDC046D02008402DE9F043171C0D464FF00009ADF1240D1F
+:202B000019D0DFF83C804603202FACBF20243C1C4046006871196A46234607F0ADFA4846DD
+:202B20006946224605F0D0FE3F1B2D19BFB2ADB28146002FE8D1484609B0BDE8F083C04637
+:202B400068FC002010B510481249104A006800F00F0083025C1E08461360E1430160012052
+:202B600004F0FEFB044607F031FB094A116831B107F0B6FC34B1204607F0E6F910BD146042
+:202B800007F0AEFC10BDC0463024034098130120941301209C130120084608B500F000517A
+:202BA00000F00400084316D00B480068016801208847012808D007F05BF93221B1FBF0F1B0
+:202BC000064806F0A5FD08BD0549064828310860054807F02FF808BDE001001088F600202E
+:202BE00030F50020F95E0000F4120120F0B5134E00274FF6FE75ADF1140D07F042FA0446F1
+:202C0000301D0088A042F8D007F03EF9A042F4D0204601F061FF0028EFD1002CEDD08DF854
+:202C20000070ADF802406846FBF7CAFE0028E4D1A542E2D0204605B0F0BDC0461AFB00205C
+:202C4000F8B50D46044607F0C1FA06466768A0682946874205D1304607F042FC4FF0FF302E
+:202C6000F8BDE568A26923686D1CB5FBF7F078432D1A05FB0230F8F739FFA0686169E5602A
+:202C8000401CA060814238BF6061304607F028FCA068F8BDB0B5171C0C460546ADF1280D07
+:202CA00019D01048B9680068884204D8B1F1FF3F18BF002014D1684600212822082307F0AD
+:202CC0008BFBFA680792386804907B680593B96806916A4600E000222846214606F0A4F9F2
+:202CE0000AB0B0BD7CAC02009EB507460C46084600226B46032100F02FFFD0B1029A108879
+:202D0000874216D00B4948783FB90020108048784FF40051FFF704FB06E017804FF40051EE
+:202D20004FF47A7207F017FA0348016809B1204688479EBD4CFF0020E002012038B5134CA4
+:202D40000546A06848B9182007F0A6FAA06008B1002141610146056115E0A4681434206856
+:202D600020B100F1140420680028FAD1182007F093FA2060011C06D0486910B10020486194
+:202D800021680D612168084638BDC0467004012098B544684088401E10F0030F18BF0020AD
+:202DA0001FD18008C7B2384600EB4000801C80B207F072FAA8B12178477001708FB1641C6E
+:202DC00000226378217801EB032183185980A1787F1E00EB020302F1030204F103041971B5
+:202DE000EFD198BD12492DE9F04180460120114F087017E07D887E6820462946324607F037
+:202E0000FDF870B9B8F1000F06D120462A460021334606F0E1FD04E020462946324607F099
+:202E2000F3F808373C88002CE4D1BDE8F081C046B9FE002010AE020070B50646B5682968F1
+:202E40007468486820F002004860204607F0BCF9D4F8CC0003F0CDF804F1300007F0CEF9E7
+:202E600094F8F80018B904F16C0007F0C3F9304602F0E4FE287BF6F731FB04F11C0005F0DD
+:202E800023FC002084F8FD0070BD10B50C466168ADF1180DE9B1A068D8B1087800280CBF0C
+:202EA0003B203A2011226B46002106F095FD607088B96068A168007808709DF80000A16860
+:202EC0004870A06810220DF10101801C06F0E2F901E00220607006B0012010BDF8B5064623
+:202EE0004FF6FE7000217080301D06F069FF304604F0DAFD351D0746012F13D1B0890A4BE1
+:202F0000840004EBC004181D0068241860887080241D204605F088FD012803D128462146D6
+:202F200006F04EFF3846F8BD30050120D0B50446122005F0D2FA07460F480668D7B13846EB
+:202F400000211222FBF702FDC720387000237B70A0893882A07A21460A22B873381D06F088
+:202F600099F91EB9384605F09FFBD0BD3079394600F092FBD0BDC0462C1A002011482DE941
+:202F8000F041076800260760B7B1DFF83C800124D8F80410B7FA87F0C0F11F0082008D58A1
+:202FA00004FA00F39F43002D08BF1E4302D08958C0B28847002FEBD116B1304600BF00BF4F
+:202FC000BDE8F081E0200240D4C2020070B5124C054694F84A000E46ADF1200D042814BF3F
+:202FE0000828C22016D0E564684600211C2284F85260FBF7ABFC00958DF8056001208DF897
+:20300000040000238DF80730022284F84A206846FBF702FE08B070BDE4FA0020F8B5124C35
+:2030200006466069002710B1804700B90B272069BFB9F9F7B3FF27780546381C0DD1E08EB4
+:20304000C0F5005000B2864203DC002E18BF042703D10020E6F7B8F8677820692946FCF797
+:2030600097FB3846F8BDC0465CFC00203EB504461048052100224FF6FF75801E30F8043F6E
+:203080009D4201D09C4204D0491E02F10102F5D13EBD052A0DDAFF210422FBF757FC064DBC
+:2030A0000220ADF8004029888DF80800684604F02CFC3EBD200100202CFB00202DE9F04137
+:2030C000044698460D46101C06AF17D108460021FCF78EF9061C17D0B079400814D33888A2
+:2030E00041462246F4F756FC4FF6FE7181420BD0708028460C222546044600E00B2220469E
+:2031000029460023FBF72CFFBDE8F0811CB504463A220120694606F068FEE0B99DF8000019
+:20312000A04216D001200DF101013B2206F05DFE88B99DF80100A0420DD19DF800009DF837
+:2031400001108842A8BF3B2007DA9DF80100F8F72DF83A201CBD4FF6FF701CBD38B504682E
+:2031600094F83000042808BF0F4D17D0022805D001280CBF00204FF0FF3038BD216A04F167
+:20318000340006F0C4FC0DE0012006F0DBFF281F006810F0030FF7D0F8F710FFA06A616A0C
+:2031A0008842F1D8E06A38BD0C800240F0B5124C074600250E46ADF11C0D2068029577B990
+:2031C0000121009106AB01933A788DF81820694606F066FF48B1761E0AD07F1C206800965E
+:2031E0000197694606F05CFF10B94FF0FF3000E0284607B0F0BDC046A013012098B506F031
+:20320000E5FF04460D48007898B90D490F78012037F07F0707D10B490F7837F07F0702D184
+:2032200009490F781FB180F00100C0B208B103F06DF9204607F054F998BDC04606140120B0
+:20324000051401200A1401200014012038B5124C22680546D2F8EC0050F82100D2F8E010C7
+:2032600008602168D1F8E41008600A480068A84203D82068D0F84C058047280803D32068C3
+:20328000D0F84C05804706F0A1FF07F029F904F0DDF938BDE000002014010020124AB0B5EA
+:2032A000032311464C88A04208BFC52015D05B1E01F10401F6D1114603234FF6FE754C880A
+:2032C000A54208D05B1E01F10401F8D1111F032211F8047F27B94880002004220A70B0BD40
+:2032E000521EF5D1C720B0BD28FC00202DE9F047114E00258A460746A846B8F1000F18D183
+:203300006C01A4EB8504A01900F10209484605F08BFB58B1305B874208BF48F00A08514665
+:20332000484605F065FE08B148F0A0086D1C322DE3DB4046BDE8F0876C080020F8B5124C27
+:20334000607801281CD004F5C27600204FF4405731467F1E41F8040BFBD1E82131604BF652
+:20336000FC75A851A5F1E801C6F8E81006F1E801A160F9F76FFCE060A660012060702561B5
+:203380004BF6BE20F8BDC046501A00207CB5124C0346A06A16460025E0B18269D2B1012244
+:2033A0008DF80020826AADF80230ADF8041082B19DE80300904760B1864208D1A06A8269B3
+:2033C0009DE803009047012808BF0A2502E00C2500E0092528467CBDD4DB0020F8B50546E0
+:2033E0000C46122005F079F8071C1ED000211222FBF7ACFA7C203870002078702188B980B7
+:20340000A17AB973267B014606B1012139740146E07A00B101210822B81DF973A11C05F066
+:2034200039FFE8B2394600F037F9F8BD7CB5124C024620680E460025D8B1C169C9B1072139
+:203440008DF800100223ADF80230ADF80420026A72B19DE80300904750B12068C4699DE8E9
+:20346000030041223346A047012808BF0A2500E0092528467CBDC046F8FD002030B500248E
+:203480000822ADF1240D214605A88DF81C40FBF75DFA05A807A96A46FBF7DAF905469DF843
+:2034A0001C0078B1684621461422FBF74FFAFF20294614226B468DF81000042003F0C2F866
+:2034C000204600E0012009B030BD98B5437B0A460021042B1ED1077CE7B94769D7B138783A
+:2034E00010F0030F16D150687C7B437DA34211D112887B899A420DD1C288BB889A4209D102
+:203500008278BB789A4204D0007800F00C00042800D10121084698BD30B50C466068ADF1FB
+:20352000140DD8B1007800280CBF3B253A25616848788DF80000887820B90DF1010003F0DE
+:2035400095FB05E00DF10100C91C102205F0A2FE284611216A4606F057FD00E002206070DF
+:2035600005B0012030BD000038B5104C15466269E368A488A13816D0401E0AD0401E02D07B
+:2035800008380BD038BD0A48006868B18047044609E04AB108462946904738BD28461946FD
+:2035A00006F0FAFD38BD2C8038BDC046AC00012004030120E0B5061C1FD0062004F08DFF41
+:2035C00007460E480568C7B1384600210622FBF7BDF9C521397000237B703178F97071785C
+:2035E0003971B178281C797103D1384605F05CF8E0BD0079394600F04FF8E0BD2C1A002060
+:203600001149C8B570310A684E6D410806D302F0010106F0040600270E4300D001278108F6
+:2036200005D3002117B1930828BF01210F46C00805D3002017B1D10828BF01200746002FEB
+:2036400014BF01200220C8BDD020084038B5491D04468DB2294604F0E7FF20F002002946F1
+:203660000246204605F0DAFA0A480C21493014FB0105287860B12046022104F0D5FF20F0B4
+:20368000030002210246204605F0C8FA0020287038BDC0465CFC0020F8B505460F1C08BF8A
+:2036A00005201CD00E4C2078C0B1241D14F8181F8D4211D104F03EFD0646394604F108006A
+:2036C00003F042FD28464FF40041FEF76BFA304606F013F80020F8BD401EE7D10320F8BD32
+:2036E000501A0020042870B51ED1104D05F5AC70064606F067FAB8B106F0BAFB0446304616
+:2037000006F056FD6043B0F5967F0DD2304606F055FD052003F0EAF92846012180F8311022
+:203720000421E03006F070FD002070BD30F5002098B5114C0146323C94F82C000727C0B9A1
+:203740000846B4F8481002F063FF011C11D094F83100012807D1887804F0F2FE497881429F
+:20376000A8BF081C02E0887804F0EAFE071C08BF0727384698BDC04616FB002070B50E4665
+:20378000044606F023FDA16805463046B1B1A2692369216802FB0311F8F7A8F92069A1684A
+:2037A0006368401C491EB0FBF3F2A1605A43801A2061284606F094FEA06870BD284606F0A3
+:2037C0008FFE4FF0FF3070BDFEB5104D6C682079F6F77AF906F0FAFC2E680746307880B934
+:2037E000684606F00FFAA079094A0190617900956B46301D01F0CEFC01203070284605F0D3
+:20380000B5FA384606F06CFE2846FEBDE0C30200ABA0020010B5002104461822ADF1180DD3
+:2038200021726846FBF792F80B226846214605F031FD08220DF10B0004F10B0105F02AFD16
+:20384000A08AADF81400A07D8DF8160003480068D0F81C126846884706B010BD14010020EF
+:2038600030B5054610484830048800213C22ADF13C0D6846FBF76AF802208DF80C00ADF8FC
+:2038800000508DF808003121ADF80A400DF10E0004F0A4F803480068D0F8881268468847DC
+:2038A0000FB030BD14010020E4FA0020114A80B557680146002F08BF012019D0384643686A
+:2038C0001B78994206D100685060384601F064F9002080BD076857B17A681278914204BFE9
+:2038E00039680160F1D038463F68002FF4D1022080BDC04620050120114980B501F13F027F
+:203900001278120928BF012017D2FF2804D1FF200A490870002080BD70B1F1280CDACF6877
+:2039200057B179680A78904203D03F68002FF8D102E04F78002FEBD1022080BDDC020120E6
+:203940004CFF0020F8B506460F4D104F7388002417E0A20002EBC402921951689068D26847
+:2039600052B9AF420BD00A7855F822200346491C08461946904701E0F8F7B8F87388641C32
+:20398000A4B2A342E5DCF8BD50C902005CC9020010B5ADF1180D05F0F5FC012801D106F0D5
+:2039A000D9FA00208DF802008DF80400029001218DF80310074C60706846EDF7E7F90649D4
+:2039C00020790870FF232371E12001F025FE06B010BDC0462004012020FB00202DE9F041BB
+:2039E0000F4E00254FF6FF70B570DFF8388035702C46F080B368F57009E008EB84073868CF
+:203A000018B104F051FEB3683D60641CE4B2002CF3D01BB1284601460A469847BDE8F08117
+:203A2000200401205819002010B506F0CFFB0C49097879B90B49097861B90B49097849B95D
+:203A40000A49097831B90A49097831F0020108BF012400D0002406F043FD204610BDC04661
+:203A600005140120071401200A1401200014012006140120114980B50B68071C1DD0181CDB
+:203A80000DD00022874204D0024640680028F9D105E0834219BF406850604068086038681E
+:203AA000006A01F079F8386801F076F8786908B101F072F8384601F06FF880BD38050120D5
+:203AC000F8B504F037FB104900252F463E462C46CB68486012E0110809D21FB914461D46D4
+:203AE00001270AE02968A4188918296005E082F000420027B44288BF261C9B181A68002A9F
+:203B0000E9D105F0FAFDF8BD501A002090B5114C2468ADF1240DBCB1276AAFB101248DF8BB
+:203B200018400424ADF81A400024ADF81C400091019202930C9A039206AB049093E803002A
+:203B400022461423B84708B10A2000E0204609B090BDC046FCDB00202DE9F04114460D46A7
+:203B600005F070FA9846071C08D03B7C00204FF00C0C01E0401CC0B2834202DC0020BDE8C8
+:203B8000F0817A6910FB0CF1565AB542F2D189188A889442EED107C988E807000120BDE80A
+:203BA000F081000010B583899A0002EBC3020E4B1B1D1B6801291A44144618BF02290AD1A4
+:203BC0004288022962800BD1001D04F02DFF08B90020207004E0121D011D104606F0F0F81F
+:203BE000204606F039F910BD3005012010B5104CA41EA07888B10120207004F0F5FDA17830
+:203C0000FF290ED00020094BA07018784FF47A724A43802106F09FFA03E00020207004F017
+:203C2000E3FD4120214601F0F7FC10BDE4FA0020360401200E49086820F0020040F408704D
+:203C400008600C48032140F8041C41F230018160012101605022826001604FF4CA6282605E
+:203C600001604FF48652826001600348016070470000046058600440004104402DE9FC47E4
+:203C80000F4C8046606900271D4692460E46B94608B1804758B157B904200090E06806EBFF
+:203CA00048312B46524606F0A7F8814600E00B27B9F1000F48BF01273846BDE8FC87C04680
+:203CC0005CFC00202DE9F0410746B86840681C460D4690462919884238BF6FF0030010D33D
+:203CE000094E30684FF0FF3105F011FF3846294642462346FAF76EFD0446306806F07CFAD9
+:203D00002046BDE8F081C046A81301200E4A98B512780F460446012A01D003F0C9FA0B4872
+:203D20000078A0420CDD07B9064F09480C2114FB01F140588069394602462046904798BDD2
+:203D4000002098BD18C40200090601204CBF020070C102000F49A1F1240000688008FAD3D5
+:203D60000D48001F0068012819BF0122111C20210122074840F8251C002340F83D3C0823EB
+:203D8000C0F8FB3FC0F8FF3F40F83D2C7047C0463D400C407C600C405016002098B506F023
+:203DA00015FA0446F9F756FA0D480021001D0170032002F083FE204606F092FB074CA0688C
+:203DC0000146022088470746102001F0C3FF1FB1A06801460320884798BDC046FCC1020050
+:203DE0004416002070B50E4615460446082300212422ADF1280D684606F02EFB0020069043
+:203E00000590ADF81000084800684FF47A71AAB26B46B1FBF0F080B231464243204606F04F
+:203E2000D7FA20460AB070BD40C40200F8B5104C074604F1080005680E46281C09D00179B3
+:203E40008F4202D1C1888E4210D0054600680028F5D10820F8F7FEFE40B10771C680002141
+:203E60000160A16800290CBFA0602860F8BDC04698FD002038B50178012914BF0025082537
+:203E8000411C8078012814BF082009200B78C0F16C00C4B22BB1052005F044FA241A0D3CAF
+:203EA000E4B20548007820B105F03CFA241A0E3CE4B2641BE0B238BD14FB002002461048B8
+:203EC000F8B5801F06780D46CEB1001D4FF6FF7310F8141F4C0810D30DB1890809D2C78887
+:203EE0003FB1BB4205D0018989188F42A8BF8FB20781017801F0FD010170761EE8D1F8BDF9
+:203F0000F60C01200F4910B50446C87808B1886B10B90020C870486B04F0B4FF0A480068F6
+:203F200038B9012C14BF052003200021E4F76AFB10BD012C14BF012100216420E0F7CAFFB3
+:203F400010BDC0464CFF0020E4FE0020C8B50F480F490278CF68FF2A0F610ED177B17868C4
+:203F600006781EB1F12E01DA46786EB93F68002F0F61F4D102E03F680F610FB90020C8BDA4
+:203F8000786803789A42F6D1C8BDC046DC0201204CFF00201FB54FF6FE71814219D00E4AA2
+:203FA000042300245178012903D011B95188884205D05B1E02F10E0204F10104F2D1042C45
+:203FC00007D1ADF80C00042168468DF8001002F0E5FC00901FBDC0466C010020B0B54FF07A
+:203FE0008054D4F8D8010E4D80680146284688472A1D116804F5EC74C7B241F0300111601C
+:2040000067B1206840680021024628469047206880680146284688470028F8D13846B0BDDA
+:2040200000400340BCB50546FEF782FA002818BF4FF0FF3017D10C4CC72021888DF800000E
+:20404000284605F040FD68460121FFF7AFF821880746284605F040FD002F18BF381C02D190
+:204060002846FEF765FABCBDA4130120104810B50078ADF1780D042815D0082813D000242D
+:2040800090B9212003F050FB74280DD12120214674226B4605F0A0FC30B99DF8260004288E
+:2040A00018BF082800D1012420461EB010BDC0462EFB0020104A98B5D768C7B10D48006898
+:2040C00000690078FF2810D03B7883420DDC7978C918814209DD79681778C01AC0B20C56FE
+:2040E000F81AC0B20856844201D0012098BD002098BDC046180100207000012070B505461C
+:2041000006F064F80E4C2268D2F8D810D2F8F82406462846904730B92268D2F8DC10D2F84D
+:20412000F824284690472068E83001680968A94202D1D0F8F0038047304606F0D1F970BD01
+:204140001401002038B504460D46142004F0C5F9011C0BD00C2008708C7000248C730A4BAA
+:204160004D701878FFF798FA204638BD204604F007FF38B106214173007B02F0CFFC20464D
+:20418000FAF730F9102038BDE4FA0020F8B5064614460D46162004F0A0F9071C19D000214C
+:2041A0001622FAF7D3FB4820387000237B70BD802088A11C0822F88007F1080005F06AF84F
+:2041C000A07A07F1100103F0F4FBF0B23946FFF763FAF8BDD0B504460C2004F07EF90746FE
+:2041E0000D480668BFB1384600210C22FAF7AEFBCC20387000237B706088F8802088B88043
+:2042000020793872A079B872607978721EB130793946FFF741FAD0BD2C1A002098B505F0F8
+:20422000D5FF0446F9F716F80028FBD0032002F045FC0A4900200870204606F051F9084C34
+:20424000A0680146022088470746102001F082FD1FB1A06801460320884798BD481600204D
+:20426000FCC1020098B5426802F00301012919D1D10817D20C4903680F681C7D97B13979F2
+:204280008C4203D03F68002FF9D10BE0B96849B19B88212B06D1120938BF002003D3F2F7A0
+:2042A0001DFF98BD012098BD74040120B0B505460C460E2004F011F9071C19D000210E22F3
+:2042C000FAF744FBE52000233870294608227B70B81DBC8004F0DEFFF22004F0FDFD18B9A7
+:2042E000384604F0E1F9B0BD00793946FFF7D4F9B0BD38B50546297D032905D002291AD1E8
+:20430000808905F0E9FE03E005F10C0005F014FF041C10D0687860B1F12818BFE12804D10C
+:20432000A079012801D105F063FFA07918B1401E00E00020A07138BD90B50F1C4FF0000419
+:20434000ADF1340D18D00168086AA8B1C97F6A46F1F7B2F97888BDF80C1088420CD19DF8CA
+:204360000200012808D10A980178012904D139788078814208BF012420460DB090BDB0B5F2
+:20438000054668886C68410828BF002019D2401C80B205F081FF071C12D0688840103870E3
+:2043A00000200AE06278217807EB4005431CA41CD8B201EB0221A5F8011039788142F1DCA2
+:2043C0003846B0BDF8B505460C460C2004F085F807460C480668A7B1384600210C22FAF7E6
+:2043E000B5FACB21397000237B703C72301C7D6003D1384604F058F9F8BD00793946FFF75A
+:204400004BF9F8BD2C1A00200E4870B50168D8310868006810B94868006888B105F0D6FE95
+:2044200006460948001D056802F0A4F80446304606F056F8641CA5428CBF281B012070BD80
+:20444000002070BD14010020E000002010B504460E48ADF1180D047005F0B6FF002115223C
+:204460006846FAF773FA152102A22346684604F097FEFEE75B417373657274205265617359
+:204480006F6E5D2030782530325800C0C8E800200F4908B5D1F878020B68020F03F0FF03DA
+:2044A0007F2B88BF002304F081FB01464FF0FF3004290CD11146012908D9891E03D0491E76
+:2044C00005D1153300E00B3358B208BD0A2008BDA01000502DE9F041876878681D460C4617
+:2044E00090466119884238BF6FF003000FD3094E30684FF0FF3105F00AFB396840462A4678
+:204500000919F7F7F3FA306805F076FE0020BDE8F081C0469413012010B50E4C20784FF49F
+:20452000805100F019FB88B90B48C27C407E012814BF032101210020F0F7CAFB20784FF42D
+:2045400080514FF47A7205F006FE10BD0120E07010BDC046E4FA0020ACFE0020B0B505F02F
+:2045600035FE05460B48017801290FD00A49024601230878137048B1084C0746206880681C
+:204580000146204688470C347F1EF7D1284605F0A7FFB0BD0A06012050BF02005CC3020021
+:2045A00010B5ADF1280DFAF7BFFA00248220182221466B4605F010FA88B906A8214610221A
+:2045C000FAF7C4F90DF1010006A9102204F05CF828B9684621461822FAF7B8F901242046A8
+:2045E0000AB010BD3EB50E4D0C462C7224B9287810B9032004F0D2FE5035296851B1094860
+:204600008DF80040428FADF80220C08FADF80400684688470220002102F0F8FA3EBDC046A0
+:2046200034FD0020E4FA0020F8B50F4C054660681E46174605F0B0FD62680020012F107211
+:2046400004D16168087A40F040000872012E03D1117A41F080011172204629463422092336
+:20466000FCF75CFAF8BDC04698FD0020F8B50F4C06AF6568D7F800E08446184603E01EF827
+:20468000016B05F8016B0646701E002EC0B2F6D13F79002F07BF0025281C40200025E07019
+:2046A0006046FCF73BFAE570F8BDC04698FD002038B5562003F038F8002808BF012015D0EC
+:2046C0001624B0FBF4F0C5B2284603F069FB012808BF02200AD014FB05F0054CE36882B215
+:2046E0000021562005F078F90020A57038BDC046F00C01202DE9F84306460E48401C90F899
+:2047000000905FEA030814460D4610D0A01CC0B203F0E3FE071C0AD0B81C2246414604F072
+:20472000B9FD3E70484639467D70FEF7B5FFBDE8F883C0464CFF00200F4B10B51C78844268
+:2047400018DD142410FB0430FF294FF0000400F11800048108D0012919BF017801F0FE01B1
+:20476000017841F001010170FF2A03D0017841F00201017010BDC046F00C012098B50E4C6B
+:20478000071C03D12068D0F84C05804705F01EFD0A4A1178B943117005F0A2FEFEF72EFD9B
+:2047A0006068C068007828B92068D0F8582400200146904798BDC0461401002006140120DB
+:2047C00098B50E4C083CA06800F1400319680F6837B9D0F84C058047A3684033186807687D
+:2047E000074810300068044605F0CEF8F860204604F08EFB19680968088298BD140100207C
+:20480000DCFF002010B504462168086AADF1380DA8B1C97F01AAF0F74FFF0A48BDF80E100A
+:204820003A30008888420AD0206800889DF821200090BDF810004FF6FE73FEF73FFC0EB003
+:2048400010BDC046E4FA0020F8B516460C46054601F0C4FE071C16D000211C22FAF776F867
+:204860003D80002E7C8106BF0120B874BE7406480078012818BF072002D1304603F060FE85
+:20488000787406203874F8BD74FB002038B50F4C0D463A3CB4F8481001F0BAFE011C10D05B
+:2048A000887803F04DFE497859B150B194F83120012A02D18142B8BF011C081C01D0854200
+:2048C00001DA002038BD012038BDC0461EFB00200E4A014608B5042002F07EFF01F00EFCA9
+:2048E000022005F0D7F9032005F0D4F90848006850B14FF6F772131DC1881140C180194021
+:20490000C18000680028F7D1002008BD057802002C1A0020F8B507467D68002616E0606970
+:20492000C5F8C8006068666110F0704F06D128B1062002F0C3F8042002F0C0F8022002F03F
+:20494000BDF8D5F8BC20384621469047D5F8C840002CE4D1F8BDF8B5064614460D46082004
+:2049600003F0BBFD071C16D000210822F9F7EEFFE020387000237B703E717D71F220FC807A
+:2049800004F0AAFA18B9384603F08EFEF8BD00793946FEF781FEF8BD10B50446207DA0B9D6
+:2049A0002046F0F795FF206918B10A48016820468847207D20B9E068E7F75EF9207504E068
+:2049C000E06800F0E9F80020E060204605F040FB10BDC04678020120D0B50446042003F074
+:2049E0007CFD07460B4806689FB1384600210422F9F7ACFFC621397000237B70301CFC702A
+:204A000003D1384603F050FED0BD00793946FEF743FED0BD2C1A0020F0B515460E460446B7
+:204A20001F1CADF1240D08BF00230DD0684600212422082305F010FD3B78ADF81030B868AB
+:204A400006907A6805926B46204631462A4605F0BFFC204609B0F0BDB0B50C460546171C98
+:204A6000ADF1280D08BF00220DD0684600212422082305F0F1FCB8683B7806907968ADF88C
+:204A800010306A460591034B2846214605F0E0FC0AB0B0BD6003012038B504460D46084619
+:204AA000FDF7DCF80C28A8BF4FF6FE7011DA094901EBC001487849686160207030B1421EF3
+:204AC00001EB4001627031F8020C38BD00206070284638BDF40100204FF6F87280B500213E
+:204AE000801A03280BD9001F07D0401E03D0801E0ED1012704E0022702E0042700E0082718
+:204B000004480078074202D107B1012100E00221084680BDEDFB00200E4938B58A68CD68DA
+:204B20001B3800FB00F482FB04234443C5FB04234C68C4FB002312091807024308681B1170
+:204B4000C11780184FEA104041EB03010904084338BDC0469402012070B50C46064603F06C
+:204B6000E9FA05462146304603F0BEFE002808BF00240AD0006802F089FA064909684FF4AE
+:204B80007A72B2FBF1F1B0FBF1F4284604F0B5FD204670BD40C40200B0B5071C19D003F0F9
+:204BA000C9FA0C4948604C690B6957F8042C15080BD322F000428D6847F8042C9B183F1FC9
+:204BC0000B61AF4238BF8F6001E0641C4C6104F094FDB0BD501A002070B505F0F7FA0646B1
+:204BE0000C48001D007850B108480068C0680546074800243C2101222346A84700B101247F
+:204C0000304605F06DFC204670BDC046A401001000A00C404416002070B504460C480668DB
+:204C20000C4800682568006B8047801B000B2060A84202D240194008206040F6C411814226
+:204C400004D3B0F5967F02D24FF49671216070BD38F500208C01001070B500260D460D4B17
+:204C6000467134461E202A7B13F8011F8A4204D0401E04F10104F7D102E02846FAF7BCF840
+:204C80001E2C06D106202C686873607B3146FFF759FA70BD4D010020F8B505F097FA0D499F
+:204CA0000B4FCA680C684B680D698E6882EA92024C60ED19CE6082EA42028B6082EA0412D8
+:204CC0000D6154400C6005F00BFC28460019F8BDC587050008130120C8B50E4601460A4837
+:204CE0000778002077B1094A12788A420ADD06B9074E084A0C2011FB00200168C9680A46B5
+:204D000031469047C8BDC0460A06012050BF020088C002005CC302003EB505460EE06A6A0D
+:204D2000AC6AA41A082C28BF0824E869694680182246F6F7DBFE686A00196862A86A696AF8
+:204D4000884206D903486946FEF718FDB0F1FF3FE5D13EBD081201203EB504460C486D4697
+:204D6000016840682960002C686014BF201C684604F018FF04B12546064C2946204605F0A1
+:204D80000BFA71200821224605F03EF93EBDC04604C10200F8FE00200E4830B50468ADF19D
+:204DA000140DA4B100252079A11D12228DF800000DF1020004F06EFA2946082014226B466E
+:204DC00001F040FC24686B1CDDB2002CEBD105B030BDC0461C03012070B5041C0D46ADF1FE
+:204DE000180D09D045B1FAF741FF064604F1100005F086F8B04201D002200BE001A80090C1
+:204E00002246902300200146E9F7ACFB01A82946F4F784FC06B070BD7CB50E4C0125032649
+:204E200001288DF80050E17984F83E600BD0032904DB606A01F09AFA002001E0491CC8B2EB
+:204E4000E071294600E0002130462A466B46FFF751FC7CBD4CFF00200FB40E4890B500684D
+:204E600003AFADF1040D78B13C7801680A78944207D1BA888B889A4203D17A8849888A42B7
+:204E800003D040680028F0D1002001B0BDE8904004B07047040D012038B50E4C024604F147
+:204EA00014000068A0B182420DD00146886801E00146886860B159B18242F9D182688A60B8
+:204EC00003F0F2FB38BD8568606903F0EDFB656138BDC0464819002010B56FF001000C49B0
+:204EE0000C4C08702068D0F8E800006878B16068C068012101702068D0F8DC04804705F0AA
+:204F000065F905F0EDFA6168C9680020087010BD0D0501201401002008B50346104604F040
+:204F2000A9FA012907D00121022A01FA03F120EA010007D109E00121022A01FA03F141EA5C
+:204F4000000002D00249086008BD0249086008BDB81001209412012038B50D480D4C0168DB
+:204F60000A48083C056860682A1A2078800092FBF0F0D1F8D420527BD1F8EC1051F82210D3
+:204F800000F04AF80846656038BDC0461000012014010020E00000200E4870B50068E83070
+:204FA000016809680A4C4D6804F108010968A94202D8D0F86404804705F008F90646E5605A
+:204FC0002846F9F78FF9304605F08AFA70BDC046D8000020140100202DE9F0410D4C4FF6B7
+:204FE000FF7705463226A7F101081C3C34F81C0F854203D0AF4208D1804506D0A01C03F09A
+:2050000013FD10B9204604F0BCF8761EEED1BDE8F081C0466C0800201CB50A1C17D00023A5
+:205020000124E407A04238BF041C944201D95200FBE790425B41904228BF801A914201D21C
+:205040005208F6E7191C021C081C111C1CBD00B1C843F4F722F91CBD98B50C4604F032FF3D
+:20506000002700B101270B4A18329069211AB1F1004F08D8011B891DC90F05D1801DA0429D
+:2050800088BF041C00E0841D14600FB904F020FF98BDC04600200940F8B505F091F90028C1
+:2050A00008BF002013D00A480768002F0DDD0948046800250020294604F0ACFC0646B068DB
+:2050C000A0476D1C7F1E7060F4D14FF0FF30F8BD20C4020038C402000E4B90B51B680024E2
+:2050E000ADF1140D93B15F6987B107238DF808300223ADF80A30ADF80C000B4602A8009284
+:2051000003C82246B847012808BF0A24204605B090BDC046F8FD0020F8B5064634681746CA
+:205120000D4605F053F894F8251021B105F0D8F94FF0FF30F8BD012184F8251005F0D0F9CF
+:2051400028680FC80C3484E80F003A4630462946EDF7AAFEF8BD9EB50090171C01914FF0A0
+:2051600000008DF8080010D00346009A01999C5C595C9DF808207F1E03F1010381EA0401D6
+:2051800042EA01028DF80820EFD19DF8087007B901209EBDF0B514460D4606461F1CADF1B3
+:2051A000340D08BF00230DD0684600213022082305F002F97B680893386805903A7AADF89F
+:2051C00018206B4630462946224600F06FFB0DB0F0BD98B50446617820784018F7F73AFD50
+:2051E000071C13D022780021F9F7B0FB4FF6FE70788004F05BFEB8802078C0193861607841
+:20520000387502F04FFF7875A0783876384698BD00F003028A70C0F38302CA70C0F3811274
+:205220000A71C0F340228A71C0F300224A71C0F380224A77C0F3C022CA71C0F300320A720C
+:20524000C0F3403281F831208013C0B270472DE9F84316468846044602F06CFF276881462B
+:20526000002005462FB100E0401C57F80C7C002FFAD1864204D92046414601F065FF0125C9
+:20528000484604F03AFA2846BDE8F88398B503680021D9629F690FB10221397093F8301057
+:2052A00002290DD001290FD19A692AB91C69D96ADA699B6AA04798BDDC68D96AA04798BDE7
+:2052C00003F1340004F098FF98BDB0B500F02AFB071C18D0002410E007EBC400401C0546D0
+:2052E00004F02AFF38B10079012818BF022802D12846FDF77FFB641CE4B23878A042EBDCE7
+:205300003846FFF749FCB0BDB0B505461446102003F0E3F8071C15D000211022F9F716FB03
+:205320009520387000237B702088A11C0822B88007F1080003F0AEFF60893946F880E8B221
+:20534000FEF7AAF9B0BD000038B50C4CE168054699B1206988B1606978B16888884760B999
+:2053600007490A6868889101A1EB820122699047012802D161696888884738BDECFB0020F7
+:205380006CBC0200C8B5032003F0A7F807460B48066897B1384600210322F9F7D7FACA21EB
+:2053A00000233970301C7B7003D1384603F07CF9C8BD00793946FEF76FF9C8BD2C1A00206B
+:2053C00010F1240F00F1240103DB1C28A8BF3F2100E00021032001F00F030F22A0EB211086
+:2053E000C3F10F0102414FF6FF7343FA01F0024B40EA02401860704718A00C4038B50B4C91
+:20540000207888B10A4D287860B1022806D0012804D008480068D0F84C0580470020287066
+:2054200004F01CF80020207038BDC046041401200B06012014010020F8B54FF0805706460A
+:2054400007F5EC7420680A4D81682846884700F003003060D7F8D8014268002128469047B0
+:2054600020688168284688470028F9D1F8BDC046004003402DE9F0410C4D0646287800249E
+:20548000182705F11C080CE014FB07814A68964205D1C8684FF0FF3105F01AF82878641C0A
+:2054A000E4B2A042F0DCBDE8F081C046501A00200D4B70B50D4606460824B3F93000854217
+:2054C0000BD13046194604F0BDFB30B11AB193F83300024201D0184670BD641E03F1580394
+:2054E000EBD1002070BDC04678F70020F8B51C461546074604F06AFE9FB107F1280106C9BB
+:2055000007F1280307F120062943224383E8060096E8060007F120030D4344EA020683E878
+:20552000600004F0DDFFF8BD10B50446C8090AD2204604F0D1FD20B1007901280CD0022829
+:205540000AD0204610BD2146FF2001F0B9FF002808BF4FF6FE7001D00148008810BDC046F8
+:205560001EFB002038B5044603F064FE0146A01C03F03EFDA51C012809D10848016811B1F6
+:205580002046884748B9E07AF4F772FD38BD2088A27AE37A2946F1F749FC38BD88FD0020D5
+:2055A00030B5054600211822ADF11C0D6846F9F7CDF900240620214618226B46FDF768F845
+:2055C00038B9012D05D10620214618226B4601F039F8641C032CEDDB07B030BD38B50D4CDB
+:2055E000083CA068D0F8C81301208847054600208DF80000A068D0F83024694656209047BC
+:20560000A0680349D0F83024E2209047284638BD18DC00201401002038B505460C46E22DFC
+:2056200002D1094804F0B8FD522D05D1207818B907481C38007830B104480068D0F8302413
+:2056400021462846904738BD18DC002014010020D7FE0020F8B5044667680D464FB12678B4
+:205660003EB128883968098888420FD07F68761EF8D10820F7F7EEFA40B1056061684160AE
+:2056800060602078401C20700020F8BD0120F8BD08B5002101288DF800100FD00A4AD07804
+:2056A00040B1506B30B1D17003F0ECFB322003F06BFB08BD0320E2F7A5FF08BD0320012227
+:2056C0006B46FFF717F808BD4CFF00202DE9F843DFF83080164607460425002418F80E0FE9
+:2056E000874209D1404602F0A3FD28B1A642D8BF404604DD641CE4B26D1EEFD10020BDE80A
+:20570000F883C0465E0100200D4B10B51B6801EA03048C4218BF6FF0040010D1806840687E
+:20572000884298BF6FF0030009D98918884202D31340934202D06FF0050010BD002010BDAC
+:205740009C1301200D480021001F01700748084900680988D0F8D420D184D0F8D400054ADE
+:20576000C18C11800449C08C088070471401002072000120220001203E1900206C11012053
+:20578000F8B50F1C044616D00B4E0025786831680019E83178600A681268BA4202D100281D
+:2057A00048BF7D607868002802D5D1F8640480473F68002FEAD1F8BD1401002098B50D4C0D
+:2057C000A168D1F8B80007789FB1C7698FB1086C0268D06D28B102210023B847A168086C4A
+:2057E0000268106E28B1D1F8B810CC6900230821A04798BD0C010020F8B504460C480768B3
+:20580000AFB100260625386801888C420CD13E817989C90803D3387B01F080F938687D73EE
+:20582000407BF021FEF78EFC7F68002FEBD1F8BD3805012030B50D4C2468ADF1140D94B16A
+:20584000E46984B101258DF80850ADF80A00ADF80C10089D009502AD95E80300A0470128DA
+:2058600018BF002000D10A2005B030BDFCDB0020B0B505460C46102002F02FFE071C14D045
+:2058800000211022F9F762F87720387000237B702088B880207AB87161680822F81D03F080
+:2058A000F9FCE8B23946FDF7F7FEB0BDF8B507460A480B4C0668E0698D00285886420AD17A
+:2058C00008480090384604F073FDE0692858864218BF381C00D10020F8BDC04674AC02007C
+:2058E000501700206003012090B51C785B7803AFADF1240D8DF821308DF8204000230093FF
+:205900003B78019301230293BC8803943C7A04940224059408AC069407930B23EAF7C8FCE4
+:2059200009B090BDF8B58469C08948F21F01814208BF641C2778F800401CF7F78BF9061C93
+:205940000BD0751C377047B1641C2846214604F023FC083408357F1EF7D13046F8BD08B50E
+:2059600010200DF102018DF802005A20FFF754FE4FF4FA706946ADF800005520FFF74CFEF7
+:2059800003200DF103018DF803005920FFF744FE092003F03FFA08BD10B543689B6801EA31
+:2059A00003048C4218BF6FF0040011D180684068884298BF6FF003000AD98918884203D3BF
+:2059C00002EA0300904202D06FF0050010BD002010BD2DE9FF410A9F984614460D46064640
+:2059E00001ABFEF7B9F870B1039828B1404601A93A4601F05FFF06E00097304629462246F7
+:205A0000434601F05BFB0090BDE8FF817CB50C4D0646002401E0641CE4B2E878A042D8BF37
+:205A2000FF200BDDE86861036A46042304F024FB009800F0FF008642EDD120467CBDC0460F
+:205A40005CFC00200C4880B50168886800E0384647681FB101F13802BA42F8D1407B10F063
+:205A60000F0006D1498F40F60900884208BF012000D0002080BDC04634F50020B0B504464C
+:205A8000242002F02AFD0746094805787FB1322038702078B87060687860A1681B2207F1C6
+:205AA000080003F0F7FB28463946FDF7F5FDB0BDE80001203EB515460F220B4C8DF808202D
+:205AC0004FF6FD72ADF800206268107000125070901C04F061FB606813220B236946857264
+:205AE0002046FBF71BF83EBD98FD00202DE9F0411D4616468846044604F0D4F8071C0FD0AB
+:205B0000062002F0EAFC011C0AD0FD2008704D708C708E8081F8038078680078FDF7BCFD33
+:205B2000BDE8F081C8B5FE294FF0000608BF0126094A17686FB1FA88904207D1002E18BF55
+:205B4000387907D13A798A4208BF01263F68002FF1D1FE20C8BDC0461C03012003460C4831
+:205B6000D0B5C7688FB186787EB1163F002017F8164FA34205D17C88A14202D1BC88A2427E
+:205B800004D0761E00F10100F1D1FF20D0BDC046F00C01201CB500200B4C8DF80000042029
+:205BA0008DF801000120A0716846F8F7D7F960784FF48051FCF7B4FB60784FF4805141F213
+:205BC000883204F0C8FA1CBD4CFF00201CB50C4C84F821106178012803D000200121A07113
+:205BE00007E008464FF48051FCF79AFB002184F8441001206B460246FEF77CFD1CBDC0467C
+:205C00004CFF00200C4A80B5121F5768034603F0F5FB0628A8BF00200DDA384600E008462A
+:205C200010B101680029FAD10021002819600CBF53600360012080BD2C1A002038B5846806
+:205C4000456894F8380001F0DBFA94F8390001F0D7FA94F83A0001F0D3FA95F8F900012853
+:205C600003D095F8FB00FF2803D095F8FB0001F0C7FA38BD70B50B4C30B1401E18BF0020EE
+:205C80000DD1074D641C00E0074D2078411C06462170A8470028F8D1002EF6D0304670BDD5
+:205CA000C1A1020049190020A18E020038B50C46054600F05FFC0A49A04204D20846026835
+:205CC0002046DC3205E008460268DC3250680068001968601168D2F810242846904738BDF3
+:205CE000140100200C4808388268D2F8D820002111608268D2F8DC2011608268D2F8E020C8
+:205D00004FF4700313608268D2F8E42013608068D0F8E8000160704714010020094908B53B
+:205D2000012008700A488638006818B10649088B401C0883F02000F0B5FB04480078E8F76D
+:205D400035F908BDFC1301208C1101204D0201203E19002098B504460B48006888B10746A3
+:205D6000B86804420AD0F8683A690021034620469847002818BF4FF0FF3003D13F68002F1A
+:205D8000EED1002098BDC0461015002010B50C1CADF1380D13D001466A462046EFF78CFC06
+:205DA0009DF8060058B19DF801209DF81C300020214603F0C3FA002818BFA42000D10020BD
+:205DC0000EB010BD38B50C4C0D4694F8961081420EDA00F0ADF907482146058091F82B201E
+:205DE0000878642313FB02F24FF4007104F0B3F938BDC046F2FB0020E4FA002010B50C4629
+:205E000001461022ADF1200D684603F0E7FF04A804F05EF910200790CDF810D004A904485B
+:205E200005940068069404F084F908B010BDC0460CDC00202DE9F0410F46044603F0E0FD0D
+:205E400004F1280292E8600033462A46F6F7E6F980460B4642462846314603F077FB17B1E3
+:205E6000303484E803004046BDE8F08170B5049D012A4FF000001E4602D9911E10D070BD88
+:205E8000012908BF012011290BD10024204631462A46E4F7AFF918B9641C052CF6DB70BD66
+:205EA000012070BD7CB515460446E8791E46800812D3204602F066FB78B9204603F06AFFE0
+:205EC000041C08BFC12008D000200090A988288802223346A0477CBD88207CBD1FB50124FA
+:205EE0008DF80C400AB9062B11DB03290FD0002112226B46FDF730FE20B103A86946002271
+:205F000001F0D8FC9DF80C100020012900D1204600901FBDF8B5064614460D46182004F04C
+:205F2000BBF9094B1A6970B1002101600671816005741F69446117B91861F8BD0A4611686E
+:205F40000029FBD11060F8BD80030120F8B5064614460D460C2004F09FF9094A916868B1C0
+:205F60000023036086809768C580846017B99060F8BD11460A68002AFBD10860F8BDC04616
+:205F80008003012038B50C4605460021012203206B468DF8001003F01FFD70B9FF2D19BFEA
+:205FA0009DF80000A0439DF80000204301216A468DF80000032004F027F838BD024610781F
+:205FC00000280CBF00200120517809B140F00200917809B140F00400D17809B140F00800A6
+:205FE000117909B140F04000517909B140F080007047F8B54568066804F0E8F80746307871
+:2060000070B1287903F094FF012806D1286800244460301D04F0D8F834702879F3F75EFA48
+:20602000384604F05DFAF8BD10B50024ADF1180D01A800902146002214230820FFF7FAFB2A
+:2060400040B99DF80400FF2804D00DF106010022F9F7F0FA641C102CEADB06B010BD014667
+:2060600000B50420ADF1140D8DF80000087A022806D001A803F0A4FE6846FAF747FB05E07D
+:206080000888ADF802006846F8F79AFCBDF80C0005B000BD0A4938B5402205680A6080204A
+:2060A00008600024C1F8FC4295F8260020B1054804F0A2F885F82640022000F0FFFC38BD19
+:2060C00004440240B80E01207CB50B4C0026354600940220314600220E23FFF7ABFB20B931
+:2060E0002078FF281CBF6D1CADB2761C0E34042EEEDB28467CBDC0466C01002010B50A4CFA
+:20610000606820B16068FEF747FD0020606002F04BFC064CE06A30B14168E162FEF73CFD35
+:20612000E06A0028F8D110BD34040120ECFB002030B50B4C0546ADF1140D083C6A4684F841
+:20614000965014342046FBF7F9FE68468DF81250FBF742F845202146FFF75EFA05B030BD45
+:20616000ECFA00200A46014610B5101C0ED069B1074A0323C2F88437D2F88C3713F0030F0B
+:20618000FAD1044C012323601160906010BDC046044002400000484210B50A4941F8980C04
+:2061A00008684FF0805440F003000860D4F8B80181692020884704480068D4F8B801806B1F
+:2061C000804710BD242208402C20094038B514460546042211FB02F21846091D02F0FC02DC
+:2061E0008DF800208AB22946FCF782FC02460121684603F073FE84420CBF0020022038BD9A
+:2062000010B5FEF7ABF9012001F0AAF8044603F0DDFF074A116831B104F062F934B120460D
+:2062200003F092FE10BD146004F05AF910BDC046A813012038B5044603F0C8FF0849054617
+:206240000878A04308700878000904D205480821E03003F0D9FF284604F042F938BDC0461B
+:20626000FD13012030F50020F8B516460F46044603F0ACFF05460848001D0068A04205D18A
+:206280003846314601F02AF8044600E00324284604F026F92046F8BD30F500200C2838B5A3
+:2062A00012DA002808BF00240CD0921E0346002403F0FCFD32F8025FA84203D05B1E04F144
+:2062C0000104F5D1A14201D0002038BD012038BD0B49891F8A7992080ED3084A12788242FA
+:2062E0000AD00846017901F0F80141F0020101710C21817101F0E8BE7047C046BAFE002021
+:20630000E61201203EB50225ADF80000094B8DF808505C6804F8010B001204F8010B184630
+:2063200004F8011B0423694622700122FAF7F6FB3EBDC04698FD002002460B48B0B50778A3
+:20634000FF237FB1183000244578AA4202D14588A94206D07F1E00F1140004F10104F3D115
+:2063600000E023461846B0BDF00C01200B4A10B5536A0146181C05D0814205D004468069FA
+:206380000028F9D1022010BD834219BF8169A16199695162FEF700FC002010BD4CFF002095
+:2063A000BCB50B4C0546AB2021888DF80000284603F089FB01216846FCF7F8FE218807463D
+:2063C000284603F089FB17B92846FCF7B1F8BCBDA41301207CB5054609480A4C0078218869
+:2063E0008DF80000284603F06EFB01216846FCF7DDFE21880646284603F06EFB30467CBD42
+:206400004BC20200A4130120F8B50646151C41F00C0006AF18BF40F0400076B1397B3A7AA3
+:206420003C793D7840F0800042EA410244EA420445EA840243EAC2023270F8BD10B5044653
+:206440000C22ADF1200D214601A803F027F9207B082204F110018DF8100005A803F01EF909
+:20646000207E8DF81C006846EBF70EFD08B010BD80280BDC012803D0032818BF802801D1B6
+:2064800001207047022805D1022070478428B8BF042006DB842801DB862801DB002070473A
+:2064A0000320704738B50546EA2D12DBF42D10DA084C083CA068D0F8282469462846904713
+:2064C0000098A368401C0090D3F8302469462846904738BD1401002010B5094C94F9000049
+:2064E00010F1020F0BD00848064B4238006894F90010826B186890476FF00100207010BD8E
+:206500000D05012080000120220001200A4808B50068D0F8B800007800280CBF01200020C1
+:2065200000F00EF8054991F9000018B191F90000401E087008BDC04614010020140501202A
+:2065400038B5054603F042FE044600210220FAF7ADFD074800688369044800684FF0FF31E2
+:206560002A469847204603F0BBFF38BD80000120E0FF002038B503F029FE0546084800681A
+:20658000084CC06B8047083C6168401A21788900B0FBF1F4284603F0A3FF204638BDC04638
+:2065A000E0FF0020E00000200A4908B5888B401C888303F00BFE08490A78862A02D003F00E
+:2065C0008FFF08BD87220A7003F08AFFE920F6F72BFD08BD4C0201200A1401204FF6FE7085
+:2065E00038B5411C01F074F8011C0DD1074C3225A07C08B1607C18B9208800F0A7FA21462D
+:206600006D1E04F11C04F3D1084638BD6C08002038B505460A480E3000880C46A04206D1E4
+:20662000284603F059FD002818BF083007D12846214601F04DF8002814BF1030002038BD39
+:206640001EFB0020BCB50B4D2F68002487B17F6977B101258DF80050ADF80200ADF80410DA
+:206660009DE80300B84718B10A280CBF09240A242046BCBDFCDB00200B4910B5096849B118
+:206680000B7C002201E0521CD2B2934204DC09680029F5D1002010BD01EBC204E47EA04286
+:2066A000F1D1084610BDC0464405012038B5B1F1FF3F044608BF05212020EFF3118580F35E
+:2066C00011880120054B61618840A061586903F06BFEA06285F3118838BDC046E4160020E0
+:2066E00044280BD0432809D0422803D0412801D0F6F726BD0878401C80B270474A780878C1
+:2067000000EB022081B2881C80B28142C8BF4FF6FF707047B0B544684088401EC7B2F81CEA
+:2067200080B203F0B9FD70B121788770017057B1641C3946002214F8013B8518491E02F1F4
+:206740000102EB70F7D1B0BD30B50D4601460024ADF1140D01A88DF8004003F031FB684609
+:20676000F9F7D4FFBDF802104FF6FE72204629808A4218BF012005B030BD38B50E20F6F75D
+:2067800069FA041C10D0FF210E22F8F7DFF80025022029460E222346FBF77AFF6D1C042D0C
+:2067A000F6DB2046FEF7F8F9002038BD70B516460C46054601F0BEFC2968A14219BF54F846
+:2067C0000C1C46F80C1C54F80C1C2960002144F80C1CFF2104F8021C02F08FFF70BDF8B515
+:2067E0008C46071C164611D000245EB13CF814109A1E304632F8025F8D4208BF012006D096
+:20680000401EF7D17F1E04F10104EED10020F8BDF8B5846914F8016BA0780546801DF6F728
+:2068200019FA071C0BD03E70617820782A4600EB01207880E11C781D3D7102F02BFD3846DC
+:20684000F8BD10B5FF211422ADF1180D6846F8F77DF800240820214614226B46FBF718FFF0
+:206860000A2808BF0A2003D0641C102CF2DB002006B010BDB0B505460C46082001F02DFEB0
+:20688000071C0FD000210822F8F760F87A203870207878706088B880A0883946F880E8B2C9
+:2068A000FCF7FAFEB0BD70B5044604F128020CCA0846002102F04AFE04F1300292E8600072
+:2068C0002D1846EB0106290C30040143FEF7C4FB383484E8600070BD10B5044603F060FD16
+:2068E000034603E0184603F057FD03469C4208D0986803F0C5FC9042F4DA184603F096FB92
+:2069000010BD204603F08CFD10BD38B51446E2791D46920810D3224601F034FE68B9A079B4
+:20692000D5F80310FFF7DCFE0246D5F80310A06802F0B4FE002038BD882038BD0A4980B599
+:206940000A1D1768874209D057B1F968884202D00F1CFAD104E0C168F96001E0FA684A60A1
+:20696000FEF71AF980BDC046DC04012038B50C46054602F05FFC0146284602F039FB0128F0
+:2069800004D028462146FFF7DFFE38BD024800882080012038BDC0461EFB002038B5044688
+:2069A00001F082F80546012D0CD10748A28903682478910001EBC2015A5CC818A2435A542C
+:2069C00003F04AFA284638BD340501200A4908B51420F9F715FC1420002103F00BF9012011
+:2069E00003F0B0FB1420012103F004F94FF40C7003F0A8FB08BDC0460162002038B50A46D3
+:206A00000C460546002102F009F907490C39487840B97C2C08BF81F833500C2015FB0010BF
+:206A200080F8464038BDC04668FC0020F8B50A4C054620680E4617464FF0FF3103F067F891
+:206A4000284631463A46FBF765F90546206803F0D3FB2846F8BDC04694130120F8B50A4CF9
+:206A6000054620680E4617464FF0FF3103F04FF8284631463A46F3F783F80546206803F059
+:206A8000BBFB2846F8BDC046A81301200EB509490A68917969B913680749C268096831B140
+:206AA0000193029240788DF8000068468847FFF725FB0EBD38040120FC00012010B504468A
+:206AC00003F084FB084B1A1992F84311491EC9B282F8431121B99A680121A1408A439A608A
+:206AE00003F0FEFC002010BD1015002038B5044603F06CFB084A02F108031D680121A1400E
+:206B0000A4182943196094F84311491C84F8431103F0E6FC002038BD10150020094B10B577
+:206B20001E21002213F8014FA04204D0491E02F10102F7D110BD00201870034941F82200A2
+:206B400010BDC0464D010020540200200A4938B5962203254FF6FE748B795B0807D24B8894
+:206B6000984204D14B79012B04BF4D714C80521E01F10801F0D138BDBC0300200748006872
+:206B8000400909D20748064B074A016803EA9120824208BF012000D000207047B04F005037
+:206BA000F1FF0F0050130050F00107001CB54FF08054D4F8CC014068014602208847D4F802
+:206BC000CC1100904868014601208847019002486946FCF735F81CBD08120120C8B50F46D1
+:206BE000016887B17E6876B13A78042A0BD1BE684EB100224A628F617A68CA61BA688A622D
+:206C0000F2F7CCFCC8BD6FF00200C8BDF8B50446094805780E46022001F05FFC071C09D0D5
+:206C20001EB13146022202F035FB3C7028463946FCF732FDF8BDC0463BFD00200A4A98B559
+:206C40000021176801606FB1BF1F03224FF6FE7437F8063F9C4203D107600846387198BD80
+:206C6000521EF5D1C82098BD60FE002010B504461022ADF1200D04A9684603F0A8F80648DB
+:206C800000686946FFF7AAFF01991022204602F001FB08B010BDC04610DC00200A4980B5FF
+:206CA0000A884FF47A714A43904294BF101A00200022B0FBF1F34B43C71A18BF0122B0FB53
+:206CC000F1F0121890B280BDF60C012010B5094C641E60788021FDF73FFF50B9607880213E
+:206CE000FBF71EFB04480021C180FF21417001F0BBFD10BD4DFF0020F00C012080B5071CB3
+:206D000014BF80210021074B188F4FF67F7202401143054A08431887117867F3C7111170A4
+:206D200080BDC046DCFF002024190020094810B500240470FFF7EAFBF9F758FF06494868E9
+:206D4000C068007828B90868D0F8582420460146904710BD061401201401002010B50A4C22
+:206D60006068C068007828B92068D0F8582400210120904703F02AFA03F0B2FB2068D0F8DE
+:206D8000B800806E804710BD1401002008B503F01DFA084A517841F00201517003F0A0FB1F
+:206DA00005480068D0F8940000780021FAF7FAFE08BDC046D80000201401002038B5044611
+:206DC00009480068D0F8D85003F000FA296831B1A14208BF012403D009680029F8D1002481
+:206DE00003F07EFB204638BD14010020F8B5061C0D464FF000040CD0074807684FB138461A
+:206E00002946B047012803D07F68002FF7D100E03C462046F8BDC0463805012038B5094D0E
+:206E20003224284602F0ADF91C35641EF9D106494FF6FE73002203204B80401E01F8042BBE
+:206E4000FAD138BD6C08002028FC0020F8B5147806460D46082001F040FB071C0DD000214D
+:206E60000822F7F773FD6C20387000237B703946BD80F0B2BC71FCF70FFCF8BDF8B51478D1
+:206E800006460D46082001F028FB071C0DD000210822F7F75BFD6B20387000237B703946C6
+:206EA000BD80F0B2BC71FCF7F7FBF8BDF8B5147806460D46082001F010FB071C0DD000210F
+:206EC0000822F7F743FD7220387000237B703946BD80F0B2BC71FCF7DFFBF8BDF8B51478CC
+:206EE00006460D46082001F0F8FA071C0DD000210822F7F72BFD7420387000237B703946BE
+:206F0000BD80F0B2BC71FCF7C7FBF8BD2DE9F0410546094807681C4690460E4657B1B868F5
+:206F20002840854203D1387931464246A0473F68002FF4D1BDE8F0812C1A0020F8B5147867
+:206F400006460D46082001F0C8FA071C0DD000210822F7F7FBFC6D20387000237B703946C5
+:206F6000BD80F0B2BC71FCF797FBF8BD10B503F00FFA03F061FA032003F006FA0648103018
+:206F8000006830B1034C204602F0F0FF204602F0F3FF10BD67420100C016002008B503F0AB
+:206FA0000FFA012801D003F0EBF9074803F0E4F901F0F2F903F0DCF903F0D6F903F0D0F9B6
+:206FC00003F0CAF908BDC0466D6F0200084910B5002008600120C861064C2060216844F8D3
+:206FE000280C05480068016A14208847206810BD000024432C200940B001001030B500251E
+:20700000ADF1240D0848009502AA01930B46294603F09EF9041C03D002A902F0BBFA254682
+:20702000284609B030BDC046A8C0020030B503460025ADF1240D0848009502AA0191294618
+:2070400003F086F9041C03D002A902F0A3FA2546284609B030BDC046A8C0020030B5002598
+:20706000ADF1240D0848009502AA01930B46294603F06EF9041C03D002A902F097FA254676
+:20708000284609B030BDC046C8C0020038B50446EFF31185202080F31188A08A012809D124
+:2070A00003F022FAE168A368081A834203D22169814200D2002085F3118838BD2DE9FC4119
+:2070C000089F984615460E4602F064FE04460FB1002038803CB10097304629460122434631
+:2070E000A047BDE8FC81C120BDE8FC8110B5041C09D1002484B9214605201022FCF746F974
+:20710000641CA4B2F6E721780520102201F07F01FCF73CF90020207010BD98B5044601F02E
+:2071200009F82168002908BF002709D051F80C2C002322600F4641F80C3CFF2401F8024C6F
+:2071400002F0DBFA384698BD38B50C46054600F0F1FF6CB1002144F80C1C296811B92C60A2
+:2071600006E0114651F80C2C002AFAD141F80C4C02F0C3FA38BD38B50C46054603F026F88C
+:2071800022680346002442B12846114602F05AFD00B114461268002AF6D1184603F0A0F997
+:2071A000204638BD00B51022ADF1140D8DF8001001460DF1010002F06DF83B2011216A465F
+:2071C00002F022FF002111226846F7F7BFFB05B000BD00000346094810B5001D006858B193
+:2071E000C479A34205D18488A14202D18479A24203D0C0680028F3D1002010BDDC0401201F
+:2072000010B5044601F0FEFF07480838006850F824102046F8F7F4FF0021204601F0FEFF41
+:20722000204602F0DFFC10BDDCC2020038B50C46054602F0CBFF0749891C01EB85010A787F
+:20724000C4F3024322F007021A430A7003F048F938BDC0460010084070B5094D95F88A40E7
+:2072600064B102F00EFF4FF47A7600F07F0016FB040228784FF4807102F06AFF70BDC046DF
+:20728000E4FA002010B5202918BF6FF0010009D141688368044A4C681B8C146003490B6069
+:2072A000FCF7C0FE10BDC046A0130120A4130120074898B5007838B1064C074654F80C0B9F
+:2072C000006980477F1EF9D103490120087098BD4CBF020070C102000906012010B50C4656
+:2072E000084924310978022918BF012009D100F00FFF04B1206000F0FF0001280CBF8120B3
+:20730000022010BD30F50020094A38B503460824002084325588AB4202D11578A94205D0C4
+:20732000641E02F10A0200F10100F3D138BDC0462001002030B50D460446242208230021C6
+:20734000ADF1240D684603F0BBF8012029466A468DF81800204603F0AFF8204609B030BD21
+:2073600010B50446002124220823ADF1280D684603F0A6F8044A012069468DF81800204639
+:2073800002F0E2FF0AB010BD60030120074810B5002407490460032008600220FFF78EFBF7
+:2073A0000820F2F79BF80348047010BDA8025042108002400506012010B5002000F02AFE66
+:2073C00002F074FD044601F035FF01460448027800232046FEF76EFB002000F01BFE10BDF1
+:2073E000E612012038B5094C0146E07850B1C87840B9487830B90448002505800120FBF7A7
+:20740000EFF8E57038BDC04678FB0020E80001208CB58DF800000848001D0068027004AFD9
+:2074200043701A1282700022C2703A8804236846F9F774FB8CBDC04698FD00201FB51446FF
+:207440000222ADF8020001A88DF8002002F0B8FC6846EEF7C1FA012814BFC8200020BDF866
+:207460000C10218000901FBD98B5094B00221F680A6057B1BF1F032337F8064FA04204BFFA
+:207480000F60101C02D05B1EF6D1C82098BDC04660FE002010B5074C207838B9064807493F
+:2074A0004FF4B472F4F722FB0120207001F0F8FA10BDC0460C0601204C400021A0AF0200C3
+:2074C000094A10B512686AB11379984218BFFF2805D1931D1C88A14208BF181C03D0126846
+:2074E000002AF1D1002010BD1C03012010B5094C00203E3C207060784021FAF711FF00F005
+:2075000021F860784FF48041FAF70AFF0B2002F0D9FB10BD8AFF0020094A92F8421088421C
+:2075200002D1917801290AD001281CBF002182F83F10423210700121552002F065BD704727
+:207540004CFF0020F8B5094C606968B104F114050026286800F11407FDF71EFB2E603D46EE
+:2075600028680028F5D16661F8BDC0464CFF002038B5094C0546B92021888DF8000028469E
+:2075800002F0A1FA01216846FBF710FE2188284602F0A2FA38BDC046A4130120094A10B5FE
+:2075A000ADF1180D009100240290114608680194694602F075FD002814BF201C4FF0FF30AD
+:2075C00006B010BDA013012038B50D464FF6FF712A46ADF800104121FDF77EFD041C05D173
+:2075E00028466946022201F0B5FA08B9204638BD0D2038BD80B5071C04D107480068D0F8C0
+:207600004C05804702F0E2FD044A1178B943117002F066FF80BDC046140100200614012023
+:2076200010B5041C04D107480068D0F84C05804702F0CCFD044A11780C43147002F050FF53
+:2076400010BDC0461401002006140120084838B50068D0F8E000046802F0B8FD05460548EF
+:2076600004602046F5F74AFF284602F039FF38BD14010020E000002038B5094C0546E06A72
+:2076800028B101888D420AD040680028F9D10820F5F7E0FAE16A10B105804160E06238BDEE
+:2076A000ECFB002080B5071C12BF78680748006850B14289120B04D339B102681288914282
+:2076C00003D040680028F4D1002080BD38050120094A38B532234FF6FF7532F81C4FA042C2
+:2076E00005D15489A14214BF8D42101C02D05B1EF3D1002038BDC0465008002002460948EB
+:2077000038B5002132234FF6FE7430F81C5FAC4203D08A4204D0491CC9B25B1EF5D100200C
+:2077200038BDC046500800200EB5094909680346002061B18A6A52B101218DF80010ADF882
+:207740000200ADF804309DE80300904780B20EBDFCDB0020F8B5057C002301E05B1CDBB2C5
+:207760009D42D8BF00200ADDDE0084191B342778B942F3D1617880190A4316306270F8BDD8
+:20778000027A0B7A93420CD15AB1022A07D1098800880022814208BF012210467047032A05
+:2077A00001D00020704701F023BC7047B0B514780546042000F091FE071C0CD00021042275
+:2077C000F7F7C4F896200023387039467B70E8B2FC70FBF761FFB0BDF8B504460848076899
+:2077E00016460D4657B1F8882040844203D116B138792946B0473F68002FF4D1F8BDC04624
+:207800002C1A0020B0B50C780546042000F065FE071C0CD000210422F7F798F878200023D8
+:20782000387039467B70E8B2FC70FBF735FFB0BD08602E2088800020888102A088600846DE
+:207840007047C0467B756E6B6E6F776E2D696E7374616E63652D6E616D657D000860322059
+:2078600088800020888102A0886008467047C0467B756E6B6E6F776E2D696E7374616E639A
+:20788000652D6E616D657D0038B52020EFF3118580F31188064CA068002102F051FD616902
+:2078A000081AA169814238BF002085F3118838BD80160020B0B50B4699681746054600297E
+:2078C00008BF01200BD09879FEF70AFF996804460246284601F0E2FE07B13C800020B0BD03
+:2078E000F8B516460D46044602F070FC024629463046086043684B60476807B92746396024
+:207900004160104602F0ECFDF8BD10B5041C0FD0207A022818BF03280AD12046F5F7F8FA37
+:20792000FF2805D0227A0021FDF7F6FA002010BDE82010BD00B5817EADF1340D8DF81210AE
+:20794000C27E8DF813204188ADF80A108188427DADF80C106846ECF7B9FA0DB000BD70B53B
+:2079600014460E460546002201F0D6F9FF280AD02B2E19BF40F22B2141EA8421A10241F0D8
+:207980002B0145F8201070BD1FB50C46014602208DF8000001A802F013FA6846F8F7B6FE14
+:2079A000012814BFC8200020BDF80C10218000901FBD420824BF01220A70820824BF01228B
+:2079C0004A70C20824BF01228A70020924BF0122CA70C00924BF0120087170474A0824BFA6
+:2079E00001220270CA0824BF012242704A0924BF0122C2708A0924BF01220271490A24BF9B
+:207A00000121C171704710F15A0F05DB10F1140FC8BF6FF0130001E06FF05900332141F2D4
+:207A2000EE120E2310FB012191FBF3F0C0B27047C8B507460748466857B116B9476004E027
+:207A40000646F0680028FBD1F760B9710020F860C8BDC046DC04012038B5458940684478EA
+:207A6000062000F03AFD01460448007829B108220A704D800C71FBF70FFE38BD3BFD00209A
+:207A8000044805494160054981600549C16005490161704770020120C9D900005DF901001A
+:207AA0009D910200559700000146084B89891A8800208A4208DD8A0002EBC1025968895CAB
+:207AC00011F00F0F18BF01207047C046300501200849091F088850B149680C3911F80C2F38
+:207AE00012F00F0F08BF002002D0401EF6D101207047C0463405012038B5084C0022332397
+:207B00002579A84203DCA942A4BF521CD2B25B1E04F12404F4D1104638BDC046E40D002001
+:207B2000084933220B79052B05DA002808BF081C06D0401E80B2521E01F12401F2D1002029
+:207B40007047C046E40D002070B5084C04EB800425680E4602F03AFB05F0FF053146A94208
+:207B600018BF217002F0BCFC70BDC0460010084038B50C4601466BB1091F002051F8045FD2
+:207B8000B5F1FF3F06D01540AC4204D05B1E00F10100F3D1FF2038BD084910B5087860B12A
+:207BA00039310246002311F80C4FFE2C08BF181C03D0521E03F10103F5D110BD5FFC00201E
+:207BC0001CB55B1C8DF802109624ADF8002099008DF803406A46042389B2FCF74FF8014950
+:207BE00008701CBD5DFC002010B5044610460A46211C08D038B1C8608A6004480B6100F04E
+:207C0000BDF9002010BD6FF0020010BD1015002038B50D460446F7F781FF05F57A71241A33
+:207C2000A008814234BFB0F1405F002003D2401B012898BF012038BD084900B54422ADF1B6
+:207C4000440D6846F3F752FF01208DF83E008DF83F00684601F05CFE11B000BDD4BD020038
+:207C60000849074809780078890803D24FF48071F9F798BF4FF4807140F6C41202F06BBA33
+:207C80003BFD002016FB002010B50446062000F024FC011C09D031200870208848806088FF
+:207CA000024B88801878FBF7F7FC10BDE800012000B5ADF1140D0DF10E01FFF765FE48B949
+:207CC00002208DF80000BDF80E30ADF80C306846FEF764FE05B000BDE22808B505D1064AC5
+:207CE0000846114602F058FA08BD044A1268D2F82824904708BDC04618DC0020140100200D
+:207D000010B5FF211422ADF1180D6846F6F71EFE00240820214614226B46FEF793FC641C30
+:207D2000102CF6DB06B010BD38B51546074A12781C4652B1FEF700FBFF2806D0012D14BF3D
+:207D4000012100212246FCF7F7FC38BDF00C0120084A1432126852B11388994204D1537A53
+:207D6000984208BF101C03D05269002AF4D100207047C0464CFF002001280AD00749C878DE
+:207D800028B1486B18B10020C870FCF7BBB8002100E001210520E0F735BCC0464CFF00204F
+:207DA00010B568B1074C1621E07011FB00F0F4F751FF0021E0600028A17008BF012000D082
+:207DC000002010BDF00C01200168084603E0D1F88C0006E08268C268D208FBD20222C0F82D
+:207DE0008020C8684008F2D30020C1F88000704710B5041C04D106480068D0F84C05804746
+:207E0000044801780C430470F8F724FF10BDC0461401002006140120084A014603235088EE
+:207E2000814204D11078002818BF012004D15B1E02F10402F3D100207047C04628FC0020D6
+:207E400070B50748074C322506886089864202D0204601F096F96D1E04F11C04F5D170BD7A
+:207E60002CFB00206C08002038B50446074801882046FFF72DFC0D4638B101F082F9204685
+:207E80002946FFF725FC0028F7D138BD2CFB002038B5084D69682C6824EA010028600C40A6
+:207EA000E00901D3F5F7E6FA200A01D3FCF7B6F9AC6038BD9022084010B5084C38B106484E
+:207EC00000684068012102462046001F9047206820F03000206010BDD80100100440034047
+:207EE000B0B514780546042000F0F7FA071C0AD000210422F6F72AFD942039463870E8B274
+:207F0000FC70FBF7C9FBB0BDFEB5002516460F46ADF8045001F03EFF041C06D001A82A4613
+:207F20000090314613463846A047BDF80400FEBD0EB5014648894A68ADF8000050788DF889
+:207F4000020092788DF8082008B9487A10B16846EFF7ACFF0EBD1FB50C460021ADF802002C
+:207F600068468DF80010F6F72BFD01A9204601F027FF204600F058FD00901FBD38B50D462B
+:207F8000044602F023F900212A462346116059685160596801B921460A605A6002F0A0FA1A
+:207FA00038BD38B50C46054602F010F900212B4622461C6851601460196801B929464A6050
+:207FC0001A6002F08DFA38BD38B50D46044602F0FDF82A46116801B9214653684B6051681F
+:207FE00001B9214612680A6002F07AFA38BD1CB50024032001216A468DF8004001F0FEFF84
+:2080000028B90320214601226B4601F0E5FC9DF800001CBD074A917828B90120D0700846F7
+:208020000221FAF77DB90023D37002460846022102F091B8AC000120428913090CD392086F
+:2080400008D3427B062A05D0E92903D0CD2918BFF02901D1F0F746BB0020704708B502F078
+:208060003BF8002808BF002009D0017931B1032904DA8169C161012380F82030012008BDA1
+:208080001FB5FF210E226846F6F760FC0024022021460E226B46FEF7D5FA641C042CF6DBF2
+:2080A00000901FBD38B5074B9C782546681CC4B29C70284600F064FF0028F6D1002DF4D0EF
+:2080C000284638BDECFB00200648017808092CBF03200120890828BF40F0040002490870C0
+:2080E0007047C046E6120120EDFB0020054808B50068426801200146904703480349006848
+:20810000086008BDE001001030200940AC02012007490246083908680028FCD10023CB614C
+:208120000A60C8690028FCD0CB6148687047C0460810044010B502F07FF9064980B2000407
+:208140002140040C0C4302F041F880B260F31F44204610BD0000FFFF0749082291F83300E5
+:2081600030F07F0008BF081C04D0521E01F15801F4D100207047C04678F700200A46064916
+:2081800010B54B683BB18968084204D003490C6801462046984710BD50C3020034F50020F5
+:2081A00010B50C460021FDF7BFF92146F7F720F938B14FF6FE710180418000240471447140
+:2081C000847110BD10B5074CE41F207220B9207810B9062001F0E2F8E0792021F9F7E2FC9D
+:2081E00010BDC0463BFD0020024607480168486800E0486803789A4204D0096808680028E0
+:20820000F7D100207047C04658FF002010B5074C606918B1FCF7C0FC00206061E06918B1F6
+:20822000FCF7BAFC0020E06110BDC046DC02012010B530B14379002201E0521CD2B2934236
+:2082400001DC002010BD00EB4204E488A142F4D1012010BD064A1068002818BF012006D162
+:20826000044940200860012348600020D361704704800C4038500C40064902680B390A6007
+:2082800042684A60044902680A390A60406848607047C046220001203E19002006490020F0
+:2082A00008700648001D00680069FF2202704FF0FF308861486170477000012014010020FA
+:2082C00010B504460B2C01DB1A2C04DD04480068D0F84C0580470148047010BD1A190020E4
+:2082E000140100200649487840F00400487005480068D0F8940000780021F9F753BCC0469F
+:20830000D80000201401002038B50D460446FEF731F94019606004480268D2F8D810D2F83C
+:20832000EC242046904738BD1401002010B50346002A08BF00200AD05B1E491E11F8014F94
+:2083400013F8010F844201D1521EF7D1001B10BD024607480168002041B14B7B9A4212BFC5
+:20836000FF2A401CC0B249680029F6D17047C04638050120074910B5322200204FF6FE730B
+:208380001C3131F81C4BA3421CBF401C80B2521EF7D110BD50080020074808B51030006881
+:2083A00028B1034801F0E2FD024801F0E5FD08BDC98902007D950200C0160020074810B575
+:2083C0001030006830B1044C204601F0CFFD204601F0D2FD10BDC046EFA50100C01600201D
+:2083E000074908B5283090E80C000020F3F716FF002908BFB0F1FF3F88BF4FF0FF3008BD2C
+:20840000907E000038B505460024064A0448009429684FF0FF3301F08FFF2C6038BDC046BA
+:20842000A8C00200059D020038B505460024064A0448009429684FF0FF3301F07DFF2C60A7
+:2084400038BDC046C8C00200159D020007480078022807D0062803D0052806D001F0BEB8B0
+:20846000062000E00220E7F70BBB70474D020120074A01460523506820B10078884208BFB7
+:20848000107804D05B1E02F10802F4D10020704700FE0020074B10B501460522586810B14A
+:2084A00004788C4204D0521E03F10803F6D1002010BDC04600FE002038B5054601F086FEAA
+:2084C0002C6834B121682960216801B9294600224A6002F005F8204638BD10B5041C04D090
+:2084E00004F10C00F4F7B6FB08B9002010BD002101600481FF2383720C3010BD38B5846930
+:208500000D466178207800EB0120A41C28802146A81C01F041FE14F8080FA87238BD08B5D9
+:208520000B4600F085FC20B93220187001225A7008BD00F10C010222184600F0ABFE08BD36
+:208540000C28C8BF01200BDC0628C8BF032007DC0228C8BF052003DC002814BF07200020A6
+:2085600070473EB50546002108226846F6F7EEF92846694600F03CFD0024012818BF0124AA
+:2085800020463EBD38B514460D46E179890908D301F0F0FB031C04D0284621460222984772
+:2085A00038BD002038BD000038B5064D0024022021460E222B46FEF745F8641C0E35042CFE
+:2085C000F5DB38BD6C010020F8B516460D46044601F0FAFE074629463246204601F0DFFD53
+:2085E000384601F07DFFF8BD012814BF00200120044B03491A78087060F345121A7070470E
+:20860000240001202419002038B53821017001258570FCF7DEFD041C04D02570A57700F083
+:2086200009FE6062204638BD064A08B5126801EB4031012310466A4601F01EFD9DF8000067
+:2086400008BDC04668FC002010B54FF6FF700C46A04205D0EEF702FB0249E0B2F7F7D0FDCF
+:2086600010BDC0460160002038B5064D0524AD1C2846FF210422F6F769F92D1D641EF7D1DD
+:2086800038BDC0462001002010B5401E491E4AB111F8013F10F8014FA34218BF002002D1C9
+:2086A000521EF5D1012010BD08B5002808BF052009D010F8021CFF2918BF042003D10C388B
+:2086C000FCF76AFA002008BD38B5054601F07EFD044604482946FFF777FC204601F000FFF6
+:2086E00038BDC046101500200648054A816A8A4203D0E030042101F087BDF7F7B7BDC04641
+:20870000F95E000030F5002008B54FF0FF3001F087F8800805D303484FF40061E03001F0D2
+:2087200073FD08BD30F50020064A92F824100020022906D1D2F8A81019B9D2F8AC1001B9FB
+:208740000120704730F5002005480068400838BF002003D303480068C0F3C0107047C0461F
+:2087600040210840000004403EB50446A0686A46EFF718FE0546832D04D169462046002214
+:20878000FDF772FD28463EBD10B5044600F022FD40B9204601F0A0FC08B1007910B14FF6CB
+:2087A000FE7010BD204610BD38B5064C0546E0790421FCF7D1F920B9E0792A46042101F0CE
+:2087C000CAFC38BD34FD002008B501F05AFC42F2107210401218034800784FF4804101F0A1
+:2087E000BAFC08BD3BFD0020054808B500788DF800000448016809B16846884708BDC046E8
+:208800003604012090FD00200346064810B544682170091261701946A27003230422F8F71F
+:208820007DF910BD98FD00201CB50C46002121606946FFF7A9F828B9BDF800002146FEF743
+:2088400013FE1CBDC8201CBD10B50446087A2072087A03281CBF0888208002D1204601F068
+:208860009BFC0020608110BD06490548891D007809884FF47A724A43802101F06CBCC046CC
+:208880004DFF0020F00C0120491E012202FA01F18BB211460022034218BF0A4349005B1004
+:2088A00089B2F8D1104670470649042300200E3911F80E2FFF2A02D04A79101880B25B1EF3
+:2088C000F6D170476C0100200346104610B51A4630B1044B11F8014B62409A5C401EF9D184
+:2088E000104610BD08B1020002460648006800E0006928B103799A42FAD183689942F7D1C9
+:208900007047C0468804012005480EB50068436C0448006802216A4698479DF800000EBD00
+:20892000E0FF002080000120054808B5001D0068016C0448103000688847FFF764F808BDC1
+:20894000DCFF00207000012005490878832805D10020087003490870F0F780BE7047C046FE
+:208960000514012007140120002812BF40680548006828B1427B914203D040680028F9D155
+:208980000020704738050120064A936EC00B07D3104600F1580211609A4204BF00218166F3
+:2089A0007047C046ECFB002038B5064C04F10800006820B18569FCF7EFF8281CFAD1002087
+:2089C000A06038BDE4FA002010B5064C206901F0AFFC0146A06800B9E160A068401CA060BB
+:2089E00010BDC046C0160020054808B54168054801220838026048698969884708BDC046AC
+:208A0000841700200C200940064B1A69090907D31946886142F00203C8680B6101F0F0BCAE
+:208A20007047C0467CFB0020011C4FF0000308D01A46885C08B101230822521CD2B2082A3C
+:208A4000F7DB18467047022908BF017806D0C2780178837801EB026101EB0341407801EB1D
+:208A60000020704702294FF0000204D0012808BF4FF47A7203E0012808BF40F2EE22104655
+:208A8000704780B5074608464FB1437801787F1E00F1020001EB032122F8021BF5D180BD41
+:208AA0004FF00451002081F82004012081F86004022081F86A04032081F87804704710B5CA
+:208AC000FF2122220446F5F741FF00211F2204F12200F5F73BFF0020A07210BD402807DBD4
+:208AE0006528B8BF403806DBE02801DBF92801DBFF2070474530C0B2704710B5041C09D006
+:208B000001F0B6F94FF47A716143B1FBF0F000B9012010BD002010BD08B50420FFF718FCD8
+:208B2000062804DAFF20FFF713FC0C2801DD012008BD002008BD10B54468032001F0ACFBFC
+:208B400038B16278217801EB0221018014F8021F817010BD10B5401E491E11F8013F10F863
+:208B6000014FA34218BF002002D1521EF5D1012010BD0000054808B500784FF48071FBF72A
+:208B8000EBFF08B9FFF76CF808BDC0463BFD00200549C0310968012303FA00F200200A427E
+:208BA00018BF181C7047C04600200240054800684BF641310001B1EB104F14BF4FF0FF30E6
+:208BC000042070471813005008B5044B1B689B699847034A0021116008BDC046A80100106A
+:208BE00084046042044908B5096849698847034A0021116008BDC046A801001084046042C2
+:208C0000034605480068491C890089B201EB4331042301F031BAC04668FC002008B501235F
+:208C20008DF800206A46FBF729F80249491C087008BDC0465CFC0020806802680A604068FD
+:208C4000034A4860106800F00F0080028860704730240340054808B5006800F058FF00280F
+:208C600014BF6FF00200002008BDC04694130120054808B5006800F04AFF002814BF6FF008
+:208C80000200002008BDC046A81301200549B1F89400401CA1F8940080B210B90120F9F7EB
+:208CA0009FBC7047E4FA002008B501F0C5FB0349086001F06DFB0249086008BDE01301209D
+:208CC000DC130120044808B5006801F0C9FB0348006801F0A1FB08BDDC130120E013012035
+:208CE0004FF0FF3181600022026002710274027742771146C1604161816170470548B0F9DC
+:208D0000B610B0F9B400814202D10820FDF792BA7047C04630F5002038B51446054650232B
+:208D200040F2FF32FEF724FF1CB155F82010890A216038BD054908B56A46FDF795FA81287E
+:208D40000CBF9DF902006FF07F0008BD0100030410B5044601F03AFA03490A7814430C7030
+:208D600001F0BEFB10BDC046FD13012040684FF0FF330168034ACB6201688A60006801216C
+:208D800041607047001800200549097818B908460121F8F707BF02460846012101F0DBB941
+:208DA0003BFD0020054808B500784FF48071FBF7D3FE08B9FEF754FF08BDC0463BFD0020B6
+:208DC00005490839B1F89220904203D0A1F89200FFF7E8BF7047C046ECFA00200EB5ADF811
+:208DE00000000448019101688DF8082009B1684688470EBD78FD00200346054810B54468E1
+:208E000021700912617019460223F7F787FE10BD98FD002008B58DF8000004480068D0F89E
+:208E200030246946E020904708BDC0461401002001460548006830B142681278914202D0A2
+:208E400000680028F8D17047240501200EB54FF6FC70B4210122ADF800000F208DF80800EB
+:208E60006846F9F70DFB0EBD10B5054CE06828B1E068FBF791FE0020A070E06010BDC0463E
+:208E8000F00C0120044A054910600C3108608420042101F0B9B8C046E4FE002034FD002080
+:208EA000014605481430006828B10279914202D080680028F9D170474819002001460548D3
+:208EC000006828B10279914203D000680028F9D1002070472C1A002001460548006828B1C4
+:208EE000027B914203D000680028F9D1002070472C1A00200023038031F8012B02F0FF02CA
+:208F0000134303800988090643EA11430380704705494A680978801A8A00B0FBF2F1514356
+:208F2000401A80B27047C046D8000020054991F900004FF08073401C087000200246014663
+:208F4000F5F710BA120501200448002101700448007808B9F0F782BB7047C04607140120A3
+:208F6000051401200A684AB1904203D1106808600120704711461268002AF5D10020704754
+:208F800001460548006828B1027B914203D040680028F9D1002070473805012040B1054BC9
+:208FA00033F8022F914208BF012002D0401EF7D10020704734010020054808300068D0F8C1
+:208FC000B800007808B900F005B8F7F70FBEC0460C0100200448002101700448007808B9A2
+:208FE000F0F73CBB7047C046051401200714012010B5082211F8013B10F8014BA34218BF1C
+:20900000002002D1521EF5D1012010BD0F2808D9044B1038012100F01F024009914043F802
+:209020002010704780E200E0054B10B5044601F07BF9A06800280CBF0020201C10BDC04619
+:209040006003012001460548006828B10279914203D000680028F9D10020704790030120B1
+:2090600001460548006828B10279914203D000680028F9D1002070478C03012008B501F06B
+:2090800007F940B1002A07BF817801F0BF01817841F04001817008BD1CB50C466946FFF75C
+:2090A000C3FB002806BF009840884FF6FF7020801CBD0EB500908DF8041000208DF80500E2
+:2090C0008DF806006846F8F7A5FA0EBD38B50D460446EDF791FF4FF6FD700D2221462B4647
+:2090E000F5F73EFF38BD28B1401E082210F8013F994201D000207047521EF7D10120704716
+:20910000801E08B506D0401E00D0FEE700F092FB002008BDF9F730F908BD08B58DF8010088
+:209120000021032201206B468DF800000A20FBF7E1FA08BD0A68002A08BF086006D01146DE
+:2091400000E011468A68002AFBD18860704738B10628B8BF012006DB802801DB8A2801DBAF
+:20916000002070470220704710B503460C4650080021C0184FF0000341EB0401F3F74EF8EB
+:2091800010BD10B5041C08D000211C22F5F7DEFB4FF6FE702080401C608110BD01207047EC
+:2091A0000CB480B502AF3A6827F003031B1D01F06DF8BDE8804002B0704720380F2807D97F
+:2091C0001838022804D9A838022888BF002000D80120704708B500F07FFF28B1007918B1D1
+:2091E0000528B8BF012000DB002008BD08B500F073FF28B1007918B10328B8BF012000DB12
+:20920000002008BD0449891C01EB8000017801F0FB0101707047C04600100840044A121FA0
+:20922000126802EB80000268914218BF01607047DCC2020010B5044CE22034342146FEF7A0
+:209240004BFD204610BDC046ECFB002010B5002430B1C01D80B2F3F777F8FF2808BF012441
+:20926000204610BD0146034808B5006842680248904708BDD80100100040034000F8011BF4
+:209280000A0A00F8012B0A0C00F8012B090E00F8011B7047034610461A4628B111F8013B5D
+:2092A000401E02F8013BF9D11046704738B50C460546FEF73FFF296844F80C1C2C6000F015
+:2092C0001CFA38BD044908B591F8410118B1D1F86C0100B1804708BD101500201CB5C2F3A7
+:2092E000800302F001040093C2F340032246EAF71BFC1CBD70B515460C460646EFF755FCDB
+:20930000214630462A46EDF76FF870BD10B5044C00F078FF0146A26A6068904710BDC04647
+:2093200030F50020044908B51031096809B1884708BD002008BDC0464804012010B5044C71
+:209340000C3424680CB1A04710BD012010BDC04648040120044A12688A4202D8B1F1FF3F21
+:2093600001D1FDF7A3B970477CAC02000268406892F8303000780021042B18BF0121526972
+:20938000F8F7A8B9044810B500F078FF002400B10124204610BDC046041A002004490A78C5
+:2093A000904204D00870C8791021F8F7FBBB704734FD002008B5FEF71AFE800838BF002007
+:2093C00003D30020FEF7A8F8012008BD0449B1F1FF3F07BF0021081C0868091DEBF7B8BEF6
+:2093E000FFFFFFFF04480168002002E00968401CC0B20029FAD170471C03012004480168DB
+:20940000002002E00968401CC0B20029FAD170472C1A00200349891E08800349891E088004
+:209420007047C046220001203E19002008B5F8F711FAB0F1FF3F08BFE82002D0F0F778FF20
+:20944000002008BD044808B50068D0F82C134FF48050884708BDC046140100200448007809
+:20946000002808BF002001D0F7F7F4BB7047C04606140120022819BF024800680248006811
+:209480007047C046B810012094120120044808B50068D0F82C134FF40070884708BDC0469A
+:2094A0001401002010B5044CA06820B1F4F726F8E068F4F717FF10BDD800002008B500F0C5
+:2094C00085FE034908398A68CA6001F009F808BDE000002004490968D1F8EC2052F82000AC
+:2094E000D1F8E4100860704714010020044808B50068D0F82C134FF40060884708BDC046A6
+:2095000014010020401E082110F8012FFF2A18BF002002D1491EF7D101207047044910B14F
+:209520000A68126802600846001D00887047C04654FC0020044908B5CA681AB1497809B13B
+:209540001146884708BDC046E4FA002030B502FB01F403FB00444FF00005E2FB0054214627
+:20956000284630BD044808B54021A8300160FEF7BDFDFAF753FE08BD00A00C40044988680E
+:20958000401E886003D10869C96800F0C9BE7047C01600200121044A41600021C16012681E
+:2095A0008160801800F0B8BE1CC4020010B50446086903490968A0608847606010BDC0464B
+:2095C00028C402002022EFF3118382F31188426A1143416283F3118800F09ABE0448007819
+:2095E000012802D9C11E012901D8E6F749BA70474D02012030B10449814203D00021202257
+:20960000F5F7A4B97047C04660030120044800B502680A21ADF12C0D684690470BB000BD56
+:2096200088AD020010B54468022000F035FE20B114F8011B01702178417010BD10B544684B
+:20964000022000F029FE20B114F8011B01702178417010BD0448426A81881368806A19438E
+:20966000116000F0CDBEC046481900200448426AC1881368806A1943116000F0C1BEC0468F
+:2096800048190020044A516A10890B6818430860906A00F0B5BEC0464819002003461046EE
+:2096A0001A4628B111F8013B401E02F8013BF9D11046704708B5044B024600214FF080503D
+:2096C000FDF724FC002008BDAD77020008B5044B024600214FF00060FDF718FC002008BD6A
+:2096E0000953020010B500210446FEF759FD002108222046EBF7ECFA10BD08B50090BDF849
+:20970000020000F0EDFEBDF8000000F085FE08BD10B50129044698BF012100F04BFD20462F
+:2097200000F04AFD10BD0146002304204A1C02F8013F401E1371FAD10B80704738B1017BA3
+:2097400001F07C01042903DB40690028F7D1002070470A7A02720A7A022A02D00822FFF786
+:2097600099BD09880180704710B50446FEF726FE032000F009FE204600F03EFE10BD10B564
+:209780002021EFF3118481F3118800F0BDFD84F3118810BD08B5F7F70DFF024901200870E2
+:2097A00008BDC0461505012008B5F7F703FF02490120087008BDC0461F05012008B5E7F767
+:2097C000CBFDEDF74BFAF9F73FF9DFF7FCFC08BD034910B51CC91CC006C980E8060010BD01
+:2097E000E8C102000349096800EB5100B0FBF1F000F06ABE40C4020010B5044600F0E6FC3A
+:2098000000216160216000F06BFE10BD03480078002814BFFE20FF207047C04624000120C2
+:20982000034908310A681040C2430A607047C0460810044008B5E6F79DFF0028FBD0401ED2
+:20984000012800D9FEE708BD034938B53CC93CC01EC980E81E0038BD68C0020010B50021B0
+:209860000C220446F5F772F84FF0FF30207110BD0349103108680028FCD00020086070471E
+:209880000C10044008B5C2F3800302F0010200930123EAF749F908BD0EB50091019291F96E
+:2098A00004300A680121EAF7DBF90EBD0328BABF024901EB401000207047C04610F7002031
+:2098C000034938B53CC93CC01EC980E81E0038BD88C0020001604260836100218160016157
+:2098E0004161521EC2607047034910B51CC91CC006C980E8060010BD10C2020010B504689C
+:2099000004F1340000F076FC002084F8310010BD02460348007814210823F7F78FBCC04678
+:209920007CFB0020024603480078B0210823F7F785BCC0467CFB0020024603480078E621AB
+:209940000823F7F77BBCC0464B190020024603480078E4210823F7F771BCC0464B1900204D
+:2099600003483E30007800280CBF0120002070474DFF0020034991F8D40040F0040081F809
+:20998000D400704750180020034A5168401A11788900B0FBF1F07047D80000200249088034
+:2099A000024908807047C046220001203E190020034808B50078FEF783FC012008BDC0467D
+:2099C0007000012000280CBF00200120014908707047C046E9FA00201CB514460A4601467E
+:2099E000009300202346FBF725FF1CBD0A7A032A02721CBF0988018001D100F0CDBB704749
+:209A0000034808B508300068006B804708BDC0468401001000B903488A0002EBC1010818AF
+:209A20007047C0460005012008B500F069FC0248006800F06DFC08BD8C16002010B5044690
+:209A400000F052FD844232BF001B001B401E10BD034A014608B50820FDF7BEFE002008BDA1
+:209A60004DF00100034A014608B50220FDF7B4FE002008BD71580200034A014608B510205E
+:209A8000FDF7AAFE002008BD75680200034A014608B54020FDF7A0FE002008BDDD3302002C
+:209AA000034A014608B50120FDF796FE002008BD8F1A020001460120042903D00A291CBFA6
+:209AC0000329002070474FF6FF70884203D0C8B2002100F08FB870474FF6FF70884203D058
+:209AE000C8B2012100F086B870474FF0FF3280680A6042684A6080688860704708B58022E9
+:209B0000FBF7D6FC002814BFC068002008BD08B500F0DEFC002814BF00204FF0FF3008BDA4
+:209B200008B50020FDF7F8FCFF200321FCF72AFA08BD40698178002001E0401CC0B281420D
+:209B4000FBDC7047024910B51EC980E81E0010BD94C20200024A02EBC000F8F721BFC04607
+:209B6000C8C30200024910B51EC980E81E0010BDA4C20200024A02EBC000F6F733BAC046CD
+:209B8000D0C30200014602480078F9F785BDC046DC04012002480068FF21FFF7A4BAC046C2
+:209BA000B800012001460248006800F0F5BAC046B80001200248FF2140F22C72F4F7C6BEAC
+:209BC000E40D002008B500F059FB002100B10121084608BD0249096851F820007047C0468A
+:209BE000DCC20200024A126842F820107047C046DCC20200024A01F0010111547047C046D7
+:209C000000200240002101604FF0FF3141600121017270470248002153300170EAF70EBEF8
+:209C2000E4FA0020024A11680840C1431160704708100440024900220C39CA610860704795
+:209C40000C10044021B10969884208BF012000D00020704710B5F8F7C9FF0446F3F7A0FDBA
+:209C6000204610BD00F00300022101FA00F000F01C007047002101604FF0FF328260416078
+:209C8000C1607047024A02EBC000F1F7A9BDC046D8C30200024A002142F820107047C0466E
+:209CA00074FD002008B5FFF7C3F8002814BF4068002008BD024800788021F8F731BBC046D9
+:209CC0004DFF00200249087006200121DEF79ABC8AFF002008B5FF210E22F4F737FEF0F725
+:209CE000BDF808BD486800280CBF022012204870012070470F2802D90149103808607047A0
+:209D000000EF00E002490968401800F0F5BAC0461CC4020008B5024940680968884708BD24
+:209D20002CC4020008B5024B40681B68984708BD24C4020008B5024B40681B68984708BD95
+:209D400030C4020008B5024A40681268904708BD34C4020008B5024940680968884708BD97
+:209D60003CC4020002490020087048807047C046F003012008B5FFF765F9002814BFC06831
+:209D8000002008BD08B500F083FA002814BF8078002008BD08B5FFF755F9002814BF8068F8
+:209DA000002008BD0068002180F822100B20EFF795BB03461979DA88D8781B7AFBF796BEC2
+:209DC00019B900210822F4F7C1BD00F0E5B941600423826000210370084670474160022366
+:209DE000826000210370084670471346024618460B460021FFF7F0BD38B50468049D646A0C
+:209E00000095A04738BD0969006981420CBF0020C8687047416882680020914208BF0120F3
+:209E2000704708B5FDF732F96421B0FBF1F008BDD0F80320C31D08461946F1F757BE08B587
+:209E4000FFF7DEFD000C0904084308BD0068002101700B20EFF742BB017841F08001017064
+:209E6000FEF788BE08B50090684600F01DFB08BD014800687047C04640C4020001480078AA
+:209E80007047C046041401200148001D008870471EFB0020014800787047C046EFFB002066
+:209EA000014800787047C0461AFB0020014800887047C0461EFB0020014908707047C046A9
+:209EC000EFFB0020EFF3108072B6704700207047EFF3108062B670470020704713460A468F
+:209EE00001461846FEF7F0BC0148006800F084B9941301200148006800F07EB9A8130120C2
+:209F000008B50221FEF79FFD80B208BD08B5014688684968884708BD18B1006808B100F0C6
+:209F2000BBBA704701480830006870471015002001491231085C704748160020014909781F
+:209F400008407047FD13012008B50090684600F0CFF908BD014800F09FBAC046041A002083
+:209F6000014A42F82010704774FD00200149091F0860704754050120014908607047C0466A
+:209F800054050120014800787047C0468EFF002001494331087070474CFF0020D0F80320D9
+:209FA00008460021F4F7D2BC014800687047C0467804012008B5FBF7C5FBF3F7E3FA08BDB3
+:209FC00008B5EEF785F9EBF7DDF908BD01480021017070470414012001490C310860704773
+:209FE000DCFF0020014800787047C0466C110120014800687047C046ECFA002013460A462D
+:20A0000001460020F8F744BB13460A4601460020FCF718BB08B51046F7F7AAFE002008BD87
+:20A0200001B9014900F060B9D0C10200426808604A60116041607047014880687047C0460D
+:20A04000E4160020014800787047C04682030120006908B1FAF7A0BD704700218160017028
+:20A060004160704708B503689B68984708BD08B50268D268904708BD10B50468E469A04757
+:20A0800010BD08B5FAF708FE80B208BD4068002180F8FD10704708B501680968884708BD18
+:20A0A00008B502681269904708BD406800680121C164704708B5FAF7EFFDC0B208BD02463B
+:20A0C00056210020F9F762B900212422F4F73EBC00211022F4F73ABC01460020F5F776BCD9
+:20A0E00001464A20FDF7F8BD406800210170704700210222F4F72ABC6422514300F0A4B998
+:20A1000040686C3000F078B808B1FAF745BD70474FF0FF309060704708B1FAF73DBD704708
+:20A120000222E9F7EDB90122E9F7EAB90222FAF7F3BF0122FAF7F0BF0021F5F747BC0068CD
+:20A1400041617047401EFDD170476FF0010070470123EEF7F9B90023EEF7F6B90720F3F729
+:20A16000E5BB0022FCF780B80022FCF77DB8401C80B270470320FAF769B9C000FFF7E2BFD6
+:20A18000E920F2F751BF0846F2F764BD0846FAF703BD4122FFF782BA0822FFF77BB881609D
+:20A1A0004260704730BF704700F09AB800F094B8FCF76CBF00F048B900F042B900F06CB913
+:20A1C00000207047FEF722BF00F082B800F0FCB800F07AB800F074B8FFF78CBD00F06CB873
+:20A1E00000207047002070470020704700207047F3F7D6BA00F05CB800F002B900F054B8DE
+:20A2000000F0C6B8FFF718BFFFF7DCB900F080B800F016B9FFF74ABEFEF7E6B90020704728
+:20A2200000207047002070470020704700207047F32070470020704700207047DC20704797
+:20A24000DD207047002070470020704700207047C2207047FDF7D7BBFFF700B90020704720
+:20A2600000207047002070470020704700207047012070470120704700207047808A70473A
+:20A2800080687047EEF792BC0120704700F008B800207047FFF766BDF2F7DCBCF4F756BBF7
+:20A2A000DFF800F0B9F80210DFF800F0BDE80210DFF800F0FDE60210DFF800F019E90210FF
+:20A2C000DFF800F01DD90210DFF800F0D9D80210DFF800F075E40210DFF800F0FDE9021034
+:20A2E000DFF800F049E60210DFF800F0C9F40210DFF800F0DBEC0210DFF800F09DE80210C2
+:20A30000DFF800F0D7DB0210DFF800F0B1D70210DFF800F091D80210DFF800F0E5DE021073
+:20A32000DFF800F07BEC0210DFF800F019D70210DFF800F077EC0210DFF800F067F30210A5
+:20A34000DFF800F0C5EA0210DFF800F049DC0210DFF800F0F9F20210DFF800F0EBEC021003
+:20A36000DFF800F06BEC0210DFF800F031EC0210DFF800F0F1DC0210DFF800F059F50210EA
+:20A38000DFF800F01BD00210DFF800F011EA0210DFF800F025EA0210DFF800F0D7EC0210A1
+:20A3A000DFF800F0D3EC0210DFF800F07DE80210DFF800F021D40210DFF800F049EB0210EC
+:20A3C000DFF800F0E5F80210DFF800F055EB0210DFF800F08DDD0210DFF800F0F1EB0210B6
+:20A3E000DFF800F039F70210DFF800F0AFEC0210DFF800F0ABEC0210DFF800F0B1F70210EF
+:20A40000DFF800F021CD0210DFF800F0B9DC0210DFF800F0CDEB0210DFF800F045DF021079
+:20A42000DFF800F0D9EB0210DFF800F021EB0210DFF800F02FEB0210DFF800F04DEA021097
+:20A44000DFF800F0E7E90210DFF800F0C3EC0210DFF800F025DB0210DFF800F09DEB021091
+:20A46000DFF800F061DB0210DFF800F0F1EC0210DFF800F05DF10210DFF800F0C5F3021059
+:20A48000DFF800F0A5EA0210DFF800F0D9D50210DFF800F009EC0210DFF800F0C5E202107F
+:20A4A000DFF800F01D870310DFF800F0BBEC0210DFF800F0F5EA0210DFF800F0C1DD02106F
+:20A4C000DFF800F0E5EB0210DFF800F001CE0210DFF800F0B1BF0210DFF800F011F7021001
+:10A4E000DFF800F047EC0210DFF800F011DC02109A
+:20A4F000C4130120E00F0120541301205410012000000000AC110120CC1301205C120120CA
+:20A5100064130120E810012098BE0200F4C202008AC3020010C3020002C3020074130120D7
+:20A530008C0101209001012094010120980101209C010120A0010120A4010120A80101202B
+:20A55000AC010120841301201C1001201C130120141101204EBA0200DCB90200C0BA020065
+:20A5700032BB0200A4BB0200B8C1020044C3020038C3020009140120AC1301205C0401205B
+:20A5900078120120B802012001140120021401208810012030130120C8FC0020B0010120E5
+:20A5B000D4B7020008B202000000000000000000E4C20200E40B0120F8130120F413012036
+:20A5D000B4010120B8010120EC13012018BE0200C8120120640E0120000000000000000035
+:20A5F000A00401200000000000000000000000000000000058010120100A0120E8050120C3
+:20A61000014A031049480310D549031015470310F5A701005D49031081470310A14603105D
+:20A630009548031045450310254A031021440310ED47031099490310E1480310214903108E
+:20A650005553031089520310CD520310655003108D4E0310A1AA010081ED0100F5040200A3
+:20A670000000000059510310ED5003101DF70100CD4B03102952031011530310A955031067
+:20A690007555031069530310DD55031035550310F9A9010021540310855C03100D56031087
+:20A6B0004D5D0310A9640310B55B03106D570310E5610310095E0310C558031085600310B8
+:20A6D00071610310B16203109963031055630310FD600310B15E03108D8F0100D55A031094
+:20A6F000D559031009630310D963031019640310555F0310C56403104D62031071640310FE
+:20A710008D64031055640310E16403102975031079720310A16B0310F57203109D74031095
+:20A73000797403102D74031061730310FD7303105574031015750310D96C0310FD74031096
+:20A75000AD4B0100E17403103D75031081A20100F9640310CD6803102D710310C1740310EE
+:20A77000F56E0310B973031029670310056E0310C56F0310EDC00100A1770310797D0310C2
+:20A790003D7E031049750310157E0310357D031099760310997C0310257B031071780310A6
+:20A7B000B57D0310ED7C0310857E03102D790310B97A0310917B0310B1790310ED7B0310DC
+:20A7D000E97D0310617E0310357A0310D57E0310457C0310A57E0310BD7E0310B97801004C
+:20A7F000D9800310E97E031049830310898403108D8103107D820310E58403102B840310F3
+:20A81000C5830310918703106188031045880310F1850310B18803107D880310C988031075
+:20A830001D870310A186031001850310E188031099880310F9870310399C0100359C031081
+:20A85000819D0310E99A0310359B0310C19B0310419A0310F18803101D8C0310618F031096
+:20A87000F1940310919E0310C19E03103D9E0310699E0310259E0310619D03100D9E0310CF
+:20A89000819B0310ED93031055990310C9970310D9980310BD950310959C0310C19D0310D4
+:20A8B000A59E03107D9E0310C99103104DC70100699C0310DD9D031095900310FD9B0310FA
+:20A8D000CD990310158E0310019D0310E19C0310219D0310419D0310BD9C0310F59D031025
+:20A8F000A19D031055980310E1920310999A0310B99E0310559E0310716402004F91020002
+:20A9100039A20310DD8A020069A1031075A20310C59E0310B9A10310F9A1031015A1031030
+:20A930009DA20310CD9F0200DF6401009D920100FD5302007D9E0200A1B5000031A9031021
+:20A95000ADA20310A9220100B9A8031099A50310A1A8010039A803106DA90310817F01008C
+:20A970006DAC031099B1031009AF031059B1031001B103109DA9031045A2020041A202006A
+:20A9900031A2020025A2020039A202003DA2020029A2020035A2020049A202004DA20200C7
+:20A9B0002DA20200F1B9031075BA031081BB0310E55C020055DE01001519020051900100DF
+:20A9D0008157020011110200BD6D020075110200AD5C020009830200658F0200B518020057
+:20A9F000FD400200756502004D32020089040200D594020009ED01000944020005950200CF
+:20AA100061A2020069A20200D1FD0000F9180100E9C6031065A2020095940000E5A10200B8
+:20AA3000BD5F020053970200D319020075A1020069910200E1A1020051A20200E11E020080
+:20AA5000F9CD01001DCA010001000000000000000000000000000000FFFFFFFFB005012064
+:20AA70000400000000000000000000001400000030FD02101800000008C4020018AB0200C4
+:20AA9000880501200400000000000000000000002400000018FD0210180000000D960200EC
+:20AAB0000800000008AC0200CCAA0200C1C8021001BB021091EB0210DDE5021081E0021012
+:20AAD000B9E5021071E5021031000000010000000100000044C4020000000000FFFFFFFF15
+:20AAF000A805012004000000000000000000000028000000B8FC0210240000001E00000044
+:20AB1000180000000000000080AD02002CAB02009BEC021025E2021005EB021025DE02103C
+:20AB3000FDE10210E1E402102F00000034000000240028000000000008040120FFFFFFFF66
+:20AB5000D0050120040000000000000000000000380000006CFC0210280000000100000010
+:20AB7000100000000000000000000000F7F1021000001A00100000000300000074C3020055
+:20AB90001FC30200080000003600000040030120EC01012009001D00B3C201002001012033
+:20ABB0000100000000001200FFFFFFFFC0050120040000000000000000000000100000007C
+:20ABD00048FD0210180000000000000000001300FFFFFFFFD80501200400000000000000E5
+:20ABF0000000000054000000A0FB02103C000000000001002D0000005CAA02006BB00100B6
+:20AC1000300000000000000008AC020030AC0200E9260200D9DB021059EC0210CDD602107D
+:20AC300085DE02104DE5021029E5021030000000000016000000000000000000FF7F000067
+:20AC500000FF0020FFFFFFFFB805012004000000000000000000000058000000DCFB0210A6
+:20AC70003400000039FB021001002F00060000000000000020000000010000001BF80210CE
+:20AC90002800000080AD0200A8AC020093EC02106DEB02104DEC021029E00210BDE40210E3
+:20ACB00099E402102D000000000000009005012004000000000000000000000010000000FE
+:20ACD00040FC02102C000000000000000000030000000F003C00000000000000000000009C
+:20ACF0002FF90210100000000800000024C20200FFFFFFFFC805012004000000000000001C
+:20AD1000000000001C000000DCFC02102400000094AC020078050120040000000000000015
+:20AD3000000000000C00000000FD021018000000CBD101000000000000000000080000002B
+:20AD5000010000000400000000000000000014000000000044BD0200000019000000180096
+:20AD70002400000089A2020000400000000200005CAA02000000100055F002100C000000B5
+:20AD9000F15C010000000000700501200400000000000000000000002000000010FC02107D
+:20ADB000300000005CBD02000100000011A10200EFAB0100000000000000170000020000CF
+:20ADD0003100000000002300000015000100000018AC0200A0050120040000000000000069
+:20ADF000000000002000000094FC02102400000074BD02000005012020000000FCBF020027
+:20AE10008F0001001C05012087000100ADFE00203500280034FC002028000100C1FE002048
+:20AE300029000100AEFE002084000400E4FE0020860001008DFF00202A000100BAFE00204C
+:20AE50002B000100AFFE00202C000100B0FE00202D000800F0FE00202E000100B1FE0020AD
+:20AE70002F000100B2FE002030000100B3FE002032000100B4FE002033000100B5FE0020B4
+:20AE900034000100BFFE002036000100C5FE002038000100C6FE002039000100BEFE002043
+:20AEB00083000200DEFE002063000100B8FE002065000100C2FE00206D000100B9FE00203C
+:20AED00071000800F8FE002066000100D3FE002043000100B6FE002044000200DAFE002025
+:20AEF00045000100D0FE002046000200DCFE002047000800E8FE002048000100D1FE00203F
+:20AF10004B000100B7FE0020040001001B050120A10001001E050120370001001D05012059
+:20AF300088000100D7FE00203C000100C7FE00203D000100C8FE00204900020018050120B4
+:20AF500067000100D4FE00204D000200E0FE00204E000100D2FE00204F000200E2FE0020AA
+:20AF70003E000100C0FE002051000100CAFE002052000100CBFE002053000100CEFE0020EE
+:20AF900054000100CFFE002000000000000000005D40002189400021954000213B41002124
+:20AFB000074C657900F009F861796940490703D50121044A8903116070BD70B5024908475B
+:20AFD00080030021081104402D59000000F00AF800480047577F000000F00AF80048004702
+:20AFF0001B880000806B0C490007000F48717047094A0A4918235079CB56497EC0188142AB
+:20B0100001DD084602E00F2800DD0F20D189090909010143D1817047E00200218800002160
+:20B030000122274B02212548184710B5254880472548406A00280DD124490A200856002849
+:20B0500009DA401C07D008462038406A2049884200D1804710BDFFF7E3FF10BD00211E4BB3
+:20B070001C4A0846184701201C49400208601C48FB220178114001701248EC38004710B537
+:20B090001849884711492039012807D0020404D50020088514484862012010BD4A6A094B35
+:20B0B000EC3B9A4201D1114A05E007494A6A104B9A42F2D10F4A4A6210BD0000060800008D
+:20B0D0009F060000A1920200080100215401002163920200E7400021B5B4020080E100E0FB
+:20B0F00080030021F7960200DD4000212341002169950200194100210097B92EE5725CCBD3
+:20B110005DCAE473B82F0196BA2D03945FC8E671E7705EC90295BB2CE3745ACD0691BF282F
+:20B13000BE2907905BCCE27559CEE077BC2B05920493BD2AE17658CF51C6E87FB4230D9A0F
+:20B150000C9BB522E97E50C7EB7C52C50E99B720B6210F9853C4EA7DB2250B9C57C0EE79EF
+:20B17000EF7856C10A9DB324089FB126ED7A54C355C2EC7BB027099EA2351B8C47D0FE69CF
+:20B19000FF6846D11A8DA334188FA136FD6A44D345D2FC6BA037198E41D6F86FA4331D8AAF
+:20B1B0001C8BA532F96E40D7FB6C42D51E89A730A6311F8843D4FA6DF3644ADD1681AF388F
+:20B1D000AE3917804BDCF26549DEF067AC3B15821483AD3AF16648DF1087A93EF5624CDB6F
+:20B1F0004DDAF463A83F1186AA3D13844FD8F661F7604ED91285AB3C0001363601010001DB
+:20B21000020100010301000104010606080400000C0100340D01000F10040101140100FF70
+:20B230001608000020020000220100FF23010001240100FE250100082602000028010001D4
+:20B25000290100012A0200002C01000F2E0200003001000131010008320200FF3401000740
+:20B27000350102FF360100003701000138010001390100FF3A01000F3C0200FF3E01010FCE
+:20B290003F0100014001041F41010001420100FF43010080440800004E0100084F01000FAE
+:20B2B00050010001510100FF520100005301000054010001580400005C04000060040000BE
+:20B2D00064040000680400006C0400007004000074040000780400007C040000800100FFB2
+:20B2F00081010001820100018301020284010001E20501200B1401200C140120E105012099
+:20B3100003140120E3050120E0050120D99F0200ADDF00002D94020021760200F575020008
+:20B33000CD1D0200291E0200FD3102007D470200F17D02002D6D0200FD6C0200B5A0020004
+:20B350000D980200E9850200A56402009D8202009D99020015940200798202005D6D0200EE
+:20B3700085D50100C98E01000B7902008925020055180200B59F0200C19F020000000000AD
+:20B390002989020097690100D1DD01004557020000000000D9640200E59F02001D5D02005A
+:20B3B0008D9402000000000000000000050F0100098902003DCB0100293A0200C0C1C2C33D
+:20B3D000C4C5C6C7C8C9CACBCCCDCECFFF000000000000000000000000000000FF000000ED
+:20B3F0000000000000000000000000002100000010002081E8040120210000001100438168
+:20B41000000000002100000012002083E90401202100000013002083EA0401202100000031
+:20B4300014002083EB0401202100000015004381EC0401202100000016001A81FF05012033
+:20B450002100000017001A81FC0501202100000020001843F0040120210000002100F143C0
+:20B47000C0040120210000002200F143B004012021000000FDFF2141F2040120032C0000C6
+:20B49000000000000000000000000000000000000308000000000000000000000001650922
+:20B4B0000000000000000000012C000000000000000000000001001E000000000000000030
+:20B4D000020800000000000000000000000101000800FFFFF4040120D4030120B80301205D
+:20B4F000022C0000000000000000000000000000000000000000000000000000000000000E
+:20B510000128000000000000000000000001003000000000000000000003FF186400000043
+:20B5300000000000000000007856341200000000BAAB000000000001000000007F430200BD
+:20B550008DEE0000D991010025BC010091A401000D2C010091A40100B9D30000F1140200DA
+:20B5700025BC010091A401000D2C01003541010025BC01000000000000000000492902009C
+:20B5900025BC01000000000000000000E1A3010025BC01002596020025BC0100378B0200EF
+:20B5B000C19C0000912D020025BC010000000000000000000000000000000000000000007C
+:20B5D000000000003D960200C11B01001567020025BC01003D960200C11B01001567020019
+:20B5F00025BC0100378B0200C19C00006521020025BC0100000000000000000000000000CE
+:20B6100000000000000000000000000000000000000000000000000000000000000000001A
+:20B630000000000000000000000000000000000000000000000000000000000000000000FA
+:20B650000000000000000000000000000000000000000000000000000000000000000000DA
+:20B670000000000000000000000000000000000000000000000000000000000000000000BA
+:20B6900000000000000000000000000000000000000000000000000000000000000000009A
+:20B6B000000005000600080009001600020102020302000301030105020500060106040B0C
+:20B6D00014061506170600070107020703070009040907000A000C000D000E000F00100079
+:20B6F00011001200130014001B00000101010002010202040004010403040404050406049C
+:20B710000005020603060406050606060706080609060A060B060C060D060E060F06100633
+:20B7300011061206130604070009000B010B020B030B0000FFFFFFFFFFFFFFFF1300000060
+:20B75000492101001F000000217601001F800000CB52020000000000A9D10000010000007E
+:20B77000A9D100000200000055800100028000005713010003000000B9DA010004000000DF
+:20B790007937010004800000871E0100050000004DF501000600000051C700003100000027
+:20B7B0000183000033000000014001003400000059E701003600000049100200FFFF00007C
+:20B7D00000000000360001000600000000000000000F00000000000000000000000000000D
+:20B7F00000000300FFFF00000403FFFF0000FFFF0F00E8030005401F0310000100000000C3
+:20B81000FF3F0F000800050B00000000000000000300010F000000000000000000000000A0
+:20B830000000000000000000000000000000000000000000000000000000000000000000F8
+:20B8500000000000AD00000200000000000000000000000000000000000000000000000029
+:20B870000000000000000000000000000000000000000000000000000000000000000000B8
+:20B89000000000000000000000000000000000000000000000000000000000000000000098
+:20B8B000000000000000000000000000000000000000000000000000000000000000000078
+:20B8D00000000000000000000000000000000000FFFFFFFFFFFFFFFF000000000000000060
+:20B8F0000000000000000000000000000000000001000000D9C0000006000000778401009C
+:20B9100008000000BD0C02000B000000F342020010000000E91F010002000000F19C010059
+:20B93000050000002D160100070000007D3201000C000000119A00000D00000055170000C7
+:20B950006400000049530200FF00000000000000000000040000000003002001A2C3020047
+:20B970000000000000002005A3C30200000000000500420180C3020000000000004042011A
+:20B9900093C30200000000000400420170C202000000000007003001A4C302000000000023
+:20B9B00011003003F003012000000000FDFF21019EC302000300000000002103F203012061
+:20B9D00003000000FDFF2101A0C3020001017101010101011101010131010101010180018E
+:20B9F0000001100161013B001400630173017201620143010001130106013D0135000401EE
+:20BA10001201000100010001000104010401330133013C014401320136000001000165013A
+:20BA300000013500810100010501820183010001660100010001080109010A010B01030099
+:20BA50007100300160001100700031022003500480000700100061000000140063007300C7
+:20BA7000720062004300000013000600000000000400120000000000000000000400040068
+:20BA9000370037003C02440000000000000000006500000035008100000005000000830003
+:20BAB0000000660000000000080009000A000B000302710230016002110270020102020253
+:20BAD000020280020002100261023A00410063027302720262024302000213023800000296
+:20BAF000000204021202000200020002000204020402370037003C024402000239000002D7
+:20BB10000002650200023502810200020502820283020002660200020002080209020A024F
+:20BB30000B020103710301030103010301030103220302030103000310030003000300030F
+:20BB5000000300030003000342030003240306030003000304031203250323032503230393
+:20BB70000403040300030003000344030003000323030003650321003503810300030503D8
+:20BB9000000300030003000325032303080309030A030B030304710402046004110470049A
+:20BBB0000204020401040204000410046104000414046304730472046204430400041304A9
+:20BBD000060400040004040412040004000400040004510464000004000400044404000404
+:20BBF000000400040004650400043504810464000504000483040004660400040004080484
+:20BC100009040A040B042100D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF000000000000000051
+:20BC300000000000000000005A6967426565416C6C69616E636530390A0000000200000030
+:20BC50000400000008000000100000002000000040000000800000000001000000020000D5
+:20BC7000000400000008000000100000002000000040000035810200FB96020055CC0100CB
+:20BC9000994B020089860200EDBA01004DE90100DB840200A98602001B71020049710200E2
+:20BCB0004F520200AD670200AD920200491B020099360200810F0200A51B0200DBFD021005
+:20BCD0002D83020011DC0210E1CC0100199F020081770200ED99020099A10200F18F0200FB
+:20BCF0008F0000008F0001008F0002008F000300900000018F0001019000000290000003AB
+:20BD10008F0001048F0000058F0008048F0000048A000006510000007F0001003F00040019
+:20BD30003F0002003F0001007F0002008F0002048F0001027B7374617469632D696E7374DC
+:20BD5000616E63652D6E616D657D00C07B656D7074792D696E7374616E63652D6E616D6537
+:20BD70007D00C0467B756E6B6E6F776E2D696E7374616E63652D6E616D657D00AD20020009
+:20BD90001FF9021045F8021059F802106DF8021081F8021095F80210E5E40100CD6F02000E
+:20BDB00059500200A7680200E1830200019A0200E9890200355E02003F9E0200F595020040
+:20BDD00075FF010000000000000000000000000000000000000000000000000000000000DE
+:20BDF000000000000000000000000000000000000000000000000000000000000000000033
+:20BE10000000000000000000C003000080070000000F0000001E0000003C000000780000E7
+:20BE300000F0000000E0010000C003000080070000000F0000001E0000003C0000007800F6
+:20BE50000000F0000000F0000000004017FF0000000000000400FFFF080000001000000082
+:20BE70004018002030180020401A0020301A00200A000000090000000C0000000B000000C4
+:20BE900009080AFF0A0000000000000002000000020000000A00000002000000020001005B
+:20BEB000000000000000000000000000000000000000000000000000000000000E00000064
+:20BED000000000000000000000000000000000000000000000000000000000000000000052
+:20BEF0000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF99CF0000D2
+:20BF100071200000C97C000051760000E96B0000AD390000E97F0000DD4000002DC50000C3
+:20BF30000100010001000100010001051E0D0C1C1D1E0F0E0607140A0809000102000100FB
+:20BF5000010001000100010200010205E9A002004BA102002D6A0200398C0200452B020078
+:20BF7000558C020065E10100D5440200E99E0200F1390100A9D80100857202005D6A020074
+:20BF9000EB9A020001620200718C0200F1620100C53C0200F59E0200C514010000000000E0
+:20BFB0000060250000100000A00F012040000000000000000000000000093D001400000072
+:20BFD0006400000008AC0200ECBF0200259D0200359D0200559D0200459D02005D7002004B
+:20BFF000298402005D7802003200000015F9021001E602102DDA021045E7021041D10210E5
+:20C01000C9D30210A5DF02102DE4021061EA02109950020080AD020038C0020075A202001F
+:20C030009DCF010091F70100FD6F020005840200317802002E000000FFFFFFFFFFFFFFFF30
+:20C05000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF00000000EA
+:20C0700000000000000000003A013A0100000000000000000000000000000000FFFFFFFF3E
+:20C09000000000000000000040420F0008000000000000000000000024C00200800501206B
+:20C0B00004000000000000000000000020000000D0C1020018000000D4BF0200980501204E
+:20C0D000040000000000000000000000140000003CC102001C00000000000000000000001D
+:20C0F0000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF0000000038
+:20C1100000000000000000000000000000000000000000000000000000000000000000000F
+:20C130000000000000000000000000001C000000000000000000000050C1020000000000C0
+:20C150000800000000000000FFFFFFFFFFFFFFFFFFFF0000000000000000000000000000D1
+:20C170005CBF0200F013012000C4020084BF0200B8130120ACBF0200392E0200A96801008F
+:20C190008DA00200C54401008D7900007910010000000000020000000100000003000000C0
+:20C1B000100000002000000000000500BD00B700B100BC001C003000380008003801020092
+:20C1D000180000000000000000000000E0C10200080000000000000005000000D0070000B0
+:20C1F000C8000000FF00000000000000000000003D8D010001910200010101000000000006
+:20C21000020000000000000000000000FFFFFFFF000000000100000000000000000000000F
+:20C230000000010000000100001610000018151002000224145800001000000600000000DF
+:20C250000000000000000000000000000000000000000000000000000000000000000000CE
+:20C27000105465786173496E737472756D656E7473400000000000000000000000000000AD
+:20C29000000000000200000000000000FFFFFFFF000000000200000000000000FFFFFFFF92
+:20C2B000000000000F010000010000000E01000001000000580F0120B4C202007C0F0120A1
+:20C2D000BCC202008C1700206C0D0120E80D0120FFFFFFFF88B22400881300001000000056
+:20C2F0000000000100A6AAACA4A9A9A399B19ABCB6A8313118191A22311C1E203131343179
+:20C31000313117191A21241B1D1F313133312000000000000000000000000000FF000000E0
+:20C3300000000000000100000C0E020B040B0A070800110F000120181A18182C34041E0078
+:20C35000FF000100F59202000700000088C102001009012058BE0200FF00000000000000A1
+:20C3700080A9030025DD021031C8021075DF02100974692E726F757465720204020101013C
+:20C39000010902083230323230313235010A0200010001030100000000BE040A00BE020844
+:20C3B0000102000302000103FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB012012081C2020049
+:20C3D000401101201EC302006C0C012068C30200CC11012010C40200038000CC038000DDAF
+:20C3F0000380000C0380005D038000C0038000D500000500006000000000000000000000BE
+:20C41000000002400A29FF0000000000100000000100000087A1020079A20200F7A901009F
+:1CC430008DA10200C13A02003D33020071A202000A000000C592020000000300D6
+:20C44C005D9F0000F14D0100000000000000000000000000DD920200859802007DF3010094
+:20C46C004998020069A1020063A102009998020000000000F1A0020009F301001DFB0100DF
+:20C48C00358D0200FDC80100FD9A02006174010089CD000065D30100698702000000000016
+:20C4AC00D1230200E18C02000DB1010095970200559B02004D9E0200459B0200C9A00200F2
+:20C4CC0027A1020021A10200A9970200759B0200A59D0200659B0200D1A0020033A10200DF
+:0CC4EC002DA10200DD9D0200CF9D02008A
+:20C4F800003D00000F05D41B002001BF06017FFFFFFEFFEFBD9D914402004CC4027300B826
+:20C518000030FFE1150101FFEFDA1FEEFEBFC701957402FFE6ECC604FF0000EEC806000021
+:20C53800F1FDCA0040F4CC0A0000F6EDCF0040F7D00090FAD410FF0000FBD6120000FDFB20
+:20C558009318FFE05328000001FD560040025932000003FF5D38000004634E00FF00051736
+:20C57800720000062AFF4F1480075F281480FF085A331080095F3FFF10800A664F10800B49
+:20C59800FFCB2130800CCC273FFF800DCDC33F800ED6FF271B800FDA2F1B80FF10DE391B36
+:20C5B8008011E54FFF1B8012E047308013FFE2613F8014F5753F5F807FFFFF3FFFE10F19A7
+:20C5D8003FD801B9A21937FFEF0110FEFFFFEF580362FFE520FFEFC6012F30FFEF153BFD86
+:20C5F800105F20D9A5033F21FFEF46FEFF00050000D200A6FF0159FFE8011FB38813FEFF5A
+:20C61800EF3C010103071E0205E91E431047800200E00D0A01DB020106E00A0100000809AB
+:20C63800CB030801500A07D00821B80B7F803EFFFFE8030509AB7F23456789ABCDEFFFE6EC
+:20C65800C1FF29D000310B631D5B4DE010061D012BD239EC024C2008FC0A2F012EFFEF2384
+:20C67800F8FF0715710724E13344B0151515FF03FFEF650EF9C5A7FFE329FD9A60350100AC
+:20C6980008040120600175027D017D082F31FFEF5318AB6E377E21F3010034010120003157
+:20C6B8006201BF025001B00031FFEF2ED5F8FFEF05BFC046C00000F0FFE0F05300BC087065
+:20C6D8000031C40034CC003455D40034DC0034E40034EC0034833DC52CB74C112D8D037181
+:20C6F800FFE11C5702012000312400342C0034153400343C003444003419CF5FFFEF0D1EFE
+:20C718006EAF52A41600200031474140F9E3A3DF42F33B9F0E899F262BD4D7FFFD0307C258
+:20C7380001838703FF00C3060201A86001EF00D388F759B22B5EC8BE529032058387000180
+:20C75800B1059E01B004D388F35B72FFE108F700040180600248C402764F3282C29C77E992
+:20C7780089027B72C7FF001452285DFF00FFEF124EBAA6A1F732BB897F0BFFE614000A131D
+:20C798003F0F142014003200100A90FF0101007D005A6967FF426565416C6C6961FF6E63A9
+:20C7B800653039C0C1C2FFC3C4C5C6C7C8C9CADFCBCCCDCECF1FFF060502F964A910A70055
+:20C7D800C002008388990F12B010F3D4BFAC336341FE6DFE6C07FEFF648001E05E38CE955A
+:20C7F8007F0405000366F212D56742FD01003247280200EDA16AB1F70BB0009051F070056C
+:20C8180000335578003480003488003490003455980034A00034A80034B0003455B80034A2
+:20C83800C00034C80034D00034DDD8003401003031CF06202F03AC0900200E08FFF000CBD5
+:20C858000600000F902A0100BF05FFEF0221A27F0200114F01006D0070FEFFE9280001208B
+:20C87800EC0101792004B1043D400301200031B6FFEDFF7FFFE46CDC04C63CFA043003FF0D
+:20C89800E49D6F020069CB9702093F03BC06B00BBF0A1C02F606FF00F80508333417002074
+:20C8B800EA00313C003408FFEC0606016B20F002B0F402F4003A0BB06D06FFE2200112C082
+:20C8D8000C0B0CBF006C0FF1FFEF0202600041002000313800B0007200B400022004F001E9
+:20C8F80071814000340131003801B2013C023900010305700035FFE4FFF000570108000045
+:20C91800070100200C00F7F98000F0001FF201ADCA0100D5FFB0000005130200797DF51147
+:20C938003F14F200E0A1611567AF0016BC0214CF5B0507630000FFF0B50A0200319E02008B
+:20C958009D9F0200000000000200000010000000020000001000000002000000100000004B
+:20C9780002000000100000000200000010000000020000001000000002000000FE0D00005C
+:20C99800000100000F15FFF00200000010000000000F58AA0200FFF0000F8CBD0200FFF00E
+:20C9B800000F80160020FFF0F8C40200501A002056C802002001002012C90200501800209D
+:20C9D80060C90200301A002068C902003018002070C90200401A002078C90200401800209F
+:20C9F80080C902001018002088C902002018002090C902001006012098C90200D8000020F4
+:20CA1800A0C902000C010020A8C9020000010020B0C9020004010020B8C902000801002086
+:020000040005F5
+:207FA800000080011000C0FFFDFF58003AC1B9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF90
+:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
+:00000001FF
From 2295806569969291e2ea12b74e2772f687a5a1d3 Mon Sep 17 00:00:00 2001
From: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Date: Mon, 24 Oct 2022 13:55:28 +0200
Subject: [PATCH 052/319] Fix changelog
---
CHANGELOG.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2152515ca..4b351aa94 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,9 @@ All notable changes to this project will be documented in this file.
## [12.2.0.1]
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
-- Berry add `bytes().setbytes()`
+- Berry add `bytes().setbytes()` (#16892)
- Support for Shelly Pro 1/2 (#16773)
-- Add Zigbee router firmware for Sonoff ZBBridgePro
+- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
### Breaking Changed
From 115caf2bc9e5cf40b594bc8c04d6eb46c1a820e1 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 24 Oct 2022 15:03:19 +0200
Subject: [PATCH 053/319] actions/setup-python@v4
---
.github/workflows/build_all_the_things.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/build_all_the_things.yml b/.github/workflows/build_all_the_things.yml
index ae8e7e1eb..a5ec83b28 100644
--- a/.github/workflows/build_all_the_things.yml
+++ b/.github/workflows/build_all_the_things.yml
@@ -28,7 +28,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
@@ -54,7 +54,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
@@ -111,7 +111,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
@@ -137,7 +137,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
From 432bd6b0f3938fe2a74d15cffedbc0db50f7378d Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 24 Oct 2022 15:04:43 +0200
Subject: [PATCH 054/319] actions/setup-python@v4
---
.github/workflows/Tasmota_build_devel.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/Tasmota_build_devel.yml b/.github/workflows/Tasmota_build_devel.yml
index 2bbc4fc66..f2bee6281 100644
--- a/.github/workflows/Tasmota_build_devel.yml
+++ b/.github/workflows/Tasmota_build_devel.yml
@@ -59,7 +59,7 @@ jobs:
with:
ref: development
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
@@ -84,7 +84,7 @@ jobs:
with:
ref: development
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
From 4ec5c16ef81ddf39336cbf5c7cc1765b0faa8ea9 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 24 Oct 2022 15:06:05 +0200
Subject: [PATCH 055/319] actions/setup-python@v4
---
.github/workflows/Tasmota_build_master.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml
index f2f07a772..cbfeaaa28 100644
--- a/.github/workflows/Tasmota_build_master.yml
+++ b/.github/workflows/Tasmota_build_master.yml
@@ -58,7 +58,7 @@ jobs:
with:
ref: master
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
@@ -83,7 +83,7 @@ jobs:
with:
ref: master
- name: Set up Python
- uses: actions/setup-python@v3
+ uses: actions/setup-python@v4
- name: Install dependencies
run: |
pip install wheel
From 2bf7ea11548a820e737e75e8651541a0d2d52924 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 24 Oct 2022 23:05:23 +0200
Subject: [PATCH 056/319] Prepare for DMX Artnet support on ESP32
---
CHANGELOG.md | 1 +
.../berry_tasmota/src/be_tasmota_lib.c | 2 +
.../berry_tasmota/src/embedded/leds.be | 18 +-
.../src/embedded/leds_animator.be | 5 +-
.../src/solidify/solidified_leds.h | 608 ++++++++++--------
.../src/solidify/solidified_leds_animator.h | 213 +++---
.../xdrv_52_3_berry_tasmota.ino | 13 +
7 files changed, 491 insertions(+), 369 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b351aa94..3363b6293 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- Berry add `bytes().setbytes()` (#16892)
- Support for Shelly Pro 1/2 (#16773)
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
+- Prepare for DMX Artnet support on ESP32
### Breaking Changed
diff --git a/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c b/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c
index db4f8648c..dcef3a479 100644
--- a/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c
+++ b/lib/libesp32/berry_tasmota/src/be_tasmota_lib.c
@@ -29,6 +29,7 @@ extern int l_wifi(bvm *vm);
extern int l_eth(bvm *vm);
extern int l_yield(bvm *vm);
extern int l_delay(bvm *vm);
+extern int l_delay_microseconds(bvm *vm);
extern int l_scaleuint(bvm *vm);
extern int l_logInfo(bvm *vm);
extern int l_save(bvm *vm);
@@ -102,6 +103,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
eth, func(l_eth)
yield, func(l_yield)
delay, func(l_delay)
+ delay_microseconds, func(l_delay_microseconds)
scale_uint, func(l_scaleuint)
log, func(l_logInfo)
save, func(l_save)
diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be
index 8cacf441c..82b154186 100644
--- a/lib/libesp32/berry_tasmota/src/embedded/leds.be
+++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be
@@ -249,6 +249,8 @@ class Leds : Leds_ntv
var offset
var h, w
var alternate # are rows in alternate mode (even/odd are reversed)
+ var pix_buffer
+ var pix_size
def init(strip, w, h, offset)
self.strip = strip
@@ -256,6 +258,9 @@ class Leds : Leds_ntv
self.h = h
self.w = w
self.alternate = false
+
+ self.pix_buffer = self.strip.pixels_buffer()
+ self.pix_size = self.strip.pixel_size()
end
def clear()
@@ -270,6 +275,7 @@ class Leds : Leds_ntv
# don't trigger on segment, you will need to trigger on full strip instead
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
self.strip.show()
+ self.pix_buffer = self.strip.pixels_buffer() # update buffer after show()
end
end
def can_show()
@@ -282,10 +288,10 @@ class Leds : Leds_ntv
self.strip.dirty()
end
def pixels_buffer()
- return nil
+ return self.strip.pixels_buffer()
end
def pixel_size()
- return self.strip.pixel_size()
+ return self.pix_size
end
def pixel_count()
return self.w * self.h
@@ -304,6 +310,14 @@ class Leds : Leds_ntv
return self.strip.get_pixel_color(idx + self.offseta)
end
+ # setbytes(row, bytes)
+ # sets the raw bytes for `row`, copying at most 3 or 4 x col bytes
+ def set_bytes(row, buf, offset)
+ var h_bytes = self.h * self.pix_size
+ var offset_in_matrix = self.offset + row * h_bytes
+ self.pix_buffer.setbytes(offset_in_matrix, buf, offset, h_bytes)
+ end
+
# Leds_matrix specific
def set_alternate(alt)
self.alternate = alt
diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds_animator.be b/lib/libesp32/berry_tasmota/src/embedded/leds_animator.be
index 16573828b..a6f4fb337 100644
--- a/lib/libesp32/berry_tasmota/src/embedded/leds_animator.be
+++ b/lib/libesp32/berry_tasmota/src/embedded/leds_animator.be
@@ -17,7 +17,8 @@ class Leds_animator
#
self.clear() # clear all leds first
#
- tasmota.add_driver(self)
+ tasmota.add_fast_loop(/-> self.fast_loop())
+ # it may be useful to reduce Sleep time here
end
def add_anim(anim)
@@ -43,7 +44,7 @@ class Leds_animator
return self.bri
end
- def every_50ms()
+ def fast_loop()
if self.running
# run animators first
var i = 0
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
index b872474e4..589c59460 100644
--- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
@@ -736,66 +736,9 @@ be_local_closure(Leds_is_dirty, /* name */
/********************************************************************
-** Solidified function: pixel_count
+** Solidified function: pixels_buffer
********************************************************************/
-be_local_closure(Leds_matrix_pixel_count, /* name */
- be_nested_proto(
- 3, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 2]) { /* constants */
- /* K0 */ be_nested_str(w),
- /* K1 */ be_nested_str(h),
- }),
- &be_const_str_pixel_count,
- &be_const_str_solidified,
- ( &(const binstruction[ 4]) { /* code */
- 0x88040100, // 0000 GETMBR R1 R0 K0
- 0x88080101, // 0001 GETMBR R2 R0 K1
- 0x08040202, // 0002 MUL R1 R1 R2
- 0x80040200, // 0003 RET 1 R1
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: set_alternate
-********************************************************************/
-be_local_closure(Leds_matrix_set_alternate, /* name */
- be_nested_proto(
- 2, /* nstack */
- 2, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
- /* K0 */ be_nested_str(alternate),
- }),
- &be_const_str_set_alternate,
- &be_const_str_solidified,
- ( &(const binstruction[ 2]) { /* code */
- 0x90020001, // 0000 SETMBR R0 K0 R1
- 0x80000000, // 0001 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: pixel_size
-********************************************************************/
-be_local_closure(Leds_matrix_pixel_size, /* name */
+be_local_closure(Leds_matrix_pixels_buffer, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
@@ -807,9 +750,9 @@ be_local_closure(Leds_matrix_pixel_size, /* name */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(strip),
- /* K1 */ be_nested_str(pixel_size),
+ /* K1 */ be_nested_str(pixels_buffer),
}),
- &be_const_str_pixel_size,
+ &be_const_str_pixels_buffer,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
@@ -822,6 +765,54 @@ be_local_closure(Leds_matrix_pixel_size, /* name */
/*******************************************************************/
+/********************************************************************
+** Solidified function: init
+********************************************************************/
+be_local_closure(Leds_matrix_init, /* name */
+ be_nested_proto(
+ 7, /* nstack */
+ 5, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 9]) { /* constants */
+ /* K0 */ be_nested_str(strip),
+ /* K1 */ be_nested_str(offset),
+ /* K2 */ be_nested_str(h),
+ /* K3 */ be_nested_str(w),
+ /* K4 */ be_nested_str(alternate),
+ /* K5 */ be_nested_str(pix_buffer),
+ /* K6 */ be_nested_str(pixels_buffer),
+ /* K7 */ be_nested_str(pix_size),
+ /* K8 */ be_nested_str(pixel_size),
+ }),
+ &be_const_str_init,
+ &be_const_str_solidified,
+ ( &(const binstruction[15]) { /* code */
+ 0x90020001, // 0000 SETMBR R0 K0 R1
+ 0x90020204, // 0001 SETMBR R0 K1 R4
+ 0x90020403, // 0002 SETMBR R0 K2 R3
+ 0x90020602, // 0003 SETMBR R0 K3 R2
+ 0x50140000, // 0004 LDBOOL R5 0 0
+ 0x90020805, // 0005 SETMBR R0 K4 R5
+ 0x88140100, // 0006 GETMBR R5 R0 K0
+ 0x8C140B06, // 0007 GETMET R5 R5 K6
+ 0x7C140200, // 0008 CALL R5 1
+ 0x90020A05, // 0009 SETMBR R0 K5 R5
+ 0x88140100, // 000A GETMBR R5 R0 K0
+ 0x8C140B08, // 000B GETMET R5 R5 K8
+ 0x7C140200, // 000C CALL R5 1
+ 0x90020E05, // 000D SETMBR R0 K7 R5
+ 0x80000000, // 000E RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified function: set_pixel_color
********************************************************************/
@@ -857,6 +848,180 @@ be_local_closure(Leds_matrix_set_pixel_color, /* name */
/*******************************************************************/
+/********************************************************************
+** Solidified function: begin
+********************************************************************/
+be_local_closure(Leds_matrix_begin, /* name */
+ be_nested_proto(
+ 1, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 0, /* has constants */
+ NULL, /* no const */
+ &be_const_str_begin,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 1]) { /* code */
+ 0x80000000, // 0000 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: get_pixel_color
+********************************************************************/
+be_local_closure(Leds_matrix_get_pixel_color, /* name */
+ be_nested_proto(
+ 5, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 3]) { /* constants */
+ /* K0 */ be_nested_str(strip),
+ /* K1 */ be_nested_str(get_pixel_color),
+ /* K2 */ be_nested_str(offseta),
+ }),
+ &be_const_str_get_pixel_color,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 6]) { /* code */
+ 0x88080100, // 0000 GETMBR R2 R0 K0
+ 0x8C080501, // 0001 GETMET R2 R2 K1
+ 0x88100102, // 0002 GETMBR R4 R0 K2
+ 0x00100204, // 0003 ADD R4 R1 R4
+ 0x7C080400, // 0004 CALL R2 2
+ 0x80040400, // 0005 RET 1 R2
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: pixel_size
+********************************************************************/
+be_local_closure(Leds_matrix_pixel_size, /* name */
+ be_nested_proto(
+ 2, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(pix_size),
+ }),
+ &be_const_str_pixel_size,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 2]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x80040200, // 0001 RET 1 R1
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: set_alternate
+********************************************************************/
+be_local_closure(Leds_matrix_set_alternate, /* name */
+ be_nested_proto(
+ 2, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(alternate),
+ }),
+ &be_const_str_set_alternate,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 2]) { /* code */
+ 0x90020001, // 0000 SETMBR R0 K0 R1
+ 0x80000000, // 0001 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: can_show
+********************************************************************/
+be_local_closure(Leds_matrix_can_show, /* name */
+ be_nested_proto(
+ 3, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 2]) { /* constants */
+ /* K0 */ be_nested_str(strip),
+ /* K1 */ be_nested_str(can_show),
+ }),
+ &be_const_str_can_show,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x8C040301, // 0001 GETMET R1 R1 K1
+ 0x7C040200, // 0002 CALL R1 1
+ 0x80040200, // 0003 RET 1 R1
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: clear
+********************************************************************/
+be_local_closure(Leds_matrix_clear, /* name */
+ be_nested_proto(
+ 4, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 3]) { /* constants */
+ /* K0 */ be_nested_str(clear_to),
+ /* K1 */ be_const_int(0),
+ /* K2 */ be_nested_str(show),
+ }),
+ &be_const_str_clear,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 6]) { /* code */
+ 0x8C040100, // 0000 GETMET R1 R0 K0
+ 0x580C0001, // 0001 LDCONST R3 K1
+ 0x7C040400, // 0002 CALL R1 2
+ 0x8C040102, // 0003 GETMET R1 R0 K2
+ 0x7C040200, // 0004 CALL R1 1
+ 0x80000000, // 0005 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified function: set_matrix_pixel_color
********************************************************************/
@@ -918,6 +1083,36 @@ be_local_closure(Leds_matrix_set_matrix_pixel_color, /* name */
/*******************************************************************/
+/********************************************************************
+** Solidified function: pixel_count
+********************************************************************/
+be_local_closure(Leds_matrix_pixel_count, /* name */
+ be_nested_proto(
+ 3, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 2]) { /* constants */
+ /* K0 */ be_nested_str(w),
+ /* K1 */ be_nested_str(h),
+ }),
+ &be_const_str_pixel_count,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x88080101, // 0001 GETMBR R2 R0 K1
+ 0x08040202, // 0002 MUL R1 R1 R2
+ 0x80040200, // 0003 RET 1 R1
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified function: show
********************************************************************/
@@ -931,7 +1126,7 @@ be_local_closure(Leds_matrix_show, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 7]) { /* constants */
+ ( &(const bvalue[ 9]) { /* constants */
/* K0 */ be_nested_str(offset),
/* K1 */ be_const_int(0),
/* K2 */ be_nested_str(w),
@@ -939,58 +1134,34 @@ be_local_closure(Leds_matrix_show, /* name */
/* K4 */ be_nested_str(strip),
/* K5 */ be_nested_str(leds),
/* K6 */ be_nested_str(show),
+ /* K7 */ be_nested_str(pix_buffer),
+ /* K8 */ be_nested_str(pixels_buffer),
}),
&be_const_str_show,
&be_const_str_solidified,
- ( &(const binstruction[18]) { /* code */
+ ( &(const binstruction[22]) { /* code */
0x60080017, // 0000 GETGBL R2 G23
0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1
0x740A0009, // 0003 JMPT R2 #000E
0x88080100, // 0004 GETMBR R2 R0 K0
0x1C080501, // 0005 EQ R2 R2 K1
- 0x780A0009, // 0006 JMPF R2 #0011
+ 0x780A000D, // 0006 JMPF R2 #0015
0x88080102, // 0007 GETMBR R2 R0 K2
0x880C0103, // 0008 GETMBR R3 R0 K3
0x08080403, // 0009 MUL R2 R2 R3
0x880C0104, // 000A GETMBR R3 R0 K4
0x880C0705, // 000B GETMBR R3 R3 K5
0x1C080403, // 000C EQ R2 R2 R3
- 0x780A0002, // 000D JMPF R2 #0011
+ 0x780A0006, // 000D JMPF R2 #0015
0x88080104, // 000E GETMBR R2 R0 K4
0x8C080506, // 000F GETMET R2 R2 K6
0x7C080200, // 0010 CALL R2 1
- 0x80000000, // 0011 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: is_dirty
-********************************************************************/
-be_local_closure(Leds_matrix_is_dirty, /* name */
- be_nested_proto(
- 3, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 2]) { /* constants */
- /* K0 */ be_nested_str(strip),
- /* K1 */ be_nested_str(is_dirty),
- }),
- &be_const_str_is_dirty,
- &be_const_str_solidified,
- ( &(const binstruction[ 4]) { /* code */
- 0x88040100, // 0000 GETMBR R1 R0 K0
- 0x8C040301, // 0001 GETMET R1 R1 K1
- 0x7C040200, // 0002 CALL R1 1
- 0x80040200, // 0003 RET 1 R1
+ 0x88080104, // 0011 GETMBR R2 R0 K4
+ 0x8C080508, // 0012 GETMET R2 R2 K8
+ 0x7C080200, // 0013 CALL R2 1
+ 0x90020E02, // 0014 SETMBR R0 K7 R2
+ 0x80000000, // 0015 RET 0
})
)
);
@@ -1044,100 +1215,6 @@ be_local_closure(Leds_matrix_clear_to, /* name */
/*******************************************************************/
-/********************************************************************
-** Solidified function: clear
-********************************************************************/
-be_local_closure(Leds_matrix_clear, /* name */
- be_nested_proto(
- 4, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 3]) { /* constants */
- /* K0 */ be_nested_str(clear_to),
- /* K1 */ be_const_int(0),
- /* K2 */ be_nested_str(show),
- }),
- &be_const_str_clear,
- &be_const_str_solidified,
- ( &(const binstruction[ 6]) { /* code */
- 0x8C040100, // 0000 GETMET R1 R0 K0
- 0x580C0001, // 0001 LDCONST R3 K1
- 0x7C040400, // 0002 CALL R1 2
- 0x8C040102, // 0003 GETMET R1 R0 K2
- 0x7C040200, // 0004 CALL R1 1
- 0x80000000, // 0005 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: pixels_buffer
-********************************************************************/
-be_local_closure(Leds_matrix_pixels_buffer, /* name */
- be_nested_proto(
- 2, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 0, /* has constants */
- NULL, /* no const */
- &be_const_str_pixels_buffer,
- &be_const_str_solidified,
- ( &(const binstruction[ 2]) { /* code */
- 0x4C040000, // 0000 LDNIL R1
- 0x80040200, // 0001 RET 1 R1
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: init
-********************************************************************/
-be_local_closure(Leds_matrix_init, /* name */
- be_nested_proto(
- 6, /* nstack */
- 5, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 5]) { /* constants */
- /* K0 */ be_nested_str(strip),
- /* K1 */ be_nested_str(offset),
- /* K2 */ be_nested_str(h),
- /* K3 */ be_nested_str(w),
- /* K4 */ be_nested_str(alternate),
- }),
- &be_const_str_init,
- &be_const_str_solidified,
- ( &(const binstruction[ 7]) { /* code */
- 0x90020001, // 0000 SETMBR R0 K0 R1
- 0x90020204, // 0001 SETMBR R0 K1 R4
- 0x90020403, // 0002 SETMBR R0 K2 R3
- 0x90020602, // 0003 SETMBR R0 K3 R2
- 0x50140000, // 0004 LDBOOL R5 0 0
- 0x90020805, // 0005 SETMBR R0 K4 R5
- 0x80000000, // 0006 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
/********************************************************************
** Solidified function: dirty
********************************************************************/
@@ -1168,39 +1245,6 @@ be_local_closure(Leds_matrix_dirty, /* name */
/*******************************************************************/
-/********************************************************************
-** Solidified function: get_pixel_color
-********************************************************************/
-be_local_closure(Leds_matrix_get_pixel_color, /* name */
- be_nested_proto(
- 5, /* nstack */
- 2, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 3]) { /* constants */
- /* K0 */ be_nested_str(strip),
- /* K1 */ be_nested_str(get_pixel_color),
- /* K2 */ be_nested_str(offseta),
- }),
- &be_const_str_get_pixel_color,
- &be_const_str_solidified,
- ( &(const binstruction[ 6]) { /* code */
- 0x88080100, // 0000 GETMBR R2 R0 K0
- 0x8C080501, // 0001 GETMET R2 R2 K1
- 0x88100102, // 0002 GETMBR R4 R0 K2
- 0x00100204, // 0003 ADD R4 R1 R4
- 0x7C080400, // 0004 CALL R2 2
- 0x80040400, // 0005 RET 1 R2
- })
- )
-);
-/*******************************************************************/
-
-
/********************************************************************
** Solidified function: get_alternate
********************************************************************/
@@ -1229,33 +1273,9 @@ be_local_closure(Leds_matrix_get_alternate, /* name */
/********************************************************************
-** Solidified function: begin
+** Solidified function: is_dirty
********************************************************************/
-be_local_closure(Leds_matrix_begin, /* name */
- be_nested_proto(
- 1, /* nstack */
- 1, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 0, /* has constants */
- NULL, /* no const */
- &be_const_str_begin,
- &be_const_str_solidified,
- ( &(const binstruction[ 1]) { /* code */
- 0x80000000, // 0000 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: can_show
-********************************************************************/
-be_local_closure(Leds_matrix_can_show, /* name */
+be_local_closure(Leds_matrix_is_dirty, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
@@ -1267,9 +1287,9 @@ be_local_closure(Leds_matrix_can_show, /* name */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(strip),
- /* K1 */ be_nested_str(can_show),
+ /* K1 */ be_nested_str(is_dirty),
}),
- &be_const_str_can_show,
+ &be_const_str_is_dirty,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
@@ -1282,35 +1302,81 @@ be_local_closure(Leds_matrix_can_show, /* name */
/*******************************************************************/
+/********************************************************************
+** Solidified function: set_bytes
+********************************************************************/
+be_local_closure(Leds_matrix_set_bytes, /* name */
+ be_nested_proto(
+ 12, /* nstack */
+ 4, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 5]) { /* constants */
+ /* K0 */ be_nested_str(h),
+ /* K1 */ be_nested_str(pix_size),
+ /* K2 */ be_nested_str(offset),
+ /* K3 */ be_nested_str(pix_buffer),
+ /* K4 */ be_nested_str(setbytes),
+ }),
+ &be_const_str_set_bytes,
+ &be_const_str_solidified,
+ ( &(const binstruction[14]) { /* code */
+ 0x88100100, // 0000 GETMBR R4 R0 K0
+ 0x88140101, // 0001 GETMBR R5 R0 K1
+ 0x08100805, // 0002 MUL R4 R4 R5
+ 0x88140102, // 0003 GETMBR R5 R0 K2
+ 0x08180204, // 0004 MUL R6 R1 R4
+ 0x00140A06, // 0005 ADD R5 R5 R6
+ 0x88180103, // 0006 GETMBR R6 R0 K3
+ 0x8C180D04, // 0007 GETMET R6 R6 K4
+ 0x5C200A00, // 0008 MOVE R8 R5
+ 0x5C240400, // 0009 MOVE R9 R2
+ 0x5C280600, // 000A MOVE R10 R3
+ 0x5C2C0800, // 000B MOVE R11 R4
+ 0x7C180A00, // 000C CALL R6 5
+ 0x80000000, // 000D RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified class: Leds_matrix
********************************************************************/
be_local_class(Leds_matrix,
- 5,
+ 7,
NULL,
- be_nested_map(21,
+ be_nested_map(24,
( (struct bmapnode*) &(const bmapnode[]) {
- { be_const_key(pixel_count, -1), be_const_closure(Leds_matrix_pixel_count_closure) },
- { be_const_key(h, 6), be_const_var(2) },
- { be_const_key(set_alternate, 7), be_const_closure(Leds_matrix_set_alternate_closure) },
- { be_const_key(pixel_size, 16), be_const_closure(Leds_matrix_pixel_size_closure) },
- { be_const_key(set_pixel_color, 19), be_const_closure(Leds_matrix_set_pixel_color_closure) },
- { be_const_key(set_matrix_pixel_color, 10), be_const_closure(Leds_matrix_set_matrix_pixel_color_closure) },
- { be_const_key(show, -1), be_const_closure(Leds_matrix_show_closure) },
- { be_const_key(alternate, -1), be_const_var(4) },
- { be_const_key(strip, -1), be_const_var(0) },
- { be_const_key(clear_to, -1), be_const_closure(Leds_matrix_clear_to_closure) },
- { be_const_key(w, 15), be_const_var(3) },
- { be_const_key(pixels_buffer, -1), be_const_closure(Leds_matrix_pixels_buffer_closure) },
+ { be_const_key(set_bytes, -1), be_const_closure(Leds_matrix_set_bytes_closure) },
+ { be_const_key(pix_buffer, -1), be_const_var(5) },
+ { be_const_key(pix_size, 20), be_const_var(6) },
{ be_const_key(init, -1), be_const_closure(Leds_matrix_init_closure) },
- { be_const_key(dirty, -1), be_const_closure(Leds_matrix_dirty_closure) },
- { be_const_key(get_pixel_color, -1), be_const_closure(Leds_matrix_get_pixel_color_closure) },
- { be_const_key(get_alternate, 17), be_const_closure(Leds_matrix_get_alternate_closure) },
- { be_const_key(offset, 8), be_const_var(1) },
- { be_const_key(clear, -1), be_const_closure(Leds_matrix_clear_closure) },
+ { be_const_key(set_pixel_color, 16), be_const_closure(Leds_matrix_set_pixel_color_closure) },
+ { be_const_key(alternate, -1), be_const_var(4) },
{ be_const_key(begin, -1), be_const_closure(Leds_matrix_begin_closure) },
- { be_const_key(is_dirty, -1), be_const_closure(Leds_matrix_is_dirty_closure) },
+ { be_const_key(h, -1), be_const_var(2) },
+ { be_const_key(get_pixel_color, -1), be_const_closure(Leds_matrix_get_pixel_color_closure) },
+ { be_const_key(pixel_size, 21), be_const_closure(Leds_matrix_pixel_size_closure) },
+ { be_const_key(set_alternate, -1), be_const_closure(Leds_matrix_set_alternate_closure) },
{ be_const_key(can_show, -1), be_const_closure(Leds_matrix_can_show_closure) },
+ { be_const_key(get_alternate, 13), be_const_closure(Leds_matrix_get_alternate_closure) },
+ { be_const_key(w, -1), be_const_var(3) },
+ { be_const_key(set_matrix_pixel_color, 12), be_const_closure(Leds_matrix_set_matrix_pixel_color_closure) },
+ { be_const_key(pixel_count, -1), be_const_closure(Leds_matrix_pixel_count_closure) },
+ { be_const_key(show, -1), be_const_closure(Leds_matrix_show_closure) },
+ { be_const_key(offset, -1), be_const_var(1) },
+ { be_const_key(clear_to, 17), be_const_closure(Leds_matrix_clear_to_closure) },
+ { be_const_key(dirty, -1), be_const_closure(Leds_matrix_dirty_closure) },
+ { be_const_key(clear, 10), be_const_closure(Leds_matrix_clear_closure) },
+ { be_const_key(strip, -1), be_const_var(0) },
+ { be_const_key(is_dirty, -1), be_const_closure(Leds_matrix_is_dirty_closure) },
+ { be_const_key(pixels_buffer, 0), be_const_closure(Leds_matrix_pixels_buffer_closure) },
})),
(bstring*) &be_const_str_Leds_matrix
);
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds_animator.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds_animator.h
index 1952c41dd..4d6d70726 100644
--- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds_animator.h
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds_animator.h
@@ -14,8 +14,32 @@ be_local_closure(Leds_animator_init, /* name */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
+ 1, /* has sup protos */
+ ( &(const struct bproto*[ 1]) {
+ be_nested_proto(
+ 2, /* nstack */
+ 0, /* argc */
+ 0, /* varg */
+ 1, /* has upvals */
+ ( &(const bupvaldesc[ 1]) { /* upvals */
+ be_local_const_upval(1, 0),
+ }),
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str_weak(fast_loop),
+ }),
+ be_str_weak(_X3Clambda_X3E),
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x68000000, // 0000 GETUPV R0 U0
+ 0x8C000100, // 0001 GETMET R0 R0 K0
+ 0x7C000200, // 0002 CALL R0 1
+ 0x80040000, // 0003 RET 1 R0
+ })
+ ),
+ }),
1, /* has constants */
( &(const bvalue[ 8]) { /* constants */
/* K0 */ be_nested_str_weak(strip),
@@ -25,11 +49,11 @@ be_local_closure(Leds_animator_init, /* name */
/* K4 */ be_nested_str_weak(animators),
/* K5 */ be_nested_str_weak(clear),
/* K6 */ be_nested_str_weak(tasmota),
- /* K7 */ be_nested_str_weak(add_driver),
+ /* K7 */ be_nested_str_weak(add_fast_loop),
}),
be_str_weak(init),
&be_const_str_solidified,
- ( &(const binstruction[18]) { /* code */
+ ( &(const binstruction[19]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x540A0031, // 0001 LDINT R2 50
0x90020202, // 0002 SETMBR R0 K1 R2
@@ -45,9 +69,10 @@ be_local_closure(Leds_animator_init, /* name */
0x7C080200, // 000C CALL R2 1
0xB80A0C00, // 000D GETNGBL R2 K6
0x8C080507, // 000E GETMET R2 R2 K7
- 0x5C100000, // 000F MOVE R4 R0
+ 0x84100000, // 000F CLOSURE R4 P0
0x7C080400, // 0010 CALL R2 2
- 0x80000000, // 0011 RET 0
+ 0xA0000000, // 0011 CLOSE R0
+ 0x80000000, // 0012 RET 0
})
)
);
@@ -55,11 +80,11 @@ be_local_closure(Leds_animator_init, /* name */
/********************************************************************
-** Solidified function: set_bri
+** Solidified function: add_anim
********************************************************************/
-be_local_closure(Leds_animator_set_bri, /* name */
+be_local_closure(Leds_animator_add_anim, /* name */
be_nested_proto(
- 2, /* nstack */
+ 5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
@@ -67,14 +92,21 @@ be_local_closure(Leds_animator_set_bri, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
- /* K0 */ be_nested_str_weak(bri),
+ ( &(const bvalue[ 3]) { /* constants */
+ /* K0 */ be_nested_str_weak(animators),
+ /* K1 */ be_nested_str_weak(push),
+ /* K2 */ be_nested_str_weak(run),
}),
- be_str_weak(set_bri),
+ be_str_weak(add_anim),
&be_const_str_solidified,
- ( &(const binstruction[ 2]) { /* code */
- 0x90020001, // 0000 SETMBR R0 K0 R1
- 0x80000000, // 0001 RET 0
+ ( &(const binstruction[ 7]) { /* code */
+ 0x88080100, // 0000 GETMBR R2 R0 K0
+ 0x8C080501, // 0001 GETMET R2 R2 K1
+ 0x5C100200, // 0002 MOVE R4 R1
+ 0x7C080400, // 0003 CALL R2 2
+ 0x8C080302, // 0004 GETMET R2 R1 K2
+ 0x7C080200, // 0005 CALL R2 1
+ 0x80000000, // 0006 RET 0
})
)
);
@@ -109,6 +141,62 @@ be_local_closure(Leds_animator_stop, /* name */
/*******************************************************************/
+/********************************************************************
+** Solidified function: fast_loop
+********************************************************************/
+be_local_closure(Leds_animator_fast_loop, /* name */
+ be_nested_proto(
+ 6, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 7]) { /* constants */
+ /* K0 */ be_nested_str_weak(running),
+ /* K1 */ be_const_int(0),
+ /* K2 */ be_nested_str_weak(animators),
+ /* K3 */ be_nested_str_weak(is_running),
+ /* K4 */ be_nested_str_weak(animate),
+ /* K5 */ be_const_int(1),
+ /* K6 */ be_nested_str_weak(remove),
+ }),
+ be_str_weak(fast_loop),
+ &be_const_str_solidified,
+ ( &(const binstruction[25]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x78060015, // 0001 JMPF R1 #0018
+ 0x58040001, // 0002 LDCONST R1 K1
+ 0x6008000C, // 0003 GETGBL R2 G12
+ 0x880C0102, // 0004 GETMBR R3 R0 K2
+ 0x7C080200, // 0005 CALL R2 1
+ 0x14080202, // 0006 LT R2 R1 R2
+ 0x780A000D, // 0007 JMPF R2 #0016
+ 0x88080102, // 0008 GETMBR R2 R0 K2
+ 0x94080401, // 0009 GETIDX R2 R2 R1
+ 0x8C0C0503, // 000A GETMET R3 R2 K3
+ 0x7C0C0200, // 000B CALL R3 1
+ 0x780E0003, // 000C JMPF R3 #0011
+ 0x8C0C0504, // 000D GETMET R3 R2 K4
+ 0x7C0C0200, // 000E CALL R3 1
+ 0x00040305, // 000F ADD R1 R1 K5
+ 0x70020003, // 0010 JMP #0015
+ 0x880C0102, // 0011 GETMBR R3 R0 K2
+ 0x8C0C0706, // 0012 GETMET R3 R3 K6
+ 0x5C140200, // 0013 MOVE R5 R1
+ 0x7C0C0400, // 0014 CALL R3 2
+ 0x7001FFEC, // 0015 JMP #0003
+ 0x8C080104, // 0016 GETMET R2 R0 K4
+ 0x7C080200, // 0017 CALL R2 1
+ 0x80000000, // 0018 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified function: animate
********************************************************************/
@@ -165,55 +253,26 @@ be_local_closure(Leds_animator_remove, /* name */
/********************************************************************
-** Solidified function: every_50ms
+** Solidified function: set_bri
********************************************************************/
-be_local_closure(Leds_animator_every_50ms, /* name */
+be_local_closure(Leds_animator_set_bri, /* name */
be_nested_proto(
- 6, /* nstack */
- 1, /* argc */
+ 2, /* nstack */
+ 2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 7]) { /* constants */
- /* K0 */ be_nested_str_weak(running),
- /* K1 */ be_const_int(0),
- /* K2 */ be_nested_str_weak(animators),
- /* K3 */ be_nested_str_weak(is_running),
- /* K4 */ be_nested_str_weak(animate),
- /* K5 */ be_const_int(1),
- /* K6 */ be_nested_str_weak(remove),
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str_weak(bri),
}),
- be_str_weak(every_50ms),
+ be_str_weak(set_bri),
&be_const_str_solidified,
- ( &(const binstruction[25]) { /* code */
- 0x88040100, // 0000 GETMBR R1 R0 K0
- 0x78060015, // 0001 JMPF R1 #0018
- 0x58040001, // 0002 LDCONST R1 K1
- 0x6008000C, // 0003 GETGBL R2 G12
- 0x880C0102, // 0004 GETMBR R3 R0 K2
- 0x7C080200, // 0005 CALL R2 1
- 0x14080202, // 0006 LT R2 R1 R2
- 0x780A000D, // 0007 JMPF R2 #0016
- 0x88080102, // 0008 GETMBR R2 R0 K2
- 0x94080401, // 0009 GETIDX R2 R2 R1
- 0x8C0C0503, // 000A GETMET R3 R2 K3
- 0x7C0C0200, // 000B CALL R3 1
- 0x780E0003, // 000C JMPF R3 #0011
- 0x8C0C0504, // 000D GETMET R3 R2 K4
- 0x7C0C0200, // 000E CALL R3 1
- 0x00040305, // 000F ADD R1 R1 K5
- 0x70020003, // 0010 JMP #0015
- 0x880C0102, // 0011 GETMBR R3 R0 K2
- 0x8C0C0706, // 0012 GETMET R3 R3 K6
- 0x5C140200, // 0013 MOVE R5 R1
- 0x7C0C0400, // 0014 CALL R3 2
- 0x7001FFEC, // 0015 JMP #0003
- 0x8C080104, // 0016 GETMET R2 R0 K4
- 0x7C080200, // 0017 CALL R2 1
- 0x80000000, // 0018 RET 0
+ ( &(const binstruction[ 2]) { /* code */
+ 0x90020001, // 0000 SETMBR R0 K0 R1
+ 0x80000000, // 0001 RET 0
})
)
);
@@ -275,40 +334,6 @@ be_local_closure(Leds_animator_start, /* name */
/*******************************************************************/
-/********************************************************************
-** Solidified function: add_anim
-********************************************************************/
-be_local_closure(Leds_animator_add_anim, /* name */
- be_nested_proto(
- 5, /* nstack */
- 2, /* argc */
- 2, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 3]) { /* constants */
- /* K0 */ be_nested_str_weak(animators),
- /* K1 */ be_nested_str_weak(push),
- /* K2 */ be_nested_str_weak(run),
- }),
- be_str_weak(add_anim),
- &be_const_str_solidified,
- ( &(const binstruction[ 7]) { /* code */
- 0x88080100, // 0000 GETMBR R2 R0 K0
- 0x8C080501, // 0001 GETMET R2 R2 K1
- 0x5C100200, // 0002 MOVE R4 R1
- 0x7C080400, // 0003 CALL R2 2
- 0x8C080302, // 0004 GETMET R2 R1 K2
- 0x7C080200, // 0005 CALL R2 1
- 0x80000000, // 0006 RET 0
- })
- )
-);
-/*******************************************************************/
-
-
/********************************************************************
** Solidified function: clear
********************************************************************/
@@ -352,18 +377,18 @@ be_local_class(Leds_animator,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, 12), be_const_closure(Leds_animator_init_closure) },
{ be_const_key_weak(clear, -1), be_const_closure(Leds_animator_clear_closure) },
- { be_const_key_weak(stop, -1), be_const_closure(Leds_animator_stop_closure) },
- { be_const_key_weak(strip, 4), be_const_var(0) },
+ { be_const_key_weak(stop, 13), be_const_closure(Leds_animator_stop_closure) },
+ { be_const_key_weak(add_anim, 4), be_const_closure(Leds_animator_add_anim_closure) },
{ be_const_key_weak(pixel_count, 6), be_const_var(1) },
{ be_const_key_weak(animate, -1), be_const_closure(Leds_animator_animate_closure) },
- { be_const_key_weak(add_anim, 13), be_const_closure(Leds_animator_add_anim_closure) },
+ { be_const_key_weak(animators, 7), be_const_var(4) },
+ { be_const_key_weak(strip, -1), be_const_var(0) },
{ be_const_key_weak(bri, -1), be_const_var(2) },
- { be_const_key_weak(every_50ms, -1), be_const_closure(Leds_animator_every_50ms_closure) },
- { be_const_key_weak(remove, 7), be_const_closure(Leds_animator_remove_closure) },
+ { be_const_key_weak(remove, 8), be_const_closure(Leds_animator_remove_closure) },
{ be_const_key_weak(get_bri, -1), be_const_closure(Leds_animator_get_bri_closure) },
{ be_const_key_weak(start, -1), be_const_closure(Leds_animator_start_closure) },
{ be_const_key_weak(running, -1), be_const_var(3) },
- { be_const_key_weak(animators, -1), be_const_var(4) },
+ { be_const_key_weak(fast_loop, -1), be_const_closure(Leds_animator_fast_loop_closure) },
{ be_const_key_weak(set_bri, 1), be_const_closure(Leds_animator_set_bri_closure) },
})),
be_str_weak(Leds_animator)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino
index 31206442d..4406c6fca 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino
@@ -325,6 +325,19 @@ extern "C" {
be_raise(vm, kTypeError, nullptr);
}
+ // Berry: tasmota.delay_microseconds(timer:int) -> nil
+ //
+ int32_t l_delay_microseconds(struct bvm *vm);
+ int32_t l_delay_microseconds(struct bvm *vm) {
+ int32_t top = be_top(vm); // Get the number of arguments
+ if (top == 2 && be_isint(vm, 2)) { // only 1 argument of type string accepted
+ uint32_t timer = be_toint(vm, 2);
+ delayMicroseconds(timer);
+ be_return_nil(vm); // Return
+ }
+ be_raise(vm, kTypeError, nullptr);
+ }
+
// Berry: `yield() -> nil`
// ESP object
int32_t l_yield(bvm *vm);
From 81b363f2cbda2613ba7eec0452546b21ff3133f5 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 25 Oct 2022 11:41:21 +0200
Subject: [PATCH 057/319] add python version
---
.github/workflows/Tasmota_build_devel.yml | 4 ++++
.github/workflows/Tasmota_build_master.yml | 4 ++++
.github/workflows/build_all_the_things.yml | 8 ++++++++
3 files changed, 16 insertions(+)
diff --git a/.github/workflows/Tasmota_build_devel.yml b/.github/workflows/Tasmota_build_devel.yml
index f2bee6281..5e7d7145a 100644
--- a/.github/workflows/Tasmota_build_devel.yml
+++ b/.github/workflows/Tasmota_build_devel.yml
@@ -60,6 +60,8 @@ jobs:
ref: development
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@@ -85,6 +87,8 @@ jobs:
ref: development
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml
index cbfeaaa28..133e4502c 100644
--- a/.github/workflows/Tasmota_build_master.yml
+++ b/.github/workflows/Tasmota_build_master.yml
@@ -59,6 +59,8 @@ jobs:
ref: master
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@@ -84,6 +86,8 @@ jobs:
ref: master
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
diff --git a/.github/workflows/build_all_the_things.yml b/.github/workflows/build_all_the_things.yml
index a5ec83b28..f169b8d08 100644
--- a/.github/workflows/build_all_the_things.yml
+++ b/.github/workflows/build_all_the_things.yml
@@ -29,6 +29,8 @@ jobs:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@@ -55,6 +57,8 @@ jobs:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@@ -112,6 +116,8 @@ jobs:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@@ -138,6 +144,8 @@ jobs:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
From 549f13f7a88dfa9c16fed66acfddc58d89fa8c7c Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 25 Oct 2022 11:49:39 +0200
Subject: [PATCH 058/319] Fix Berry `gpio.INPUT` conflict
---
tasmota/berry/drivers/lv_touch_3_buttons.be | 6 +-
tasmota/berry/include/be_gpio_defines.h | 23 +-
tasmota/berry/internal/gpio.be | 257 --------------------
tools/lv_gpio/lv_gpio_enum.h | 20 +-
4 files changed, 42 insertions(+), 264 deletions(-)
delete mode 100644 tasmota/berry/internal/gpio.be
diff --git a/tasmota/berry/drivers/lv_touch_3_buttons.be b/tasmota/berry/drivers/lv_touch_3_buttons.be
index c33ed0aff..ef0711ea5 100644
--- a/tasmota/berry/drivers/lv_touch_3_buttons.be
+++ b/tasmota/berry/drivers/lv_touch_3_buttons.be
@@ -19,7 +19,7 @@ class lv_touch_3_buttons
static ACTIVE_LOW = true
# Arguments:
- # Physical GPIOs, generally through `gpio.pin(gpio.INPUT, 0), gpio.pin(gpio.INPUT, 1), gpio.pin(gpio.INPUT, 2)`
+ # Physical GPIOs, generally through `gpio.pin(gpio.GPIO_INPUT, 0), gpio.pin(gpio.GPIO_INPUT, 1), gpio.pin(gpio.GPIO_INPUT, 2)`
#
# Pre-condition:
# LVGL must be already started
@@ -85,9 +85,9 @@ class lv_touch_3_buttons
end
end
-return lv_touch_3_buttons(gpio.pin(gpio.INPUT, 0), gpio.pin(gpio.INPUT, 1), gpio.pin(gpio.INPUT, 2), true)
+return lv_touch_3_buttons(gpio.pin(gpio.GPIO_INPUT, 0), gpio.pin(gpio.GPIO_INPUT, 1), gpio.pin(gpio.GPIO_INPUT, 2), true)
#-
-lv_btn3 = lv_touch_3_buttons(gpio.pin(gpio.INPUT, 0), gpio.pin(gpio.INPUT, 1), gpio.pin(gpio.INPUT, 2), lv_touch_3_buttons.ACTIVE_LOW)
+lv_btn3 = lv_touch_3_buttons(gpio.pin(gpio.GPIO_INPUT, 0), gpio.pin(gpio.GPIO_INPUT, 1), gpio.pin(gpio.GPIO_INPUT, 2), lv_touch_3_buttons.ACTIVE_LOW)
tasmota.add_driver(lv_btn3)
-#
diff --git a/tasmota/berry/include/be_gpio_defines.h b/tasmota/berry/include/be_gpio_defines.h
index 7e97defe5..eee29d979 100644
--- a/tasmota/berry/include/be_gpio_defines.h
+++ b/tasmota/berry/include/be_gpio_defines.h
@@ -19,7 +19,9 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ADC_RANGE", (int32_t) GPIO_ADC_RANGE },
{ "ADC_TEMP", (int32_t) GPIO_ADC_TEMP },
{ "ADE7880_IRQ", (int32_t) GPIO_ADE7880_IRQ },
+ { "ADE7953_CS", (int32_t) GPIO_ADE7953_CS },
{ "ADE7953_IRQ", (int32_t) GPIO_ADE7953_IRQ },
+ { "ADE7953_RST", (int32_t) GPIO_ADE7953_RST },
{ "ARIRFRCV", (int32_t) GPIO_ARIRFRCV },
{ "ARIRFSEL", (int32_t) GPIO_ARIRFSEL },
{ "AS3935", (int32_t) GPIO_AS3935 },
@@ -35,6 +37,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "BL6523_TX", (int32_t) GPIO_BL6523_TX },
{ "BOILER_OT_RX", (int32_t) GPIO_BOILER_OT_RX },
{ "BOILER_OT_TX", (int32_t) GPIO_BOILER_OT_TX },
+ { "BP5758D_CLK", (int32_t) GPIO_BP5758D_CLK },
+ { "BP5758D_DAT", (int32_t) GPIO_BP5758D_DAT },
{ "BS814_CLK", (int32_t) GPIO_BS814_CLK },
{ "BS814_DAT", (int32_t) GPIO_BS814_DAT },
{ "BUZZER", (int32_t) GPIO_BUZZER },
@@ -75,6 +79,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "FALLING", FALLING },
{ "FLOWRATEMETER_SIGNAL", (int32_t) GPIO_FLOWRATEMETER_IN },
{ "FTC532", (int32_t) GPIO_FTC532 },
+ { "GPIO_INPUT", (int32_t) GPIO_INPUT },
{ "GPS_RX", (int32_t) GPIO_GPS_RX },
{ "GPS_TX", (int32_t) GPIO_GPS_TX },
{ "HALLEFFECT", (int32_t) GPIO_HALLEFFECT },
@@ -99,6 +104,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "I2S_IN_CLK", (int32_t) GPIO_I2S_BCLK_IN },
{ "I2S_IN_DATA", (int32_t) GPIO_I2S_DIN },
{ "I2S_IN_SLCT", (int32_t) GPIO_I2S_WS_IN },
+ { "I2S_MCLK", (int32_t) GPIO_I2S_MCLK },
{ "I2S_OUT_CLK", (int32_t) GPIO_I2S_BCLK },
{ "I2S_OUT_DATA", (int32_t) GPIO_I2S_DOUT },
{ "I2S_OUT_SLCT", (int32_t) GPIO_I2S_WS },
@@ -109,7 +115,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ILI9341_CS", (int32_t) GPIO_ILI9341_CS },
{ "ILI9341_DC", (int32_t) GPIO_ILI9341_DC },
{ "ILI9488_CS", (int32_t) GPIO_ILI9488_CS },
- { "INPUT", (int32_t) GPIO_INPUT },
+ { "INPUT", INPUT },
{ "INPUT_PULLDOWN", INPUT_PULLDOWN },
{ "INPUT_PULLUP", INPUT_PULLUP },
{ "INTERRUPT", (int32_t) GPIO_INTERRUPT },
@@ -137,6 +143,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "MAX7219CS", (int32_t) GPIO_MAX7219CS },
{ "MAX7219DIN", (int32_t) GPIO_MAX7219DIN },
{ "MAX_RMT", MAX_RMT },
+ { "MBR_RX", (int32_t) GPIO_MBR_RX },
+ { "MBR_TX", (int32_t) GPIO_MBR_TX },
{ "MCP2515_CS", (int32_t) GPIO_MCP2515_CS },
{ "MCP39F5_RST", (int32_t) GPIO_MCP39F5_RST },
{ "MCP39F5_RX", (int32_t) GPIO_MCP39F5_RX },
@@ -148,6 +156,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "MIEL_HVAC_RX", (int32_t) GPIO_MIEL_HVAC_RX },
{ "MIEL_HVAC_TX", (int32_t) GPIO_MIEL_HVAC_TX },
{ "MP3_DFR562", (int32_t) GPIO_MP3_DFR562 },
+ { "MP3_DFR562_BUSY", (int32_t) GPIO_MP3_DFR562_BUSY },
{ "MS01", (int32_t) GPIO_MS01 },
{ "NEOPOOL_RX", (int32_t) GPIO_NEOPOOL_RX },
{ "NEOPOOL_TX", (int32_t) GPIO_NEOPOOL_TX },
@@ -155,6 +164,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "NRF24_CS", (int32_t) GPIO_NRF24_CS },
{ "NRF24_DC", (int32_t) GPIO_NRF24_DC },
{ "NRG_CF1", (int32_t) GPIO_NRG_CF1 },
+ { "NRG_MBS_RX", (int32_t) GPIO_NRG_MBS_RX },
+ { "NRG_MBS_TX", (int32_t) GPIO_NRG_MBS_TX },
{ "NRG_SEL", (int32_t) GPIO_NRG_SEL },
{ "NRG_SEL_INV", (int32_t) GPIO_NRG_SEL_INV },
{ "OLED_RESET", (int32_t) GPIO_OLED_RESET },
@@ -186,6 +197,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "RC522_RST", (int32_t) GPIO_RC522_RST },
{ "RDM6300_RX", (int32_t) GPIO_RDM6300_RX },
{ "REL1", (int32_t) GPIO_REL1 },
+ { "REL1_BI", (int32_t) GPIO_REL1_BI },
+ { "REL1_BI_INV", (int32_t) GPIO_REL1_BI_INV },
{ "REL1_INV", (int32_t) GPIO_REL1_INV },
{ "RESET", (int32_t) GPIO_RESET },
{ "RFRECV", (int32_t) GPIO_RFRECV },
@@ -231,6 +244,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "SM16716_SEL", (int32_t) GPIO_SM16716_SEL },
{ "SM2135_CLK", (int32_t) GPIO_SM2135_CLK },
{ "SM2135_DAT", (int32_t) GPIO_SM2135_DAT },
+ { "SM2335_CLK", (int32_t) GPIO_SM2335_CLK },
+ { "SM2335_DAT", (int32_t) GPIO_SM2335_DAT },
{ "SOLAXX1_RTS", (int32_t) GPIO_SOLAXX1_RTS },
{ "SOLAXX1_RX", (int32_t) GPIO_SOLAXX1_RX },
{ "SOLAXX1_TX", (int32_t) GPIO_SOLAXX1_TX },
@@ -266,6 +281,10 @@ const be_const_member_t lv_gpio_constants[] = {
{ "TELEINFO_RX", (int32_t) GPIO_TELEINFO_RX },
{ "TFMINIPLUS_RX", (int32_t) GPIO_TFMINIPLUS_RX },
{ "TFMINIPLUS_TX", (int32_t) GPIO_TFMINIPLUS_TX },
+ { "TM1621_CS", (int32_t) GPIO_TM1621_CS },
+ { "TM1621_DAT", (int32_t) GPIO_TM1621_DAT },
+ { "TM1621_RD", (int32_t) GPIO_TM1621_RD },
+ { "TM1621_WR", (int32_t) GPIO_TM1621_WR },
{ "TM1637CLK", (int32_t) GPIO_TM1637CLK },
{ "TM1637DIO", (int32_t) GPIO_TM1637DIO },
{ "TM1638CLK", (int32_t) GPIO_TM1638CLK },
@@ -300,8 +319,6 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ZIGBEE_RST", (int32_t) GPIO_ZIGBEE_RST },
{ "ZIGBEE_RX", (int32_t) GPIO_ZIGBEE_RX },
{ "ZIGBEE_TX", (int32_t) GPIO_ZIGBEE_TX },
- { "MBR_RX", (int32_t) GPIO_MBR_RX },
- { "MBR_TX", (int32_t) GPIO_MBR_TX },
};
diff --git a/tasmota/berry/internal/gpio.be b/tasmota/berry/internal/gpio.be
deleted file mode 100644
index 5d9437d62..000000000
--- a/tasmota/berry/internal/gpio.be
+++ /dev/null
@@ -1,257 +0,0 @@
-gpio = module('gpio')
-#- HIGH/LOW -#
-gpio.LOW = 0
-gpio.HIGH = 1
-#- GPIO states -#
-gpio.INPUT = 1
-gpio.OUTPUT = 2
-gpio.PULLUP = 4
-gpio.INPUT_PULLUP = 5
-gpio.PULLDOWN = 8
-gpio.OPEN_DRAIN = 16
-gpio.OUTPUT_OPEN_DRAIN = 18
-#- Interrupt trigger -#
-gpio.RISING = 1
-gpio.FALLING = 2
-gpio.CHANGE = 4
-#- Tasmota GPIOs -#
-gpio.NONE = 0
-gpio.KEY1 = 1
-gpio.KEY1_NP = 2
-gpio.KEY1_INV = 3
-gpio.KEY1_INV_NP = 4
-gpio.SWT1 = 5
-gpio.SWT1_NP = 6
-gpio.REL1 = 7
-gpio.REL1_INV = 8
-gpio.LED1 = 9
-gpio.LED1_INV = 10
-gpio.CNTR1 = 11
-gpio.CNTR1_NP = 12
-gpio.PWM1 = 13
-gpio.PWM1_INV = 14
-gpio.BUZZER = 15
-gpio.BUZZER_INV = 16
-gpio.LEDLNK = 17
-gpio.LEDLNK_INV = 18
-gpio.I2C_SCL = 19
-gpio.I2C_SDA = 20
-gpio.SPI_MISO = 21
-gpio.SPI_MOSI = 22
-gpio.SPI_CLK = 23
-gpio.SPI_CS = 24
-gpio.SPI_DC = 25
-gpio.SSPI_MISO = 26
-gpio.SSPI_MOSI = 27
-gpio.SSPI_SCLK = 28
-gpio.SSPI_CS = 29
-gpio.SSPI_DC = 30
-gpio.BACKLIGHT = 31
-gpio.OLED_RESET = 32
-gpio.IRSEND = 33
-gpio.IRRECV = 34
-gpio.RFSEND = 35
-gpio.RFRECV = 36
-gpio.DHT11 = 37
-gpio.DHT22 = 38
-gpio.SI7021 = 39
-gpio.DHT11_OUT = 40
-gpio.DSB = 41
-gpio.DSB_OUT = 42
-gpio.WS2812 = 43
-gpio.MHZ_TXD = 44
-gpio.MHZ_RXD = 45
-gpio.PZEM0XX_TX = 46
-gpio.PZEM004_RX = 47
-gpio.PZEM016_RX = 48
-gpio.PZEM017_RX = 49
-gpio.SAIR_TX = 50
-gpio.SAIR_RX = 51
-gpio.PMS5003_TX = 52
-gpio.PMS5003_RX = 53
-gpio.SDS0X1_TX = 54
-gpio.SDS0X1_RX = 55
-gpio.SBR_TX = 56
-gpio.SBR_RX = 57
-gpio.SR04_TRIG = 58
-gpio.SR04_ECHO = 59
-gpio.SDM120_TX = 60
-gpio.SDM120_RX = 61
-gpio.SDM630_TX = 62
-gpio.SDM630_RX = 63
-gpio.TM1638CLK = 64
-gpio.TM1638DIO = 65
-gpio.TM1638STB = 66
-gpio.MP3_DFR562 = 67
-gpio.HX711_SCK = 68
-gpio.HX711_DAT = 69
-gpio.TX2X_TXD_BLACK = 70
-gpio.TUYA_TX = 71
-gpio.TUYA_RX = 72
-gpio.MGC3130_XFER = 73
-gpio.MGC3130_RESET = 74
-gpio.RF_SENSOR = 75
-gpio.AZ_TXD = 76
-gpio.AZ_RXD = 77
-gpio.MAX31855CS = 78
-gpio.MAX31855CLK = 79
-gpio.MAX31855DO = 80
-gpio.NRG_SEL = 81
-gpio.NRG_SEL_INV = 82
-gpio.NRG_CF1 = 83
-gpio.HLW_CF = 84
-gpio.HJL_CF = 85
-gpio.MCP39F5_TX = 86
-gpio.MCP39F5_RX = 87
-gpio.MCP39F5_RST = 88
-gpio.PN532_TXD = 89
-gpio.PN532_RXD = 90
-gpio.SM16716_CLK = 91
-gpio.SM16716_DAT = 92
-gpio.SM16716_SEL = 93
-gpio.DI = 94
-gpio.DCKI = 95
-gpio.CSE7766_TX = 96
-gpio.CSE7766_RX = 97
-gpio.ARIRFRCV = 98
-gpio.ARIRFSEL = 99
-gpio.TXD = 100
-gpio.RXD = 101
-gpio.ROT1A = 102
-gpio.ROT1B = 103
-gpio.ADC_JOY = 104
-gpio.SSPI_MAX31865_CS1 = 105
-gpio.HRE_CLOCK = 106
-gpio.HRE_DATA = 107
-gpio.ADE7953_IRQ = 108
-gpio.SOLAXX1_TX = 109
-gpio.SOLAXX1_RX = 110
-gpio.ZIGBEE_TX = 111
-gpio.ZIGBEE_RX = 112
-gpio.RDM6300_RX = 113
-gpio.IBEACON_TX = 114
-gpio.IBEACON_RX = 115
-gpio.A4988_DIR = 116
-gpio.A4988_STP = 117
-gpio.A4988_ENA = 118
-gpio.A4988_MS1 = 119
-gpio.OUTPUT_HI = 120
-gpio.OUTPUT_LO = 121
-gpio.DDS2382_TX = 122
-gpio.DDS2382_RX = 123
-gpio.DDSU666_TX = 124
-gpio.DDSU666_RX = 125
-gpio.SM2135_CLK = 126
-gpio.SM2135_DAT = 127
-gpio.DEEPSLEEP = 128
-gpio.EXS_ENABLE = 129
-gpio.TASMOTACLIENT_TXD = 130
-gpio.TASMOTACLIENT_RXD = 131
-gpio.TASMOTACLIENT_RST = 132
-gpio.TASMOTACLIENT_RST_INV = 133
-gpio.HPMA_RX = 134
-gpio.HPMA_TX = 135
-gpio.GPS_RX = 136
-gpio.GPS_TX = 137
-gpio.HM10_RX = 138
-gpio.HM10_TX = 139
-gpio.LE01MR_RX = 140
-gpio.LE01MR_TX = 141
-gpio.CC1101_GDO0 = 142
-gpio.CC1101_GDO2 = 143
-gpio.HRXL_RX = 144
-gpio.ELECTRIQ_MOODL_TX = 145
-gpio.AS3935 = 146
-gpio.ADC_INPUT = 147
-gpio.ADC_TEMP = 148
-gpio.ADC_LIGHT = 149
-gpio.ADC_BUTTON = 150
-gpio.ADC_BUTTON_INV = 151
-gpio.ADC_RANGE = 152
-gpio.ADC_CT_POWER = 153
-gpio.WEBCAM_PWDN = 154
-gpio.WEBCAM_RESET = 155
-gpio.WEBCAM_XCLK = 156
-gpio.WEBCAM_SIOD = 157
-gpio.WEBCAM_SIOC = 158
-gpio.WEBCAM_DATA = 159
-gpio.WEBCAM_VSYNC = 160
-gpio.WEBCAM_HREF = 161
-gpio.WEBCAM_PCLK = 162
-gpio.WEBCAM_PSCLK = 163
-gpio.WEBCAM_HSD = 164
-gpio.WEBCAM_PSRCS = 165
-gpio.BOILER_OT_RX = 166
-gpio.BOILER_OT_TX = 167
-gpio.WINDMETER_SPEED = 168
-gpio.KEY1_TC = 169
-gpio.BL0940_RX = 170
-gpio.TCP_TX = 171
-gpio.TCP_RX = 172
-gpio.ETH_PHY_POWER = 173
-gpio.ETH_PHY_MDC = 174
-gpio.ETH_PHY_MDIO = 175
-gpio.TELEINFO_RX = 176
-gpio.TELEINFO_ENABLE = 177
-gpio.LMT01 = 178
-gpio.IEM3000_TX = 179
-gpio.IEM3000_RX = 180
-gpio.ZIGBEE_RST = 181
-gpio.DYP_RX = 182
-gpio.MIEL_HVAC_TX = 183
-gpio.MIEL_HVAC_RX = 184
-gpio.WE517_TX = 185
-gpio.WE517_RX = 186
-gpio.AS608_TX = 187
-gpio.AS608_RX = 188
-gpio.SHELLY_DIMMER_BOOT0 = 189
-gpio.SHELLY_DIMMER_RST_INV = 190
-gpio.RC522_RST = 191
-gpio.P9813_CLK = 192
-gpio.P9813_DAT = 193
-gpio.OPTION_A = 194
-gpio.FTC532 = 195
-gpio.RC522_CS = 196
-gpio.NRF24_CS = 197
-gpio.NRF24_DC = 198
-gpio.ILI9341_CS = 199
-gpio.ILI9341_DC = 200
-gpio.ILI9488_CS = 201
-gpio.EPAPER29_CS = 202
-gpio.EPAPER42_CS = 203
-gpio.SSD1351_CS = 204
-gpio.RA8876_CS = 205
-gpio.ST7789_CS = 206
-gpio.ST7789_DC = 207
-gpio.SSD1331_CS = 208
-gpio.SSD1331_DC = 209
-gpio.SDCARD_CS = 210
-gpio.ROT1A_NP = 211
-gpio.ROT1B_NP = 212
-gpio.ADC_PH = 213
-gpio.BS814_CLK = 214
-gpio.BS814_DAT = 215
-gpio.WIEGAND_D0 = 216
-gpio.WIEGAND_D1 = 217
-gpio.NEOPOOL_TX = 218
-gpio.NEOPOOL_RX = 219
-gpio.SDM72_TX = 220
-gpio.SDM72_RX = 221
-gpio.TM1637CLK = 222
-gpio.TM1637DIO = 223
-gpio.PROJECTOR_CTRL_TX = 224
-gpio.PROJECTOR_CTRL_RX = 225
-gpio.SSD1351_DC = 226
-gpio.XPT2046_CS = 227
-gpio.CSE7761_TX = 228
-gpio.CSE7761_RX = 229
-gpio.VL53LXX_XSHUT1 = 230
-gpio.MAX7219CLK = 231
-gpio.MAX7219DIN = 232
-gpio.MAX7219CS = 233
-gpio.TFMINIPLUS_TX = 234
-gpio.TFMINIPLUS_RX = 235
-gpio.ZEROCROSS = 236
-gpio.HALLEFFECT = 237
-gpio.SENSOR_END = 238
-gpio.ADC_MQ = 239
diff --git a/tools/lv_gpio/lv_gpio_enum.h b/tools/lv_gpio/lv_gpio_enum.h
index 11535f97a..933d83f02 100644
--- a/tools/lv_gpio/lv_gpio_enum.h
+++ b/tools/lv_gpio/lv_gpio_enum.h
@@ -261,7 +261,7 @@ TFMINIPLUS_RX = GPIO_TFMINIPLUS_RX
ZEROCROSS = GPIO_ZEROCROSS
HALLEFFECT = GPIO_HALLEFFECT
EPD_DATA = GPIO_EPD_DATA
-INPUT = GPIO_INPUT
+GPIO_INPUT = GPIO_INPUT // avoid conflict with INPUT
KEY1_PD = GPIO_KEY1_PD
KEY1_INV_PD = GPIO_KEY1_INV_PD
SWT1_PD = GPIO_SWT1_PD
@@ -307,5 +307,23 @@ SDIO_D2 = GPIO_SDIO_D2
SDIO_D3 = GPIO_SDIO_D3
FLOWRATEMETER_SIGNAL = GPIO_FLOWRATEMETER_IN
+BP5758D_CLK = GPIO_BP5758D_CLK
+BP5758D_DAT = GPIO_BP5758D_DAT
+SM2335_CLK = GPIO_SM2335_CLK
+SM2335_DAT = GPIO_SM2335_DAT
+MP3_DFR562_BUSY = GPIO_MP3_DFR562_BUSY
+TM1621_CS = GPIO_TM1621_CS
+TM1621_WR = GPIO_TM1621_WR
+TM1621_RD = GPIO_TM1621_RD
+TM1621_DAT = GPIO_TM1621_DAT
+REL1_BI = GPIO_REL1_BI
+REL1_BI_INV = GPIO_REL1_BI_INV
+I2S_MCLK = GPIO_I2S_MCLK
+MBR_TX = GPIO_MBR_TX
+MBR_RX = GPIO_MBR_RX
+ADE7953_RST = GPIO_ADE7953_RST
+NRG_MBS_TX = GPIO_NRG_MBS_TX
+NRG_MBS_RX = GPIO_NRG_MBS_RX
+ADE7953_CS = GPIO_ADE7953_CS
SENSOR_END = GPIO_SENSOR_END
From e4b9ef601475c5e45fa31c509477bd8dfd9059fa Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 25 Oct 2022 12:00:37 +0200
Subject: [PATCH 059/319] macOS-12
---
.github/workflows/build_all_the_things.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build_all_the_things.yml b/.github/workflows/build_all_the_things.yml
index f169b8d08..15b07ba1b 100644
--- a/.github/workflows/build_all_the_things.yml
+++ b/.github/workflows/build_all_the_things.yml
@@ -46,7 +46,7 @@ jobs:
path: ./build_output
os-check-mac:
- runs-on: macos-latest
+ runs-on: macOS-12
if: github.repository == 'arendst/Tasmota'
strategy:
fail-fast: true
From 89d4e87195d595d668ee303c716b5430f02c1053 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Tue, 25 Oct 2022 13:11:40 +0200
Subject: [PATCH 060/319] Update to stale@v6.0.1
---
.github/workflows/stale-actions.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/stale-actions.yml b/.github/workflows/stale-actions.yml
index 75decdd3c..b99f6f555 100644
--- a/.github/workflows/stale-actions.yml
+++ b/.github/workflows/stale-actions.yml
@@ -8,7 +8,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- - uses: actions/stale@v3.0.15
+ - uses: actions/stale@v6.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 25
From e7600ac83a0f05643dfa1df3343d7dd17af1812e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 20:16:23 +0300
Subject: [PATCH 061/319] Add support NTAG21x and NTAG20x cards. NTAG21x
support password authentication
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 270 ++++++++++++++++--
1 file changed, 247 insertions(+), 23 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 03eba20c7..62615c9bc 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -16,6 +16,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
+ #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
+// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
#ifdef USE_PN532_HSU
/*********************************************************************************************\
@@ -47,24 +50,48 @@ TasmotaSerial *PN532_Serial;
#define PN532_COMMAND_SAMCONFIGURATION 0x14
#define PN532_COMMAND_RFCONFIGURATION 0x32
#define PN532_COMMAND_INDATAEXCHANGE 0x40
+#define PN532_COMMAND_INCOMMUNICATETHRU 0x42
#define PN532_COMMAND_INLISTPASSIVETARGET 0x4A
-
+#define PN532_COMMAND_INRELEASE 0x52
+#define PN532_COMMAND_INSELECT 0x54
#define PN532_MIFARE_ISO14443A 0x00
#define MIFARE_CMD_READ 0x30
#define MIFARE_CMD_AUTH_A 0x60
#define MIFARE_CMD_AUTH_B 0x61
#define MIFARE_CMD_WRITE 0xA0
+#define NTAG21X_CMD_GET_VERSION 0x60
+#define NTAG21X_CMD_READ 0x30
+#define NTAG21X_CMD_FAST_READ 0x3A
+#define NTAG21X_CMD_PWD_AUTH 0x1B
+
+const struct {
+ uint8_t version[6];
+ uint8_t confPage;
+} NTAG[] PROGMEM ={
+ {.version={0x04, 0x02, 0x01, 0x00, 0x0f, 0x03},.confPage=0x29}, /* NTAG213 */
+ {.version={0x04, 0x02, 0x01, 0x00, 0x11, 0x03},.confPage=0x83}, /* NTAG215 */
+ {.version={0x04, 0x02, 0x01, 0x00, 0x13, 0x03},.confPage=0xe3}, /* NTAG216 */
+ {.version={0x04, 0x05, 0x02, 0x02, 0x13, 0x03},.confPage=0xe3}, /* NT3H2111 */
+ {.version={0x04, 0x05, 0x02, 0x02, 0x15, 0x03},.confPage=0xe3}, /* NT3H2211 */
+};
+#define NTAG_CNT (sizeof(NTAG)/7) // num records in NTAG array
+
struct PN532 {
char uids[21]; // Number of bytes in the UID. 4, 7 or 10
uint8_t packetbuffer[64]; // Global buffer used to store packet
uint8_t command = 0; // Carry command code between functions
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
bool present = false; // Maintain detection flag
+ uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[16];
+ uint8_t newdata[33];
uint8_t function = 0;
- uint8_t newdata_len = 0;
+// uint8_t newdata_len = 0;
+ uint32_t pwd_auth=0x64636261;
+ uint16_t pwd_pack=0x6665;
+ uint32_t pwd_auth_new;
+ uint16_t pwd_pack_new;
#endif // USE_PN532_DATA_FUNCTION
} Pn532;
@@ -273,9 +300,9 @@ bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidL
return 0;
}
- uint16_t sens_res = Pn532.packetbuffer[2];
- sens_res <<= 8;
- sens_res |= Pn532.packetbuffer[3];
+ Pn532.atqa = Pn532.packetbuffer[2];
+ Pn532.atqa <<= 8;
+ Pn532.atqa |= Pn532.packetbuffer[3];
/* Card appears to be Mifare Classic */
*uidLength = Pn532.packetbuffer[5];
@@ -310,6 +337,25 @@ bool PN532_SAMConfig(void) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
+void PN532_inRelease(void) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
+ Pn532.packetbuffer[1] = 1;
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return;
+ }
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+}
+
+void PN532_inSelect(void) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
+ Pn532.packetbuffer[1] = 1;
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return ;
+ }
+ int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: Select %d %x"), res, Pn532.packetbuffer[0]);
+}
+
#ifdef USE_PN532_DATA_FUNCTION
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
@@ -393,19 +439,151 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
+uint8_t ntag21x_probe (void) {
+ uint8_t result=0;
+
+ Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
+ Pn532.packetbuffer[1] = NTAG21X_CMD_GET_VERSION;
+
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return result;
+ }
+
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))<9){
+ return result;
+ }
+
+/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: NTAG Version %02x %02x %02x %02x %02x %02x %02x %02x %02x"),
+ Pn532.packetbuffer[0],Pn532.packetbuffer[1],Pn532.packetbuffer[2],Pn532.packetbuffer[3],
+ Pn532.packetbuffer[4],Pn532.packetbuffer[5],Pn532.packetbuffer[6],Pn532.packetbuffer[7],
+ Pn532.packetbuffer[8]);
+ */
+ if (Pn532.packetbuffer[3] != 4) { // not NTAG type
+ return result;
+ }
+
+ for (uint8_t i=0; i0) {
+ /* NTAG EV1 found*/
+ str_pwd=PWD_NONE;
+ if (!ntag21x_read32(card_datas, sizeof(card_datas))) {
+ if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
+ if (memcmp(uid, nuid, sizeof(uid))==0) {
+ if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
+ if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ }
+ }
+ }
+
+ } else {
+ if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
+ if (memcmp(uid, nuid, sizeof(uid))==0) {
+ if (!ntag20x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ }
+ }
+ }
+ } else
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
@@ -415,7 +593,7 @@ void PN532_ScanForTag(void) {
memcpy(&card_datas,&card_data,sizeof(card_data));
#else
for (uint32_t i = 0;i < sizeof(card_data);i++) {
- if ((isalpha(card_data[i])) || ((isdigit(card_data[i])))) {
+ if (isprint(card_data[i])) {
card_datas[i] = char(card_data[i]);
} else {
card_datas[i] = '\0';
@@ -424,11 +602,12 @@ void PN532_ScanForTag(void) {
#endif // USE_PN532_DATA_RAW
}
if (Pn532.function == 1) { // erase block 1 of card
+//TODO : Test
for (uint32_t i = 0;i<16;i++) {
card_data[i] = 0x00;
}
if (mifareclassic_WriteDataBlock(1, card_data)) {
- erase_success = true;
+ success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
@@ -437,14 +616,14 @@ void PN532_ScanForTag(void) {
#ifdef USE_PN532_DATA_RAW
memcpy(&card_data,&Pn532.newdata,sizeof(card_data));
if (mifareclassic_WriteDataBlock(1, card_data)) {
- set_success = true;
+ success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
#else
bool IsAlphaNumeric = true;
for (uint32_t i = 0;i < Pn532.newdata_len;i++) {
- if ((!isalpha(Pn532.newdata[i])) && (!isdigit(Pn532.newdata[i]))) {
+ if (!isprint(Pn532.newdata[i])) {
IsAlphaNumeric = false;
}
}
@@ -452,7 +631,7 @@ void PN532_ScanForTag(void) {
memcpy(&card_data,&Pn532.newdata,Pn532.newdata_len);
card_data[Pn532.newdata_len] = '\0'; // Enforce null termination
if (mifareclassic_WriteDataBlock(1, card_data)) {
- set_success = true;
+ success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
@@ -467,24 +646,35 @@ void PN532_ScanForTag(void) {
}
switch (Pn532.function) {
case 0x01:
- if (!erase_success) {
+ if (!success) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
}
break;
case 0x02:
- if (!set_success) {
+ if (!success) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
}
default:
break;
}
Pn532.function = 0;
- ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\"}}"), Pn532.uids, card_datas);
+ ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas);
+ if (str_pwd == PWD_NONE) {
+ ResponseAppend_P(PSTR(",\"Auth\":\"None\""));
+ } else
+ if (str_pwd == PWD_OK) {
+ ResponseAppend_P(PSTR(",\"Auth\":\"Ok\""));
+ } else
+ if (str_pwd == PWD_NOK) {
+ ResponseAppend_P(PSTR(",\"Auth\":\"NOk\""));
+ }
+ ResponseAppend_P(PSTR("}}"));
#else
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
#endif // USE_PN532_DATA_FUNCTION
MqttPublishTeleSensor();
+ PN532_inRelease();
Pn532.scantimer = 7; // Ignore tags found for two seconds
}
}
@@ -501,19 +691,23 @@ bool PN532_Command(void) {
return serviced;
}
char argument[XdrvMailbox.data_len];
+/*
for (uint32_t ca=0;ca 1) {
+ } else
+ if (!strcmp(argument,"S")) {
+ if (ArgC() > 1) {
if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
serviced = false;
return serviced;
@@ -528,6 +722,36 @@ bool PN532_Command(void) {
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
return serviced;
}
+ } else
+ if (!strncmp_P(argument,PSTR("AUTH"),4)) {
+ if (ArgC() > 1) {
+ Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_auth);
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"NTAG_PWD\"}}"));
+ }
+ if (ArgC() > 2) {
+ Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_pack);
+ }
+ return true;
+ } else
+ if (!strncmp_P(argument,PSTR("SET_PWD"),7)) {
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}"));
+ Pn532.pwd_auth_new=Pn532.pwd_auth;
+ Pn532.pwd_pack_new=Pn532.pwd_pack;
+ if (ArgC() > 1) {
+ Pn532.pwd_auth_new=strtoul(ArgV(argument,2),nullptr,0);
+ }
+ if (ArgC() > 2) {
+ Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0);
+ }
+ Pn532.function = 3;
+ return true;
+ } else
+ if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) {
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
+ Pn532.function = 4;
+ return true;
}
return false;
}
From b419e69759de4c0ccb8017fcdac1c741c6346241 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 20:18:31 +0300
Subject: [PATCH 062/319] Defines
---
tasmota/my_user_config.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 51ea0d677..ddb3912a5 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -776,8 +776,8 @@
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
-//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
-// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
+#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
+ #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
From 5db8fcd0d051a44e62039956eec974c56f056ab5 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 22:38:12 +0300
Subject: [PATCH 063/319] refactoring mifare classic
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 68 ++++++-------------
1 file changed, 20 insertions(+), 48 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 62615c9bc..fe105f8ce 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -18,7 +18,6 @@
*/
#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
#define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
-// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
#ifdef USE_PN532_HSU
/*********************************************************************************************\
@@ -85,9 +84,9 @@ struct PN532 {
bool present = false; // Maintain detection flag
uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[33];
+ uint8_t newdata[16];
uint8_t function = 0;
-// uint8_t newdata_len = 0;
+ uint8_t newdata_len = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
uint32_t pwd_auth_new;
@@ -587,58 +586,29 @@ void PN532_ScanForTag(void) {
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- uint8_t card_data[16];
- if (mifareclassic_ReadDataBlock(1, card_data)) {
-#ifdef USE_PN532_DATA_RAW
- memcpy(&card_datas,&card_data,sizeof(card_data));
-#else
- for (uint32_t i = 0;i < sizeof(card_data);i++) {
- if (isprint(card_data[i])) {
- card_datas[i] = char(card_data[i]);
- } else {
- card_datas[i] = '\0';
+ if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
+ for (uint32_t i = 0;i < sizeof(card_datas);i++) {
+ if (!isprint(card_datas[i])) {
+ // do not output non-printable characters to the console
+ card_datas[i] = 0;
}
}
-#endif // USE_PN532_DATA_RAW
+ } else {
+ card_datas[0] = 0;
}
if (Pn532.function == 1) { // erase block 1 of card
-//TODO : Test
- for (uint32_t i = 0;i<16;i++) {
- card_data[i] = 0x00;
- }
- if (mifareclassic_WriteDataBlock(1, card_data)) {
+ memset(card_datas,0,sizeof(card_datas));
+ if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
- memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
- }
+ } else
if (Pn532.function == 2) {
-#ifdef USE_PN532_DATA_RAW
- memcpy(&card_data,&Pn532.newdata,sizeof(card_data));
- if (mifareclassic_WriteDataBlock(1, card_data)) {
+ memcpy(&card_datas,&Pn532.newdata,sizeof(card_datas));
+ if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
success = true;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
- memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
}
-#else
- bool IsAlphaNumeric = true;
- for (uint32_t i = 0;i < Pn532.newdata_len;i++) {
- if (!isprint(Pn532.newdata[i])) {
- IsAlphaNumeric = false;
- }
- }
- if (IsAlphaNumeric) {
- memcpy(&card_data,&Pn532.newdata,Pn532.newdata_len);
- card_data[Pn532.newdata_len] = '\0'; // Enforce null termination
- if (mifareclassic_WriteDataBlock(1, card_data)) {
- success = true;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
- memcpy(&card_datas,&card_data,sizeof(card_data)); // Cast block 1 to a string
- }
- } else {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data must be alphanumeric"));
- }
-#endif // USE_PN532_DATA_RAW
}
} else {
sprintf_P(card_datas, PSTR("AUTHFAIL"));
@@ -713,10 +683,12 @@ bool PN532_Command(void) {
return serviced;
}
ArgV(argument, 2);
- Pn532.newdata_len = strlen(argument);
- if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; }
- memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
- Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
+// Pn532.newdata_len = strlen(argument);
+// if (Pn532.newdata_len > 15) { Pn532.newdata_len = 15; }
+// memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
+// Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
+ strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
+ Pn532.newdata[sizeof(Pn532.newdata)-1]=0;
Pn532.function = 2;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
From 3e3dfa35d33db379267102de737fb30cab0df5c7 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 23:14:27 +0300
Subject: [PATCH 064/319] refactoring mifare classic stage 2
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index fe105f8ce..fee1302f8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -86,7 +86,7 @@ struct PN532 {
#ifdef USE_PN532_DATA_FUNCTION
uint8_t newdata[16];
uint8_t function = 0;
- uint8_t newdata_len = 0;
+// uint8_t newdata_len = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
uint32_t pwd_auth_new;
@@ -586,16 +586,6 @@ void PN532_ScanForTag(void) {
if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0;i < sizeof(card_datas);i++) {
- if (!isprint(card_datas[i])) {
- // do not output non-printable characters to the console
- card_datas[i] = 0;
- }
- }
- } else {
- card_datas[0] = 0;
- }
if (Pn532.function == 1) { // erase block 1 of card
memset(card_datas,0,sizeof(card_datas));
if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
@@ -610,6 +600,16 @@ void PN532_ScanForTag(void) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
}
}
+ if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
+ for (uint32_t i = 0;i < sizeof(card_datas);i++) {
+ if (!isprint(card_datas[i])) {
+ // do not output non-printable characters to the console
+ card_datas[i] = 0;
+ }
+ }
+ } else {
+ card_datas[0] = 0;
+ }
} else {
sprintf_P(card_datas, PSTR("AUTHFAIL"));
}
From b35479559db49acb94014bbcf3c55151561a1b5b Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Tue, 25 Oct 2022 23:15:58 +0300
Subject: [PATCH 065/319] Delete #define USE_PN532_DATA_RAW
---
tasmota/my_user_config.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index ddb3912a5..1838b9096 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -778,7 +778,6 @@
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
#define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
-// #define USE_PN532_DATA_RAW // Allow DATA block to be used by non-alpha-numberic data (+ 80 bytes code, 48 bytes ram)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
From 0eebdf86208e04297c70c1f3a15e1ee040bf8c79 Mon Sep 17 00:00:00 2001
From: cybermaus
Date: Tue, 25 Oct 2022 22:34:08 +0200
Subject: [PATCH 066/319] Deduplicate code from xdrv_10_rules.ino
Turns out this code was already done in xdrv_09_timers.ino
---
tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
index 6686b8770..49342df27 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
@@ -1458,19 +1458,7 @@ bool findNextVariableValue(char * &pVarname, float &value)
} else if (sVarName.startsWith(F("TIMER"))) {
uint32_t index = sVarName.substring(5).toInt();
if (index > 0 && index <= MAX_TIMERS) {
- value = Settings->timer[index -1].time;
-#if defined(USE_SUNRISE)
- // Correct %timerN% values for sunrise/sunset timers
- if ((1 == Settings->timer[index -1].mode) || (2 == Settings->timer[index -1].mode)) {
- // in this context, time variable itself is merely an offset, with <720 being negative
- value += -720 + SunMinutes(Settings->timer[index -1].mode -1);
- if (2 == Settings->timer[index -1].mode) {
- // To aid rule comparative statements, sunset past midnight (high lattitudes) is expressed past 24h00
- // So sunset at 00h45 is at 24h45
- if (value < 360) { value += 1440; }
- }
- }
-#endif // USE_SUNRISE
+ value = TimerGetTimeOfDay(index -1);
}
#if defined(USE_SUNRISE)
} else if (sVarName.equals(F("SUNRISE"))) {
From a47f6baf2fc36ba903392a27263587c2d125caa4 Mon Sep 17 00:00:00 2001
From: cybermaus
Date: Tue, 25 Oct 2022 22:39:30 +0200
Subject: [PATCH 067/319] Deduplicate xdrv_09_timers.ino also
Turns out even TimerGetTimeOfDay was duplicate code from ApplyTimerOffsets
Did add a fix for the permanent day/night situation
---
tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino b/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
index 438ade4d5..8c1fd530e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
@@ -253,10 +253,10 @@ uint16_t TimerGetTimeOfDay(uint8_t index)
int16_t xtime = xtimer.time;
#ifdef USE_SUNRISE
if (xtimer.mode) {
- if (xtime >= 12*60) xtime = 12*60 - xtime;
- xtime += (int16_t)SunMinutes(xtimer.mode-1);
- if (xtime < 0) xtime += 24*60;
- if (xtime >= 24*60) xtime -= 24*60;
+ ApplyTimerOffsets(&xtimer);
+ xtime = xtimer.time;
+ if (xtime==2047 && xtimer.mode==1) xtime *= -1; // Sun always has already rises
+ if (xtime==2046 && xtimer.mode==2) xtime *= -1; // Sun always has already set
}
#endif
return xtime;
From 37df680a80720d6b6a2de45870cac171c91b2fc1 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 00:15:04 +0300
Subject: [PATCH 068/319] Refactoring mifare classic, stage 3
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 23 +++++--------------
1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index fee1302f8..50bb6e02a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -82,11 +82,10 @@ struct PN532 {
uint8_t command = 0; // Carry command code between functions
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
bool present = false; // Maintain detection flag
- uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[16];
+ uint16_t atqa;
+ uint8_t newdata[32];
uint8_t function = 0;
-// uint8_t newdata_len = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
uint32_t pwd_auth_new;
@@ -601,12 +600,13 @@ void PN532_ScanForTag(void) {
}
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0;i < sizeof(card_datas);i++) {
+ for (uint32_t i = 0; i < 16;i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
card_datas[i] = 0;
}
}
+ card_datas[16] = 0;
} else {
card_datas[0] = 0;
}
@@ -661,13 +661,6 @@ bool PN532_Command(void) {
return serviced;
}
char argument[XdrvMailbox.data_len];
-/*
- for (uint32_t ca=0;ca 15) { Pn532.newdata_len = 15; }
-// memcpy(&Pn532.newdata,&argument,Pn532.newdata_len);
-// Pn532.newdata[Pn532.newdata_len] = 0x00; // Null terminate the string
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
- Pn532.newdata[sizeof(Pn532.newdata)-1]=0;
+ if (strlen(argument)>16) argument[16]=0;
Pn532.function = 2;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), Pn532.newdata);
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
return serviced;
}
From 0487cf9eaa5ea074c194078ca416c023a62356d7 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 00:50:07 +0300
Subject: [PATCH 069/319] renamed the commands Sensor40, increased recording to
32
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 75 ++++++++++---------
1 file changed, 40 insertions(+), 35 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 50bb6e02a..7e40e58d3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -395,46 +395,51 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the command */
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ for (uint8_t i = 0; i < 2; i++) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
+ Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- /* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
- return 0;
+ /* Send the command */
+ if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
+ return 0;
+ }
+
+ /* Read the response packet */
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+
+ /* If byte 8 isn't 0x00 we probably have an error */
+ if (Pn532.packetbuffer[0] != 0x00) {
+ return 0;
+ }
+
+ /* Copy the 16 data bytes to the output buffer */
+ /* Block content starts at byte 9 of a valid response */
+ memcpy (&data[i<<4], &Pn532.packetbuffer[1], 16);
}
-
- /* Read the response packet */
- PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
-
- /* If byte 8 isn't 0x00 we probably have an error */
- if (Pn532.packetbuffer[0] != 0x00) {
- return 0;
- }
-
- /* Copy the 16 data bytes to the output buffer */
- /* Block content starts at byte 9 of a valid response */
- memcpy (data, &Pn532.packetbuffer[1], 16);
-
return 1;
}
uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
+ for (uint8_t i = 0; i < 2; i++) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
+ Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ memcpy(&Pn532.packetbuffer[4], &data[i<<4], 16); /* Data Payload */
/* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return 0;
- }
-
+ if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
+ return 0;
+ }
/* Read the response packet */
- return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
+ if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) {
+ return 0;
+ }
+ }
+ return 1;
}
uint8_t ntag21x_probe (void) {
@@ -600,13 +605,13 @@ void PN532_ScanForTag(void) {
}
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0; i < 16;i++) {
+ for (uint32_t i = 0; i < 32;i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
card_datas[i] = 0;
}
}
- card_datas[16] = 0;
+ card_datas[32] = 0;
} else {
card_datas[0] = 0;
}
@@ -663,13 +668,13 @@ bool PN532_Command(void) {
char argument[XdrvMailbox.data_len];
ArgV(argument, 1);
UpperCase(argument,argument);
- if (!strcmp(argument,"E")) {
+ if (!strncmp_P(argument,PSTR("ERASE"),5)) {
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}"));
return serviced;
} else
- if (!strcmp(argument,"S")) {
+ if (!strncmp_P(argument,PSTR("WRITE"),5)) {
if (ArgC() > 1) {
if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
serviced = false;
@@ -677,7 +682,7 @@ bool PN532_Command(void) {
}
ArgV(argument, 2);
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
- if (strlen(argument)>16) argument[16]=0;
+ if (strlen(argument)>32) argument[32]=0;
Pn532.function = 2;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
From 9534838c19cb93f2ea6926058c5d431301088598 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 00:56:44 +0300
Subject: [PATCH 070/319] renamed the commands Sensor40, increased recording to
32, stage 2
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 7e40e58d3..35bbfd5e6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -671,7 +671,7 @@ bool PN532_Command(void) {
if (!strncmp_P(argument,PSTR("ERASE"),5)) {
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"E\"}}"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
return serviced;
} else
if (!strncmp_P(argument,PSTR("WRITE"),5)) {
@@ -685,7 +685,7 @@ bool PN532_Command(void) {
if (strlen(argument)>32) argument[32]=0;
Pn532.function = 2;
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"S\"}}"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}"));
return serviced;
}
} else
From 0887ec31f54e4ebc738cefd110d133f567c2996c Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 01:29:10 +0300
Subject: [PATCH 071/319] Reduced 16 bytes
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 25 +++++++++++--------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 35bbfd5e6..c6823d259 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -421,7 +421,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
return 1;
}
-uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
+bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
for (uint8_t i = 0; i < 2; i++) {
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
@@ -432,14 +432,14 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Send the command */
if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return 0;
+ return false;
}
/* Read the response packet */
if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) {
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
uint8_t ntag21x_probe (void) {
@@ -575,6 +575,12 @@ void PN532_ScanForTag(void) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (Pn532.command == 1) {
+ /* Erase */
+ } else
+ if (Pn532.command == 2) {
+ /* Write */
+ }
}
}
}
@@ -587,20 +593,17 @@ void PN532_ScanForTag(void) {
}
}
} else
- if (uid_len == 4) { // Lets try to read block 1 of the mifare classic card for more information
+ if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- if (Pn532.function == 1) { // erase block 1 of card
+ if (Pn532.function == 1) { // erase blocks 1 & 2 of card
memset(card_datas,0,sizeof(card_datas));
- if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
- success = true;
+ if ((success=mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas))) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
}
} else
if (Pn532.function == 2) {
- memcpy(&card_datas,&Pn532.newdata,sizeof(card_datas));
- if (mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas)) {
- success = true;
+ if ((success=mifareclassic_WriteDataBlock(1, Pn532.newdata))) {
AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
}
}
From 0d45590ac4a0b8c314070e234f96b21837b31804 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 26 Oct 2022 12:45:06 +0200
Subject: [PATCH 072/319] Fix Shelly Pro led functionality
---
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 3 +
.../xdrv_88_esp32_shelly_pro.ino | 59 +++++++++++++++----
2 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 4752702b2..f6e90ca2b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -1036,6 +1036,9 @@ void CmndMaxEnergyStart(void) {
void EnergyDrvInit(void) {
memset(&Energy, 0, sizeof(Energy)); // Reset all to 0 and false;
+// Energy.voltage_common = false;
+// Energy.frequency_common = false;
+// Energy.use_overtemp = false;
for (uint32_t phase = 0; phase < ENERGY_MAX_PHASES; phase++) {
Energy.apparent_power[phase] = NAN;
Energy.reactive_power[phase] = NAN;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index d7ffd8caa..1c695804d 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -23,18 +23,18 @@
/*********************************************************************************************\
* Shelly Pro support
*
- * {"NAME":"Shelly Pro 1","GPIO":[0,0,0,0,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,0,0,160,0],"FLAG":0,"BASE":1}
- * {"NAME":"Shelly Pro 2","GPIO":[0,0,0,0,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,0,0,160,161],"FLAG":0,"BASE":1}
+ * {"NAME":"Shelly Pro 1","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
+ * {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
+ * {"NAME":"Shelly Pro 2","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350;AdcParam2 2,10000,10000,3350"}
+ * {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350;AdcParam2 2,10000,10000,3350"}
*
* Shelly Pro uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring
- *
- * Testset
- * {"NAME":"Shelly Pro 2PM (POC)","GPIO":[1,0,1,0,768,1,0,0,672,704,736,1,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,32,1,1,160,161],"FLAG":0,"BASE":1}
\*********************************************************************************************/
#define XDRV_88 88
struct SPro {
+ uint32_t last_update;
uint8_t pin_shift595_rclk;
uint8_t ledlink;
uint8_t power;
@@ -53,9 +53,9 @@ void ShellyProUpdate(void) {
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
SPI.transfer(val); // Write 74HC595 shift register
SPI.endTransaction();
-
- digitalWrite(SPro.pin_shift595_rclk, 1);
- delayMicroseconds(200); // Shelly 10mS
+ delayMicroseconds(2); // Wait for SPI clock to stop
+ digitalWrite(SPro.pin_shift595_rclk, 1); // Latch data
+ delayMicroseconds(2); // Shelly 10mS
digitalWrite(SPro.pin_shift595_rclk, 0);
}
@@ -71,13 +71,13 @@ void ShellyProPreInit(void) {
}
SPro.pin_shift595_rclk = Pin(GPIO_SPI_CS);
- pinMode(SPro.pin_shift595_rclk, OUTPUT);
digitalWrite(SPro.pin_shift595_rclk, 0);
+ pinMode(SPro.pin_shift595_rclk, OUTPUT);
// Does nothing if SPI is already initiated (by ADE7953) so no harm done
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
SPro.power = TasmotaGlobal.power &3; // Restore power
- SPro.ledlink = 0x1C; // All leds off
+ SPro.ledlink = 0x18; // Blue led on
ShellyProUpdate();
SPro.detected = true;
@@ -90,10 +90,40 @@ void ShellyProPower(void) {
ShellyProUpdate();
}
+void ShellyProUpdateLedLink(uint32_t ledlink) {
+ if (ledlink != SPro.ledlink) {
+ SPro.ledlink = ledlink;
+ ShellyProUpdate();
+ }
+}
+
void ShellyProLedLink(void) {
- // bit 2 = blue, 3 = green, 4 = red
- SPro.ledlink = (XdrvMailbox.index) ? 0x18 : 0x1C; // Blue on (wifi link) or all off
- ShellyProUpdate();
+ /*
+ bit 2 = blue, 3 = green, 4 = red
+ Shelly Pro documentation
+ - Blue light indicator will be on if in AP mode.
+ - Red light indicator will be on if in STA mode and not connected to a Wi-Fi network.
+ - Yellow light indicator will be on if in STA mode and connected to a Wi-Fi network.
+ - Green light indicator will be on if in STA mode and connected to a Wi-Fi network and to the Shelly Cloud.
+ - The light indicator will be flashing Red/Blue if OTA update is in progress.
+ Tasmota default behaviour
+ - Blue light indicator will blink if no wifi or mqtt.
+ */
+ SPro.last_update = TasmotaGlobal.uptime;
+ uint32_t ledlink = 0x1C;
+ if (XdrvMailbox.index) { ledlink &= 0xFB; } // Blue blinks if wifi/mqtt lost
+ if (!TasmotaGlobal.global_state.wifi_down) { ledlink &= 0xF7; } // Green On
+ ShellyProUpdateLedLink(ledlink);
+}
+
+void ShellyProLedLinkWifiOff(void) {
+ /*
+ bit 2 = blue, 3 = green, 4 = red
+ - Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
+ */
+ if (SPro.last_update +1 < TasmotaGlobal.uptime) {
+ ShellyProUpdateLedLink((TasmotaGlobal.global_state.wifi_down) ? 0x1C : 0x14); // Green off if wifi OFF
+ }
}
/*********************************************************************************************\
@@ -107,6 +137,9 @@ bool Xdrv88(uint8_t function) {
ShellyProPreInit();
} else if (SPro.detected) {
switch (function) {
+ case FUNC_EVERY_SECOND:
+ ShellyProLedLinkWifiOff();
+ break;
case FUNC_SET_POWER:
ShellyProPower();
break;
From e2391c33e7ee1a17772ac0edda23a422848e9538 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:50:44 +0200
Subject: [PATCH 073/319] use actual builded safeboot firmwares for all esp32
env (Github Actions only) (#16915)
---
.github/workflows/Tasmota_build_devel.yml | 148 ++++++++++++++++-----
.github/workflows/Tasmota_build_master.yml | 137 ++++++++++++++-----
pio-tools/post_esp32.py | 7 +
3 files changed, 227 insertions(+), 65 deletions(-)
diff --git a/.github/workflows/Tasmota_build_devel.yml b/.github/workflows/Tasmota_build_devel.yml
index 5e7d7145a..30502be32 100644
--- a/.github/workflows/Tasmota_build_devel.yml
+++ b/.github/workflows/Tasmota_build_devel.yml
@@ -1,12 +1,13 @@
+
name: Build_development
on:
- workflow_dispatch: # Manually start a workflow
+ workflow_dispatch: # Manually start a workflow
push:
branches: development
paths-ignore:
- - '.github/**' # Ignore changes towards the .github directory
- - '**.md' # Do no build if *.md files changes
+ - '.github/**' # Ignore changes towards the .github directory
+ - '**.md' # Do no build if *.md files changes
# Ensures that only one deploy task per branch/environment will run at a time.
concurrency:
@@ -14,38 +15,13 @@ concurrency:
cancel-in-progress: true
jobs:
- base-images:
+ safeboot-images:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
strategy:
matrix:
variant:
- - tasmota
- - tasmota4M
- - tasmota-minimal
- - tasmota-display
- - tasmota-ir
- - tasmota-knx
- - tasmota-lite
- - tasmota-sensors
- - tasmota-zbbridge
- - tasmota-zigbee
- - tasmota32
- - tasmota32-zbbrdgpro
- - tasmota32-webcam
- - tasmota32-bluetooth
- - tasmota32-nspanel
- - tasmota32-display
- - tasmota32-ir
- - tasmota32-lvgl
- - tasmota32c3
- - tasmota32c3cdc
- - tasmota32s2
- - tasmota32s2cdc
- - tasmota32s3
- - tasmota32s3cdc
- - tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
@@ -68,12 +44,102 @@ jobs:
pip install -U platformio
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- - uses: actions/upload-artifact@v3
+ - name: Upload safeboot firmware artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./build_output
+
+ base-images:
+ runs-on: ubuntu-latest
+ if: github.repository == 'arendst/Tasmota'
+ continue-on-error: true
+ strategy:
+ matrix:
+ variant:
+ - tasmota
+ - tasmota4M
+ - tasmota-minimal
+ - tasmota-display
+ - tasmota-ir
+ - tasmota-knx
+ - tasmota-lite
+ - tasmota-sensors
+ - tasmota-zbbridge
+ - tasmota-zigbee
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: development
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ - name: Install dependencies
+ run: |
+ pip install wheel
+ pip install -U platformio
+ - name: Run PlatformIO
+ run: platformio run -e ${{ matrix.variant }}
+ - name: Upload firmware artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: firmware
+ path: ./build_output
+
+ base32-images:
+ needs: safeboot-images
+ runs-on: ubuntu-latest
+ if: github.repository == 'arendst/Tasmota'
+ continue-on-error: true
+ strategy:
+ matrix:
+ variant:
+ - tasmota32
+ - tasmota32-zbbrdgpro
+ - tasmota32-webcam
+ - tasmota32-bluetooth
+ - tasmota32-nspanel
+ - tasmota32-display
+ - tasmota32-ir
+ - tasmota32-lvgl
+ - tasmota32c3
+ - tasmota32c3cdc
+ - tasmota32s2
+ - tasmota32s2cdc
+ - tasmota32s3
+ - tasmota32s3cdc
+ - tasmota32solo1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: development
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ - name: Install dependencies
+ run: |
+ pip install wheel
+ pip install -U platformio
+ - name: Download safeboot firmwares
+ uses: actions/download-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./firmware
+ - name: Display downloaded files
+ run: |
+ ls -R ./firmware/
+ - name: Run PlatformIO
+ run: platformio run -e ${{ matrix.variant }}
+ - name: Upload firmware artifacts
+ uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
language-images:
+ needs: safeboot-images
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
@@ -93,22 +159,37 @@ jobs:
run: |
pip install wheel
pip install -U platformio
+ - name: Download safeboot firmwares
+ uses: actions/download-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./firmware
+ - name: Display downloaded files
+ run: |
+ ls -R ./firmware/
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
- - uses: actions/upload-artifact@v3
+ - name: Upload language firmware artifacts
+ uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
Upload:
- needs: [base-images, language-images]
+ needs: [base-images, base32-images, language-images]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- - uses: actions/download-artifact@v3
+ - name: Download firmware
+ uses: actions/download-artifact@v3
with:
name: firmware
path: ./mv_firmware
+ - name: Downlaod safeboot firmware
+ uses: actions/download-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./mv_firmware
- name: Display structure of downloaded files
run: ls -R
working-directory: ./mv_firmware
@@ -159,7 +240,6 @@ jobs:
destination_branch: 'firmware'
user_email: 'github-actions@github.com'
user_name: 'github-actions'
-
Start_final_copy:
needs: Upload
runs-on: ubuntu-latest
diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml
index 133e4502c..e538a623f 100644
--- a/.github/workflows/Tasmota_build_master.yml
+++ b/.github/workflows/Tasmota_build_master.yml
@@ -1,11 +1,12 @@
name: Build_firmware_master
on:
+ workflow_dispatch: # Manually start a workflow
push:
branches: master
paths-ignore:
- - '.github/**' # Ignore changes towards the .github directory
- - '**.md' # Do no build if *.md files changes
+ - '.github/**' # Ignore changes towards the .github directory
+ - '**.md' # Do no build if *.md files changes
# Ensures that only one deploy task per branch/environment will run at a time.
concurrency:
@@ -13,38 +14,13 @@ concurrency:
cancel-in-progress: true
jobs:
- base-images:
+ safeboot-images:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
strategy:
matrix:
variant:
- - tasmota
- - tasmota4M
- - tasmota-minimal
- - tasmota-display
- - tasmota-ir
- - tasmota-knx
- - tasmota-lite
- - tasmota-sensors
- - tasmota-zbbridge
- - tasmota-zigbee
- - tasmota32
- - tasmota32-zbbrdgpro
- - tasmota32-webcam
- - tasmota32-bluetooth
- - tasmota32-nspanel
- - tasmota32-display
- - tasmota32-ir
- - tasmota32-lvgl
- - tasmota32c3
- - tasmota32c3cdc
- - tasmota32s2
- - tasmota32s2cdc
- - tasmota32s3
- - tasmota32s3cdc
- - tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
@@ -67,12 +43,102 @@ jobs:
pip install -U platformio
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- - uses: actions/upload-artifact@v3
+ - name: Upload safeboot firmware artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./build_output
+
+ base-images:
+ runs-on: ubuntu-latest
+ if: github.repository == 'arendst/Tasmota'
+ continue-on-error: true
+ strategy:
+ matrix:
+ variant:
+ - tasmota
+ - tasmota4M
+ - tasmota-minimal
+ - tasmota-display
+ - tasmota-ir
+ - tasmota-knx
+ - tasmota-lite
+ - tasmota-sensors
+ - tasmota-zbbridge
+ - tasmota-zigbee
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: master
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ - name: Install dependencies
+ run: |
+ pip install wheel
+ pip install -U platformio
+ - name: Run PlatformIO
+ run: platformio run -e ${{ matrix.variant }}
+ - name: Upload firmware artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: firmware
+ path: ./build_output
+
+ base32-images:
+ needs: safeboot-images
+ runs-on: ubuntu-latest
+ if: github.repository == 'arendst/Tasmota'
+ continue-on-error: true
+ strategy:
+ matrix:
+ variant:
+ - tasmota32
+ - tasmota32-zbbrdgpro
+ - tasmota32-webcam
+ - tasmota32-bluetooth
+ - tasmota32-nspanel
+ - tasmota32-display
+ - tasmota32-ir
+ - tasmota32-lvgl
+ - tasmota32c3
+ - tasmota32c3cdc
+ - tasmota32s2
+ - tasmota32s2cdc
+ - tasmota32s3
+ - tasmota32s3cdc
+ - tasmota32solo1
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ ref: master
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ - name: Install dependencies
+ run: |
+ pip install wheel
+ pip install -U platformio
+ - name: Download safeboot firmwares
+ uses: actions/download-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./firmware
+ - name: Display downloaded files
+ run: |
+ ls -R ./firmware/
+ - name: Run PlatformIO
+ run: platformio run -e ${{ matrix.variant }}
+ - name: Upload firmware artifacts
+ uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
language-images:
+ needs: safeboot-images
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
@@ -92,9 +158,18 @@ jobs:
run: |
pip install wheel
pip install -U platformio
+ - name: Download safeboot firmwares
+ uses: actions/download-artifact@v3
+ with:
+ name: firmware_safeboot
+ path: ./firmware
+ - name: Display downloaded files
+ run: |
+ ls -R ./firmware/
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
- - uses: actions/upload-artifact@v3
+ - name: Upload language firmware artifacts
+ uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
@@ -112,7 +187,7 @@ jobs:
- name: Display structure of downloaded files
run: ls -R ./mv_firmware/
- name: Release
- uses: softprops/action-gh-release@v1
+ uses: jason2866/action-gh-release@v1.1
#if: startsWith(github.ref, 'refs/tags/')
with:
tag_name: ${{ github.run_number }}
diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py
index 2ca0afc4f..3ded90386 100644
--- a/pio-tools/post_esp32.py
+++ b/pio-tools/post_esp32.py
@@ -33,15 +33,22 @@ import subprocess
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
+github_actions = os.getenv('GITHUB_ACTIONS')
extra_flags = ''.join([element.replace("-D", " ") for element in env.BoardConfig().get("build.extra_flags", "")])
build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectOption("build_flags")])
if "CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags:
FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1")
+ if github_actions and os.path.exists("./firmware/firmware"):
+ shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota")
elif "CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags:
FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD")
+ if github_actions and os.path.exists("./firmware/firmware"):
+ shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota")
else:
FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32")
+ if github_actions and os.path.exists("./firmware/firmware"):
+ shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota")
variants_dir = join(FRAMEWORK_DIR, "variants", "tasmota")
From c5f7195d774e3454a8b874edd86a1b700c021161 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 26 Oct 2022 17:16:36 +0200
Subject: [PATCH 074/319] Add support for Shelly Pro 1/1PM and 2/2PM (#16773)
---
CHANGELOG.md | 2 +-
RELEASENOTES.md | 6 +-
.../xdrv_88_esp32_shelly_pro.ino | 5 +-
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 494 +++++++++++-------
4 files changed, 315 insertions(+), 192 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3363b6293..b563d0683 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
- Berry add `bytes().setbytes()` (#16892)
-- Support for Shelly Pro 1/2 (#16773)
+- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
- Prepare for DMX Artnet support on ESP32
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 5e85b1f00..2286b8edb 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,9 +109,11 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.1
### Added
-- DS18x20 support on up to four GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
+- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
+- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
+- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
-- Support for Shelly Pro 1/2 [#16773](https://github.com/arendst/Tasmota/issues/16773)
+- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
### Breaking Changed
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 1c695804d..486d79037 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -106,11 +106,12 @@ void ShellyProLedLink(void) {
- Yellow light indicator will be on if in STA mode and connected to a Wi-Fi network.
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network and to the Shelly Cloud.
- The light indicator will be flashing Red/Blue if OTA update is in progress.
- Tasmota default behaviour
+ Tasmota behaviour
- Blue light indicator will blink if no wifi or mqtt.
+ - Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
*/
SPro.last_update = TasmotaGlobal.uptime;
- uint32_t ledlink = 0x1C;
+ uint32_t ledlink = 0x1C; // All leds off
if (XdrvMailbox.index) { ledlink &= 0xFB; } // Blue blinks if wifi/mqtt lost
if (!TasmotaGlobal.global_state.wifi_down) { ledlink &= 0xF7; } // Green On
ShellyProUpdateLedLink(ledlink);
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 6b01b4b61..fc8e3411e 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -17,29 +17,40 @@
along with this program. If not, see .
*/
-#ifdef USE_I2C
+#if defined(ESP32) && defined(USE_SPI)
+#define USE_ESP32_SPI
+#endif
+#if defined(USE_I2C) || defined(USE_ESP32_SPI)
#ifdef USE_ENERGY_SENSOR
#ifdef USE_ADE7953
/*********************************************************************************************\
- * ADE7953 - Energy used in Shelly 2.5 (model 1), Shelly EM (model 2) and Shelly Plus 2PM (model 3)
+ * ADE7953 - Energy used in Shelly 2.5 (model 1), Shelly EM (model 2), Shelly Plus 2PM (model 3), Shelly Pro 1PM (model 4) and Shelly Pro 2PM (model 5)
*
* {"NAME":"Shelly 2.5","GPIO":[320,0,32,0,224,193,0,0,640,192,608,225,3456,4736],"FLAG":0,"BASE":18}
* {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,640,3457,608,224,8832,1],"FLAG":0,"BASE":18}
* {"NAME":"Shelly Plus 2PM PCB v0.1.5","GPIO":[320,0,192,0,0,0,1,1,225,224,0,0,0,0,193,0,0,0,0,0,0,608,3840,32,0,0,0,0,0,640,0,0,3458,4736,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,32000,40000,3350"}
* {"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
+ * {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
+ * {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350;AdcParam2 2,10000,10000,3350"}
*
* Based on datasheet from https://www.analog.com/en/products/ade7953.html
*
* Model differences:
- * Function Model1 Model2 Model3 Remark
- * ------------------------------ ------ ------ ------- -------------------------------------------------
- * Shelly 2.5 EM Plus2PM
- * Current measurement device shunt CT shunt CT = Current Transformer
- * Swapped channel A/B Yes No No Defined by hardware design - Fixed by Tasmota
- * Support Export Active No Yes No Only EM supports correct negative value detection
- * Show negative (reactive) power No Yes No Only EM supports correct negative value detection
- * Default phase calibration 0 200 0 CT needs different phase calibration than shunts
- * Default reset pin on ESP8266 - 16 - Legacy support. Replaced by GPIO ADE7953RST
+ * Function Model1 Model2 Model3 Model4 Model5 Remark
+ * ------------------------------ ------- ------- ------- ------ ------ -------------------------------------------------
+ * Shelly 2.5 EM Plus2PM Pro1PM Pro2PM
+ * Processor ESP8266 ESP8266 ESP32 ESP32 ESP32
+ * Interface I2C I2C I2C SPI SPI Interface type used
+ * Number of ADE9753 chips 1 1 1 1 2 Count of ADE9753 chips
+ * ADE9753 IRQ 1 2 3 4 5 Index defines model number
+ * Current measurement device shunt CT shunt shunt shunt CT = Current Transformer
+ * Common voltage Yes Yes Yes No No Show common voltage in GUI/JSON
+ * Common frequency Yes Yes Yes No No Show common frequency in GUI/JSON
+ * Swapped channel A/B Yes No No No No Defined by hardware design - Fixed by Tasmota
+ * Support Export Active No Yes No No No Only EM supports correct negative value detection
+ * Show negative (reactive) power No Yes No No No Only EM supports correct negative value detection
+ * Default phase calibration 0 200 0 0 0 CT needs different phase calibration than shunts
+ * Default reset pin on ESP8266 - 16 - - - Legacy support. Replaced by GPIO ADE7953RST
*
* I2C Address: 0x38
*********************************************************************************************
@@ -66,11 +77,10 @@
// Default calibration parameters can be overridden by a rule as documented above.
#define ADE7953_GAIN_DEFAULT 4194304 // = 0x400000 range 2097152 (min) to 6291456 (max)
-
#define ADE7953_PHCAL_DEFAULT 0 // = range -383 to 383 - Default phase calibration for Shunts
#define ADE7953_PHCAL_DEFAULT_CT 200 // = range -383 to 383 - Default phase calibration for Current Transformers (Shelly EM)
-enum Ade7953Models { ADE7953_SHELLY_25, ADE7953_SHELLY_EM, ADE7953_SHELLY_PLUS_2PM };
+enum Ade7953Models { ADE7953_SHELLY_25, ADE7953_SHELLY_EM, ADE7953_SHELLY_PLUS_2PM, ADE7953_SHELLY_PRO_1PM, ADE7953_SHELLY_PRO_2PM };
enum Ade7953_8BitRegisters {
// Register Name Addres R/W Bt Ty Default Description
@@ -175,57 +185,38 @@ enum Ade7953_32BitRegisters {
};
enum Ade7953CalibrationRegisters {
- ADE7953_CAL_AVGAIN,
- ADE7953_CAL_BVGAIN,
- ADE7953_CAL_AIGAIN,
- ADE7953_CAL_BIGAIN,
- ADE7953_CAL_AWGAIN,
- ADE7953_CAL_BWGAIN,
- ADE7953_CAL_AVAGAIN,
- ADE7953_CAL_BVAGAIN,
- ADE7953_CAL_AVARGAIN,
- ADE7953_CAL_BVARGAIN,
- ADE7943_CAL_PHCALA,
- ADE7943_CAL_PHCALB
+ ADE7953_CAL_VGAIN,
+ ADE7953_CAL_IGAIN,
+ ADE7953_CAL_WGAIN,
+ ADE7953_CAL_VAGAIN,
+ ADE7953_CAL_VARGAIN,
+ ADE7943_CAL_PHCAL
};
-const uint16_t Ade7953CalibRegs[] {
- ADE7953_AVGAIN,
- ADE7953_BVGAIN,
- ADE7953_AIGAIN,
- ADE7953_BIGAIN,
- ADE7953_AWGAIN,
- ADE7953_BWGAIN,
- ADE7953_AVAGAIN,
- ADE7953_BVAGAIN,
- ADE7953_AVARGAIN,
- ADE7953_BVARGAIN,
- ADE7943_PHCALA,
- ADE7943_PHCALB
+const uint8_t ADE7953_CALIBREGS = 6;
+const uint16_t Ade7953CalibRegs[2][ADE7953_CALIBREGS] {
+ { ADE7953_AVGAIN, ADE7953_AIGAIN, ADE7953_AWGAIN, ADE7953_AVAGAIN, ADE7953_AVARGAIN, ADE7943_PHCALA },
+ { ADE7953_BVGAIN, ADE7953_BIGAIN, ADE7953_BWGAIN, ADE7953_BVAGAIN, ADE7953_BVARGAIN, ADE7943_PHCALB }
};
-const uint16_t Ade7953Registers[] {
- ADE7953_IRMSA, // IRMSA - RMS current channel A
- ADE7953_AWATT, // AWATT - Active power channel A
- ADE7953_AVA, // AVA - Apparent power channel A
- ADE7953_AVAR, // AVAR - Reactive power channel A
- ADE7953_IRMSB, // IRMSB - RMS current channel B
- ADE7953_BWATT, // BWATT - Active power channel B
- ADE7953_BVA, // BVA - Apparent power channel B
- ADE7953_BVAR, // BVAR - Reactive power channel B
- ADE7953_VRMS, // VRMS - RMS voltage (Both channels)
- ADE7943_Period, // Period - 16-bit unsigned period register
- ADE7953_ACCMODE // ACCMODE - Accumulation mode
+const uint8_t ADE7953_REGISTERS = 6;
+const uint16_t Ade7953Registers[2][ADE7953_REGISTERS] {
+ { ADE7953_IRMSA, ADE7953_AWATT, ADE7953_AVA, ADE7953_AVAR, ADE7953_VRMS, ADE7943_Period },
+ { ADE7953_IRMSB, ADE7953_BWATT, ADE7953_BVA, ADE7953_BVAR, ADE7953_VRMS, ADE7943_Period }
};
struct Ade7953 {
- uint32_t voltage_rms = 0;
- uint32_t period = 0;
+ uint32_t voltage_rms[2] = { 0, 0 };
uint32_t current_rms[2] = { 0, 0 };
uint32_t active_power[2] = { 0, 0 };
- int32_t calib_data[sizeof(Ade7953CalibRegs)/sizeof(uint16_t)];
+ int32_t calib_data[2][ADE7953_CALIBREGS];
uint8_t init_step = 0;
- uint8_t model = 0; // 0 = Shelly 2.5, 1 = Shelly EM, 2 = Shelly Plus 2PM
+ uint8_t model = 0; // 0 = Shelly 2.5, 1 = Shelly EM, 2 = Shelly Plus 2PM, 3 = Shelly Pro 1PM, 4 = Shelly Pro 2PM
+ uint8_t cs_index;
+#ifdef USE_ESP32_SPI
+ SPISettings spi_settings;
+ int8_t pin_cs[2];
+#endif // USE_ESP32_SPI
} Ade7953;
int Ade7953RegSize(uint16_t reg) {
@@ -248,14 +239,35 @@ int Ade7953RegSize(uint16_t reg) {
void Ade7953Write(uint16_t reg, uint32_t val) {
int size = Ade7953RegSize(reg);
if (size) {
- Wire.beginTransmission(ADE7953_ADDR);
- Wire.write((reg >> 8) & 0xFF);
- Wire.write(reg & 0xFF);
- while (size--) {
- Wire.write((val >> (8 * size)) & 0xFF); // Write data, MSB first
+
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Write %08X"), val);
+
+#ifdef USE_ESP32_SPI
+ if (Ade7953.pin_cs[0] >= 0) {
+ digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 0);
+ delayMicroseconds(1); // CS 1uS to SCLK edge
+ SPI.beginTransaction(Ade7953.spi_settings);
+ SPI.transfer16(reg);
+ SPI.transfer(0x00); // Write
+ while (size--) {
+ SPI.transfer((val >> (8 * size)) & 0xFF); // Write data, MSB first
+ }
+ SPI.endTransaction();
+ delayMicroseconds(2); // CS high 1.2uS after SCLK edge (when writing to COMM_LOCK bit)
+ digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 1);
+ } else {
+#endif // USE_ESP32_SPI
+ Wire.beginTransmission(ADE7953_ADDR);
+ Wire.write((reg >> 8) & 0xFF);
+ Wire.write(reg & 0xFF);
+ while (size--) {
+ Wire.write((val >> (8 * size)) & 0xFF); // Write data, MSB first
+ }
+ Wire.endTransmission();
+ delayMicroseconds(5); // Bus-free time minimum 4.7us
+#ifdef USE_ESP32_SPI
}
- Wire.endTransmission();
- delayMicroseconds(5); // Bus-free time minimum 4.7us
+#endif // USE_ESP32_SPI
}
}
@@ -264,115 +276,176 @@ int32_t Ade7953Read(uint16_t reg) {
int size = Ade7953RegSize(reg);
if (size) {
- Wire.beginTransmission(ADE7953_ADDR);
- Wire.write((reg >> 8) & 0xFF);
- Wire.write(reg & 0xFF);
- Wire.endTransmission(0);
- Wire.requestFrom(ADE7953_ADDR, size);
- if (size <= Wire.available()) {
- for (uint32_t i = 0; i < size; i++) {
- response = response << 8 | Wire.read(); // receive DATA (MSB first)
+#ifdef USE_ESP32_SPI
+ if (Ade7953.pin_cs[0] >= 0) {
+ digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 0);
+ delayMicroseconds(1); // CS 1uS to SCLK edge
+ SPI.beginTransaction(Ade7953.spi_settings);
+ SPI.transfer16(reg);
+ SPI.transfer(0x80); // Read
+ while (size--) {
+ response = response << 8 | SPI.transfer(0); // receive DATA (MSB first)
}
+ SPI.endTransaction();
+ digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 1);
+ } else {
+#endif // USE_ESP32_SPI
+ Wire.beginTransmission(ADE7953_ADDR);
+ Wire.write((reg >> 8) & 0xFF);
+ Wire.write(reg & 0xFF);
+ Wire.endTransmission(0);
+ Wire.requestFrom(ADE7953_ADDR, size);
+ if (size <= Wire.available()) {
+ for (uint32_t i = 0; i < size; i++) {
+ response = response << 8 | Wire.read(); // receive DATA (MSB first)
+ }
+ }
+#ifdef USE_ESP32_SPI
}
+#endif // USE_ESP32_SPI
}
return response;
}
#ifdef ADE7953_DUMP_REGS
void Ade7953DumpRegs(void) {
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: SAGCYC DISNOLD Resrvd Resrvd LCYCMOD Resrvd Resrvd PGAV PGAIA PGAIB"));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** SAGCYC DISNOLD Resrvd Resrvd LCYCMOD Resrvd Resrvd PGAV PGAIA PGAIB"));
char data[200] = { 0 };
for (uint32_t i = 0; i < 10; i++) {
int32_t value = Ade7953Read(ADE7953_SAGCYC + i);
snprintf_P(data, sizeof(data), PSTR("%s %02X"), data, value); // 8-bit regs
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x000..009%s"), data);
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: ZXTOUT LINECYC CONFIG CF1DEN CF2DEN Resrvd Resrvd CFMODE PHCALA PHCALB PFA PFB ANGLEA ANGLEB Period"));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x000..009%s"), data);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** ZXTOUT LINECYC CONFIG CF1DEN CF2DEN Resrvd Resrvd CFMODE PHCALA PHCALB PFA PFB ANGLEA ANGLEB Period"));
data[0] = '\0';
for (uint32_t i = 0; i < 15; i++) {
int32_t value = Ade7953Read(ADE7953_ZXTOUT + i);
snprintf_P(data, sizeof(data), PSTR("%s %04X"), data, value); // 16-bit regs
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x100..10E%s"), data);
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: IGAIN VGAIN WGAIN VARGAIN VAGAIN Resrvd IRMSOS Resrvd VRMSOS WATTOS VAROS VAOS"));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x100..10E%s"), data);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** IGAIN VGAIN WGAIN VARGAIN VAGAIN Resrvd IRMSOS Resrvd VRMSOS WATTOS VAROS VAOS"));
data[0] = '\0';
for (uint32_t i = 0; i < 12; i++) {
int32_t value = Ade7953Read(ADE7953_AIGAIN + i);
snprintf_P(data, sizeof(data), PSTR("%s %06X"), data, value); // 24-bit regs
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x380..38B%s"), data);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x380..38B%s"), data);
data[0] = '\0';
for (uint32_t i = 0; i < 12; i++) {
int32_t value = Ade7953Read(ADE7953_BIGAIN + i);
snprintf_P(data, sizeof(data), PSTR("%s %06X"), data, value); // 24-bit regs
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x38C..397%s"), data);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x38C..397%s"), data);
}
#endif // ADE7953_DUMP_REGS
+void Ade7953SetCalibration(uint32_t regset, uint32_t calibset) {
+ Ade7953.cs_index = calibset;
+ for (uint32_t i = 0; i < ADE7953_CALIBREGS; i++) {
+ int32_t value = Ade7953.calib_data[calibset][i];
+ if (ADE7943_CAL_PHCAL == i) {
+// if (ADE7953_PHCAL_DEFAULT == value) { continue; } // ADE7953 reset does NOT always reset all registers
+ if (value < 0) {
+ value = abs(value) + 0x200; // Add sign magnitude
+ }
+ }
+// if (ADE7953_GAIN_DEFAULT == value) { continue; } // ADE7953 reset does NOT always reset all registers
+ Ade7953Write(Ade7953CalibRegs[regset][i], value);
+ }
+}
+
void Ade7953Init(void) {
+ uint32_t chips = 1;
+#ifdef USE_ESP32_SPI
+ chips = (Ade7953.pin_cs[1] >= 0) ? 2 : 1;
+#endif // USE_ESP32_SPI
+ for (uint32_t chip = 0; chip < chips; chip++) {
+ Ade7953.cs_index = chip;
+
#ifdef ADE7953_DUMP_REGS
- Ade7953DumpRegs();
+ Ade7953DumpRegs();
#endif // ADE7953_DUMP_REGS
- Ade7953Write(ADE7953_CONFIG, 0x0004); // Locking the communication interface (Clear bit COMM_LOCK), Enable HPF
- Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120
- Ade7953Write(0x120, 0x0030); // Configure optimum setting
+ Ade7953Write(ADE7953_CONFIG, 0x0004); // Locking the communication interface (Clear bit COMM_LOCK), Enable HPF
+ Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120
+ Ade7953Write(0x120, 0x0030); // Configure optimum setting
+#ifdef USE_ESP32_SPI
+ int32_t value = Ade7953Read(0x702); // Silicon version
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Chip%d version %d"), chip +1, value);
+#endif // USE_ESP32_SPI
+ }
- for (uint32_t i = 0; i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t); i++) {
- if (i >= ADE7943_CAL_PHCALA) {
- int16_t phasecal = Ade7953.calib_data[i];
- if (phasecal < 0) {
- phasecal = abs(phasecal) + 0x200; // Add sign magnitude
- }
- Ade7953Write(Ade7953CalibRegs[i], phasecal);
- } else {
- Ade7953Write(Ade7953CalibRegs[i], Ade7953.calib_data[i]);
- }
+ Ade7953SetCalibration(0, 0); // First ADE7953 A registers set with calibration set 0
+#ifdef USE_ESP32_SPI
+ if (Ade7953.pin_cs[1] >= 0) { // Second ADE7953 using SPI
+ Ade7953SetCalibration(0, 1); // Second ADE7953 A registers set with calibration set 1
}
- int32_t regs[sizeof(Ade7953CalibRegs)/sizeof(uint16_t)];
- for (uint32_t i = 0; i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t); i++) {
- regs[i] = Ade7953Read(Ade7953CalibRegs[i]);
- if (i >= ADE7943_CAL_PHCALA) {
- if (regs[i] >= 0x0200) {
- regs[i] &= 0x01FF; // Clear sign magnitude
- regs[i] *= -1; // Make negative
+ else if (Ade7953.pin_cs[0] == -1) // No first ADE7953 using SPI so set register set B
+#endif // USE_ESP32_SPI
+ Ade7953SetCalibration(1, 1); // First ADE7953 B register set with calibration set 1
+
+ int32_t regs[ADE7953_CALIBREGS];
+ for (uint32_t chip = 0; chip < chips; chip++) {
+ Ade7953.cs_index = chip;
+ for (uint32_t channel = 0; channel < 2; channel++) {
+ for (uint32_t i = 0; i < ADE7953_CALIBREGS; i++) {
+ regs[i] = Ade7953Read(Ade7953CalibRegs[channel][i]);
+ if (ADE7943_CAL_PHCAL == i) {
+ if (regs[i] >= 0x0200) {
+ regs[i] &= 0x01FF; // Clear sign magnitude
+ regs[i] *= -1; // Make negative
+ }
+ }
}
+#ifdef USE_ESP32_SPI
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: Chip%d CalibRegs%c V %d, I %d, W %d, VA %d, VAr %d, Ph %d"), chip +1, 'A'+channel, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]);
+#else
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: CalibRegs%c V %d, I %d, W %d, VA %d, VAr %d, Ph %d"), 'A'+channel, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]);
+#endif // USE_ESP32_SPI
}
- }
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: CalibRegs aV %d, bV %d, aI %d, bI %d, aW %d, bW %d, aVA %d, bVA %d, aVAr %d, bVAr %d, aP %d, bP %d"),
- regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[8], regs[9], regs[10], regs[11]);
+
#ifdef ADE7953_DUMP_REGS
- Ade7953DumpRegs();
+ Ade7953DumpRegs();
#endif // ADE7953_DUMP_REGS
+ }
}
void Ade7953GetData(void) {
- uint32_t acc_mode;
- int32_t reg[2][4];
- for (uint32_t i = 0; i < sizeof(Ade7953Registers)/sizeof(uint16_t); i++) {
- int32_t value = Ade7953Read(Ade7953Registers[i]);
- if (8 == i) {
- Ade7953.voltage_rms = value; // RMS voltage (both channels)
- } else if (9 == i) {
- Ade7953.period = value; // Period
- } else if (10 == i) {
- acc_mode = value; // Accumulation mode
- } else {
- uint32_t reg_index = i >> 2; // 0 or 1
- reg[(ADE7953_SHELLY_25 == Ade7953.model) ? !reg_index : reg_index][i &3] = value; // IRMS, WATT, VA, VAR
+ uint32_t acc_mode = 0;
+ int32_t reg[2][ADE7953_REGISTERS];
+
+#ifdef USE_ESP32_SPI
+ if (Ade7953.pin_cs[0] >= 0) {
+ for (uint32_t chip = 0; chip < 2; chip++) {
+ if (Ade7953.pin_cs[chip] < 0) { continue; }
+ Ade7953.cs_index = chip;
+ for (uint32_t i = 0; i < ADE7953_REGISTERS; i++) {
+ reg[chip][i] = Ade7953Read(Ade7953Registers[0][i]); // IRMS, WATT, VA, VAR, VRMS, Period
+ }
}
+ } else {
+#endif // USE_ESP32_SPI
+ for (uint32_t channel = 0; channel < 2; channel++) {
+ uint32_t channel_swap = (ADE7953_SHELLY_25 == Ade7953.model) ? !channel : channel;
+ for (uint32_t i = 0; i < ADE7953_REGISTERS; i++) {
+ reg[channel_swap][i] = Ade7953Read(Ade7953Registers[channel][i]);
+ }
+ }
+ acc_mode = Ade7953Read(ADE7953_ACCMODE); // Accumulation mode
+#ifdef USE_ESP32_SPI
}
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: ACCMODE 0x%06X, VRMS %d, Period %d, IRMS %d, %d, WATT %d, %d, VA %d, %d, VAR %d, %d"),
- acc_mode, Ade7953.voltage_rms, Ade7953.period,
+#endif // USE_ESP32_SPI
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: ACCMODE 0x%06X, VRMS %d, %d, Period %d, %d, IRMS %d, %d, WATT %d, %d, VA %d, %d, VAR %d, %d"),
+ acc_mode, reg[0][4], reg[1][4], reg[0][5], reg[1][5],
reg[0][0], reg[1][0], reg[0][1], reg[1][1], reg[0][2], reg[1][2], reg[0][3], reg[1][3]);
uint32_t apparent_power[2] = { 0, 0 };
uint32_t reactive_power[2] = { 0, 0 };
for (uint32_t channel = 0; channel < 2; channel++) {
+ Ade7953.voltage_rms[channel] = reg[channel][4];
Ade7953.current_rms[channel] = reg[channel][0];
- if (Ade7953.current_rms[channel] < 2000) { // No load threshold (20mA)
+ if (Ade7953.current_rms[channel] < 2000) { // No load threshold (20mA)
Ade7953.current_rms[channel] = 0;
Ade7953.active_power[channel] = 0;
} else {
@@ -385,41 +458,37 @@ void Ade7953GetData(void) {
}
}
- if (Energy.power_on) { // Powered on
- float divider = (Ade7953.calib_data[ADE7953_CAL_AVGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
- Energy.voltage[0] = (float)Ade7953.voltage_rms / divider;
- Energy.frequency[0] = 223750.0f / ((float)Ade7953.period + 1);
-
+ if (Energy.power_on) { // Powered on
+ float divider;
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
- divider = (Ade7953.calib_data[ADE7953_CAL_AWGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+
+ Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
+ Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
- divider = (Ade7953.calib_data[ADE7953_CAL_AVARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
if (ADE7953_SHELLY_EM == Ade7953.model) {
- if (bitRead(acc_mode, 10 +channel)) { // APSIGN
+ if (bitRead(acc_mode, 10 +channel)) { // APSIGN
Energy.active_power[channel] *= -1;
}
- if (bitRead(acc_mode, 12 +channel)) { // VARSIGN
+ if (bitRead(acc_mode, 12 +channel)) { // VARSIGN
Energy.reactive_power[channel] *= -1;
}
}
- divider = (Ade7953.calib_data[ADE7953_CAL_AVAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- divider = (Ade7953.calib_data[ADE7953_CAL_AIGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider;
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
}
}
EnergyUpdateToday();
-/*
- } else { // Powered off
- Energy.data_valid[0] = ENERGY_WATCHDOG;
- Energy.data_valid[1] = ENERGY_WATCHDOG;
-*/
}
}
@@ -439,11 +508,12 @@ void Ade7953EnergyEverySecond(void) {
bool Ade7953SetDefaults(const char* json) {
// {"angles":{"angle0":180,"angle1":176}}
// {"rms":{"current_a":4194303,"current_b":4194303,"voltage":1613194},"angles":{"angle0":0,"angle1":0},"powers":{"totactive":{"a":2723574,"b":2723574},"apparent":{"a":2723574,"b":2723574},"reactive":{"a":2723574,"b":2723574}}}
+ // {"rms":{"current_a":21865738,"current_b":1558533,"voltage_a":1599149,"voltage_b":1597289},"angles":{"angle0":0,"angle1":0},"powers":{"totactive":{"a":106692616,"b":3540894}}}
uint32_t len = strlen(json) +1;
- if (len < 7) { return false; } // Too short
+ if (len < 7) { return false; } // Too short
char json_buffer[len];
- memcpy(json_buffer, json, len); // Keep original safe
+ memcpy(json_buffer, json, len); // Keep original safe
JsonParser parser(json_buffer);
JsonParserObject root = parser.getRootObject();
if (!root) {
@@ -457,57 +527,64 @@ bool Ade7953SetDefaults(const char* json) {
if (rms) {
val = rms[PSTR("voltage")];
if (val) {
- Ade7953.calib_data[ADE7953_CAL_AVGAIN] = val.getInt();
- Ade7953.calib_data[ADE7953_CAL_BVGAIN] = Ade7953.calib_data[ADE7953_CAL_AVGAIN];
+ Ade7953.calib_data[0][ADE7953_CAL_VGAIN] = val.getInt();
+ Ade7953.calib_data[1][ADE7953_CAL_VGAIN] = Ade7953.calib_data[0][ADE7953_CAL_VGAIN];
}
+#ifdef USE_ESP32_SPI
+ val = rms[PSTR("voltage_a")];
+ if (val) { Ade7953.calib_data[0][ADE7953_CAL_VGAIN] = val.getInt(); }
+ val = rms[PSTR("voltage_b")];
+ if (val) { Ade7953.calib_data[1][ADE7953_CAL_VGAIN] = val.getInt(); }
+#endif // USE_ESP32_SPI
val = rms[PSTR("current_a")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_AIGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[0][ADE7953_CAL_IGAIN] = val.getInt(); }
val = rms[PSTR("current_b")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_BIGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[1][ADE7953_CAL_IGAIN] = val.getInt(); }
}
JsonParserObject angles = root[PSTR("angles")].getObject();
if (angles) {
val = angles[PSTR("angle0")];
- if (val) { Ade7953.calib_data[ADE7943_CAL_PHCALA] = val.getInt(); }
+ if (val) { Ade7953.calib_data[0][ADE7943_CAL_PHCAL] = val.getInt(); }
val = angles[PSTR("angle1")];
- if (val) { Ade7953.calib_data[ADE7943_CAL_PHCALB] = val.getInt(); }
+ if (val) { Ade7953.calib_data[1][ADE7943_CAL_PHCAL] = val.getInt(); }
}
JsonParserObject powers = root[PSTR("powers")].getObject();
if (powers) {
JsonParserObject totactive = powers[PSTR("totactive")].getObject();
if (totactive) {
val = totactive[PSTR("a")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_AWGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[0][ADE7953_CAL_WGAIN] = val.getInt(); }
val = totactive[PSTR("b")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_BWGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[1][ADE7953_CAL_WGAIN] = val.getInt(); }
}
JsonParserObject apparent = powers[PSTR("apparent")].getObject();
if (apparent) {
val = apparent[PSTR("a")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_AVAGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[0][ADE7953_CAL_VAGAIN] = val.getInt(); }
val = apparent[PSTR("b")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_BVAGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[1][ADE7953_CAL_VAGAIN] = val.getInt(); }
}
JsonParserObject reactive = powers[PSTR("reactive")].getObject();
if (reactive) {
val = reactive[PSTR("a")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_AVARGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[0][ADE7953_CAL_VARGAIN] = val.getInt(); }
val = reactive[PSTR("b")];
- if (val) { Ade7953.calib_data[ADE7953_CAL_BVARGAIN] = val.getInt(); }
+ if (val) { Ade7953.calib_data[1][ADE7953_CAL_VARGAIN] = val.getInt(); }
}
}
return true;
}
void Ade7953Defaults(void) {
- for (uint32_t i = 0; i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t); i++) {
- if (i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t) -2) {
- Ade7953.calib_data[i] = ADE7953_GAIN_DEFAULT;
- } else {
- Ade7953.calib_data[i] = (ADE7953_SHELLY_EM == Ade7953.model) ? ADE7953_PHCAL_DEFAULT_CT : ADE7953_PHCAL_DEFAULT;
+ for (uint32_t channel = 0; channel < 2; channel++) {
+ for (uint32_t i = 0; i < ADE7953_CALIBREGS; i++) {
+ if (ADE7943_CAL_PHCAL == i) {
+ Ade7953.calib_data[channel][i] = (ADE7953_SHELLY_EM == Ade7953.model) ? ADE7953_PHCAL_DEFAULT_CT : ADE7953_PHCAL_DEFAULT;
+ } else {
+ Ade7953.calib_data[channel][i] = ADE7953_GAIN_DEFAULT;
+ }
}
}
-
#ifdef USE_RULES
// rule3 on file#calib.dat do {"angles":{"angle0":180,"angle1":176}} endon
String calib = RuleLoadFile("CALIB.DAT");
@@ -519,12 +596,13 @@ void Ade7953Defaults(void) {
}
void Ade7953DrvInit(void) {
- if (PinUsed(GPIO_ADE7953_IRQ, GPIO_ANY)) { // Irq on GPIO16 is not supported...
+ if (PinUsed(GPIO_ADE7953_IRQ, GPIO_ANY)) { // Irq is not supported...
uint32_t pin_irq = Pin(GPIO_ADE7953_IRQ, GPIO_ANY);
- pinMode(pin_irq, INPUT); // Related to resetPins() - Must be set to input
- Ade7953.model = GetPin(pin_irq) - AGPIO(GPIO_ADE7953_IRQ); // 0 (1 = Shelly 2.5), 1 (2 = Shelly EM), 2 (3 = Shelly Plus 2PM)
+ pinMode(pin_irq, INPUT); // Related to resetPins() - Must be set to input
+ // 0 (1 = Shelly 2.5), 1 (2 = Shelly EM), 2 (3 = Shelly Plus 2PM), 3 (4 = Shelly Pro 1PM), 4 (5 = Shelly Pro 2PM)
+ Ade7953.model = GetPin(pin_irq) - AGPIO(GPIO_ADE7953_IRQ);
- int pin_reset = Pin(GPIO_ADE7953_RST); // -1 if not defined
+ int pin_reset = Pin(GPIO_ADE7953_RST); // -1 if not defined
#ifdef ESP8266
if (ADE7953_SHELLY_EM == Ade7953.model) {
if (-1 == pin_reset) {
@@ -532,35 +610,77 @@ void Ade7953DrvInit(void) {
}
}
#endif
- if (pin_reset > -1) {
- pinMode(pin_reset, OUTPUT); // Reset pin ADE7953
+ if (pin_reset >= 0) {
digitalWrite(pin_reset, 0);
- delay(1);
+ pinMode(pin_reset, OUTPUT); // Reset pin ADE7953
+ delay(1); // To initiate a hardware reset, this pin must be brought low for a minimum of 10 μs.
digitalWrite(pin_reset, 1);
- pinMode(pin_reset, INPUT);
+ if (Ade7953.model < ADE7953_SHELLY_PRO_1PM) {
+ pinMode(pin_reset, INPUT);
+ }
}
+ delay(100); // Need 100mS to init ADE7953
- delay(100); // Need 100mS to init ADE7953
- if (I2cSetDevice(ADE7953_ADDR)) {
- if (HLW_PREF_PULSE == Settings->energy_power_calibration) {
- Settings->energy_power_calibration = ADE7953_PREF;
- Settings->energy_voltage_calibration = ADE7953_UREF;
- Settings->energy_current_calibration = ADE7953_IREF;
+#ifdef USE_ESP32_SPI
+ Ade7953.pin_cs[0] = -1;
+ Ade7953.pin_cs[1] = -1;
+ if (Ade7953.model >= ADE7953_SHELLY_PRO_1PM) { // SPI
+ if (PinUsed(GPIO_ADE7953_CS)) { // ADE7953 CS1 enabled (Pro 1PM/2PM)
+ Ade7953.pin_cs[0] = Pin(GPIO_ADE7953_CS);
+ digitalWrite(Ade7953.pin_cs[0], 1); // ADE7953 CS1 enabled (Pro 2PM)
+ pinMode(Ade7953.pin_cs[0], OUTPUT);
+ Ade7953.pin_cs[1] = Pin(GPIO_ADE7953_CS, 1);
+ if (Ade7953.pin_cs[1] > -1) { // ADE7953 CS2 enabled (Pro 2PM)
+ digitalWrite(Ade7953.pin_cs[1], 1);
+ pinMode(Ade7953.pin_cs[1], OUTPUT);
+ } else {
+ Ade7953.model = ADE7953_SHELLY_PRO_1PM;
+ }
+ Ade7953.cs_index = 0;
+ SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
+ Ade7953.spi_settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); // Set up SPI at 1MHz, MSB first, Capture at rising edge
+ AddLog(LOG_LEVEL_INFO, PSTR("SPI: ADE7953 found"));
+ } else {
+ return; // No CS pin defined
+ }
+ } else {
+#endif // USE_ESP32_SPI
+ if (!I2cSetDevice(ADE7953_ADDR)) {
+ return;
}
I2cSetActiveFound(ADE7953_ADDR, "ADE7953");
-
- Ade7953Defaults();
-
- Ade7953.init_step = 2;
- Energy.phase_count = 2; // Handle two channels as two phases
- Energy.voltage_common = true; // Use common voltage
- Energy.frequency_common = true; // Use common frequency
- Energy.use_overtemp = true; // Use global temperature for overtemp detection
- if (ADE7953_SHELLY_EM == Ade7953.model) {
- Energy.local_energy_active_export = true;
- }
- TasmotaGlobal.energy_driver = XNRG_07;
+#ifdef USE_ESP32_SPI
}
+#endif // USE_ESP32_SPI
+
+ if (HLW_PREF_PULSE == Settings->energy_power_calibration) {
+ Settings->energy_power_calibration = ADE7953_PREF;
+ Settings->energy_voltage_calibration = ADE7953_UREF;
+ Settings->energy_current_calibration = ADE7953_IREF;
+ }
+
+ Ade7953Defaults();
+
+ Ade7953.init_step = 2;
+
+// Energy.phase_count = 1;
+// Energy.voltage_common = false;
+// Energy.frequency_common = false;
+// Energy.use_overtemp = false;
+ if (ADE7953_SHELLY_PRO_1PM == Ade7953.model) {
+ } else {
+ Energy.phase_count = 2; // Handle two channels as two phases
+ if (ADE7953_SHELLY_PRO_2PM == Ade7953.model) {
+ } else {
+ Energy.voltage_common = true; // Use common voltage
+ Energy.frequency_common = true; // Use common frequency
+ }
+ }
+ Energy.use_overtemp = true; // Use global temperature for overtemp detection
+ if (ADE7953_SHELLY_EM == Ade7953.model) {
+ Energy.local_energy_active_export = true;
+ }
+ TasmotaGlobal.energy_driver = XNRG_07;
}
}
@@ -584,26 +704,26 @@ bool Ade7953Command(void) {
}
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
- if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
+ if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
Settings->energy_power_calibration = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
- if (XdrvMailbox.data_len && Ade7953.voltage_rms) {
- if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = (Ade7953.voltage_rms * 100) / value; // 0.00 V
+ if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) {
+ if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
+ Settings->energy_voltage_calibration = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.current_rms[channel]) {
- if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A
+ if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A
Settings->energy_current_calibration = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
}
}
}
- else serviced = false; // Unknown command
+ else serviced = false; // Unknown command
return serviced;
}
@@ -613,7 +733,7 @@ bool Ade7953Command(void) {
\*********************************************************************************************/
bool Xnrg07(uint8_t function) {
- if (!I2cEnabled(XI2C_07)) { return false; }
+ if (!I2cEnabled(XI2C_07) && (SPI_MOSI_MISO != TasmotaGlobal.spi_enabled)) { return false; }
bool result = false;
@@ -633,4 +753,4 @@ bool Xnrg07(uint8_t function) {
#endif // USE_ADE7953
#endif // USE_ENERGY_SENSOR
-#endif // USE_I2C
+#endif // USE_I2C or USE_ESP_SPI
From cef18060a0c541973f6104758b6c71930b651300 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 26 Oct 2022 17:59:43 +0200
Subject: [PATCH 075/319] Bump version to v12.2.0.2
Prepare for extended calibration and move some persistent data (PowerLow)
---
CHANGELOG.md | 18 +++++++++++++-----
RELEASENOTES.md | 2 +-
tasmota/include/tasmota_types.h | 15 ++++++++-------
tasmota/include/tasmota_version.h | 2 +-
tasmota/tasmota_support/settings.ino | 18 ++++++++++++++----
5 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b563d0683..637f44d9d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [12.2.0.1]
+## [12.2.0.2]
+### Added
+
+### Breaking Changed
+
+### Changed
+- Prepare for extended calibration and move some persistent data (PowerLow)
+
+### Fixed
+
+### Removed
+
+## [12.2.0.1] 20221026
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
- Berry add `bytes().setbytes()` (#16892)
@@ -11,8 +23,6 @@ All notable changes to this project will be documented in this file.
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
- Prepare for DMX Artnet support on ESP32
-### Breaking Changed
-
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
- Compiling with reduced boards manifests in favour of Autoconfig (#16848)
@@ -22,8 +32,6 @@ All notable changes to this project will be documented in this file.
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
-### Removed
-
## [Released]
## [12.2.0] 20221017
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 2286b8edb..a56da4e9f 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -107,7 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v12.2.0.1
+## Changelog v12.2.0.2
### Added
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index e1964b9e6..0fa7d6f69 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -268,7 +268,7 @@ typedef union {
uint32_t spare25 : 1; // bit 25
uint32_t spare26 : 1; // bit 26
uint32_t spare27 : 1; // bit 27
- uint32_t sunrise_dawn_angle : 2; // bits 28/29 (v12.1.1.4) -
+ uint32_t sunrise_dawn_angle : 2; // bits 28/29 (v12.1.1.4) -
uint32_t temperature_set_res : 2; // bits 30/31 (v9.3.1.4) - (Tuya)
};
} SysMBitfield2;
@@ -549,10 +549,9 @@ typedef struct {
uint32_t energy_power_calibration; // 364
uint32_t energy_voltage_calibration; // 368
uint32_t energy_current_calibration; // 36C
- uint32_t ex_energy_kWhtoday; // 370
- uint32_t ex_energy_kWhyesterday; // 374
- uint16_t energy_kWhdoy; // 378
- uint16_t energy_min_power; // 37A
+ uint32_t energy_power_calibration2; // 370 - ex_energy_kWhtoday
+ uint32_t energy_voltage_calibration2; // 374 - ex_energy_kWhyesterday
+ uint32_t energy_current_calibration2; // 378 - ex_energy_kWhdoy, ex_energy_min_power
uint16_t energy_max_power; // 37C
uint16_t energy_min_voltage; // 37E
uint16_t energy_max_voltage; // 380
@@ -573,8 +572,10 @@ typedef struct {
uint16_t blinkcount; // 39C
uint16_t light_rotation; // 39E
SOBitfield3 flag3; // 3A0
+ uint16_t energy_kWhdoy; // 3A4
+ uint16_t energy_min_power; // 3A6
- uint8_t ex_switchmode[8]; // 3A4 - Free since 9.2.0.6
+ uint8_t free_3A8[4]; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
#ifdef CONFIG_IDF_TARGET_ESP32S3
// ------------------------------------
@@ -836,7 +837,7 @@ typedef struct {
uint8_t free_f63[13]; // F63 - Decrement if adding new Setting variables just above and below
// Only 32 bit boundary variables below
- uint32_t touch_threshold; // F70
+ uint32_t touch_threshold; // F70
SOBitfield6 flag6; // F74
uint16_t flowratemeter_calibration[2];// F78
int32_t energy_kWhexport_ph[3]; // F7C
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index 992709ba0..6d24b16b5 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x0C020001; // 12.2.0.1
+const uint32_t VERSION = 0x0C020002; // 12.2.0.2
#endif // _TASMOTA_VERSION_H_
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index 5d0e8c6d7..bf1f9ba63 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -45,7 +45,7 @@ void RtcSettingsSave(void) {
if (RTC_MEM_VALID != RtcSettings.valid) {
memset(&RtcSettings, 0, sizeof(RtcSettings));
RtcSettings.valid = RTC_MEM_VALID;
-// RtcSettings.ex_energy_kWhtoday = Settings->ex_energy_kWhtoday;
+// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2;
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
for (uint32_t i = 0; i < 3; i++) {
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
@@ -1046,6 +1046,9 @@ void SettingsDefaultSet2(void) {
Settings->energy_power_calibration = HLW_PREF_PULSE;
Settings->energy_voltage_calibration = HLW_UREF_PULSE;
Settings->energy_current_calibration = HLW_IREF_PULSE;
+ Settings->energy_power_calibration2 = HLW_PREF_PULSE;
+ Settings->energy_voltage_calibration2 = HLW_UREF_PULSE;
+ Settings->energy_current_calibration2 = HLW_IREF_PULSE;
// Settings->energy_kWhtoday_ph[0] = 0;
// Settings->energy_kWhtoday_ph[1] = 0;
// Settings->energy_kWhtoday_ph[2] = 0;
@@ -1468,7 +1471,7 @@ void SettingsDelta(void) {
}
if (Settings->version < 0x09020006) {
for (uint32_t i = 0; i < MAX_SWITCHES_SET; i++) {
- Settings->switchmode[i] = (i < 8) ? Settings->ex_switchmode[i] : SWITCH_MODE;
+ Settings->switchmode[i] = SWITCH_MODE;
}
for (uint32_t i = 0; i < MAX_INTERLOCKS_SET; i++) {
Settings->interlock[i] = (i < 4) ? Settings->ds3502_state[i] : 0;
@@ -1532,8 +1535,8 @@ void SettingsDelta(void) {
memset(&Settings->energy_kWhtoday_ph, 0, 36);
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
- Settings->energy_kWhtoday_ph[0] = Settings->ex_energy_kWhtoday;
- Settings->energy_kWhyesterday_ph[0] = Settings->ex_energy_kWhyesterday;
+ Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2;
+ Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2;
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
RtcSettings.energy_kWhtotal_ph[0] = RtcSettings.ex_energy_kWhtotal;
}
@@ -1598,6 +1601,13 @@ void SettingsDelta(void) {
Settings->webcam_clk = 20;
}
#endif // ESP32
+ if (Settings->version < 0x0C020002) { // 12.2.0.2
+ Settings->energy_kWhdoy = Settings->energy_current_calibration2 & 0xFFFF;
+ Settings->energy_min_power = (Settings->energy_current_calibration2 >> 16) & 0xFFFF;
+ Settings->energy_power_calibration2 = Settings->energy_power_calibration;
+ Settings->energy_voltage_calibration2 = Settings->energy_voltage_calibration;
+ Settings->energy_current_calibration2 = Settings->energy_current_calibration;
+ }
Settings->version = VERSION;
SettingsSave(1);
From 97230fe456ec1328cdca325b0e36c05a64a59118 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Wed, 26 Oct 2022 19:21:50 +0300
Subject: [PATCH 076/319] Removed the duplicated functionality
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 74 +++++--------------
1 file changed, 18 insertions(+), 56 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index c6823d259..3e8224d7a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -472,29 +472,6 @@ uint8_t ntag21x_probe (void) {
return result; //Return configuration page address
}
-bool ntag21x_read32(char *out, uint8_t out_len) {
-
- if (out_len<33) return false;
-
- Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
- Pn532.packetbuffer[1] = NTAG21X_CMD_FAST_READ;
- Pn532.packetbuffer[2] = 0x04; // first page
- Pn532.packetbuffer[3] = 0x0b; // last page
- if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
- return false;
- }
- if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<33){
- return false;
- }
-
- if (Pn532.packetbuffer[0]!=0) {
- return false;
- }
- memcpy(out,&Pn532.packetbuffer[1],out_len);
- out[32]=0;
- return true;
-}
-
bool ntag21x_auth(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH;
@@ -512,41 +489,26 @@ bool ntag21x_auth(void) {
return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0;
}
-bool ntag20x_read32(char *out, uint8_t out_len) {
+bool ntag2xx_read32(char *out, uint8_t out_len) {
if (out_len<33) return false;
+ for (uint8_t i = 0; i < 2; i++) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
+ Pn532.packetbuffer[1] = NTAG21X_CMD_READ;
+ Pn532.packetbuffer[2] = 0x04 << i; // first page
- Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
- Pn532.packetbuffer[1] = NTAG21X_CMD_READ;
- Pn532.packetbuffer[2] = 0x04; // first page
-
- if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
- return false;
+ if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
+ return false;
+ }
+ if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
+ return false;
+ }
+ if (Pn532.packetbuffer[0]!=0) {
+ return false;
+ }
+ memcpy(&out[i<<4],&Pn532.packetbuffer[1],16);
}
- if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
- return false;
- }
- if (Pn532.packetbuffer[0]!=0) {
- return false;
- }
- memcpy(out,&Pn532.packetbuffer[1],16);
-
- Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
- Pn532.packetbuffer[1] = NTAG21X_CMD_READ;
- Pn532.packetbuffer[2] = 0x08; // first page
-
- if (PN532_writeCommand(Pn532.packetbuffer, 3)) {
- return false;
- }
- if ((PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)))<17){
- return false;
- }
- if (Pn532.packetbuffer[0]!=0) {
- return false;
- }
- memcpy(&out[16],&Pn532.packetbuffer[1],16);
out[32]=0;
-
return true;
}
@@ -570,11 +532,11 @@ void PN532_ScanForTag(void) {
if ((confPage=ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag21x_read32(card_datas, sizeof(card_datas))) {
+ if (!ntag2xx_read32(card_datas, sizeof(card_datas))) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
- if (!ntag21x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
if (Pn532.command == 1) {
/* Erase */
} else
@@ -588,7 +550,7 @@ void PN532_ScanForTag(void) {
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag20x_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
}
}
}
From cc7936bd7e90b0df19013fae1963baedb03f726c Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Thu, 27 Oct 2022 00:48:22 +0300
Subject: [PATCH 077/319] Add password operations
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 197 ++++++++++++------
1 file changed, 134 insertions(+), 63 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 3e8224d7a..639a3a8c8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -60,9 +60,10 @@ TasmotaSerial *PN532_Serial;
#define MIFARE_CMD_WRITE 0xA0
#define NTAG21X_CMD_GET_VERSION 0x60
-#define NTAG21X_CMD_READ 0x30
+#define NTAG2XX_CMD_READ 0x30
#define NTAG21X_CMD_FAST_READ 0x3A
#define NTAG21X_CMD_PWD_AUTH 0x1B
+#define NTAG2XX_CMD_WRITE 0xA2
const struct {
uint8_t version[6];
@@ -344,15 +345,14 @@ void PN532_inRelease(void) {
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
}
-void PN532_inSelect(void) {
+/* void PN532_inSelect(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
Pn532.packetbuffer[1] = 1;
if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
return ;
}
int16_t res = PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: Select %d %x"), res, Pn532.packetbuffer[0]);
-}
+} */
#ifdef USE_PN532_DATA_FUNCTION
@@ -435,7 +435,7 @@ bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
return false;
}
/* Read the response packet */
- if (0 >= PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer))) {
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
return false;
}
}
@@ -456,23 +456,20 @@ uint8_t ntag21x_probe (void) {
return result;
}
-/* AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NFC: NTAG Version %02x %02x %02x %02x %02x %02x %02x %02x %02x"),
- Pn532.packetbuffer[0],Pn532.packetbuffer[1],Pn532.packetbuffer[2],Pn532.packetbuffer[3],
- Pn532.packetbuffer[4],Pn532.packetbuffer[5],Pn532.packetbuffer[6],Pn532.packetbuffer[7],
- Pn532.packetbuffer[8]);
- */
if (Pn532.packetbuffer[3] != 4) { // not NTAG type
return result;
}
for (uint8_t i=0; i= 33 */
+
+ if (!ntag2xx_read16(page, out)) {
+ return false;
+ }
+ if (!ntag2xx_read16(page + 4, &out[16])) {
+ return false;
}
out[32]=0;
return true;
}
+bool ntag2xx_write4(uint8_t page, char *in) {
+
+ Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
+ Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE;
+ Pn532.packetbuffer[2] = page; // first page
+ memcpy(&Pn532.packetbuffer[3],in,4);
+
+ if (PN532_writeCommand(Pn532.packetbuffer, 7)) {
+ return false;
+ }
+
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
+ return false;
+ }
+ return true;
+}
+
+bool ntag2xx_writeN(uint8_t page, uint8_t numPages, char *in) {
+
+ for (uint8_t i = 0; i < numPages; i++) {
+ if (!ntag2xx_write4(page +i, &in[i << 2])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
+ char card_datas[16];
+
+ if (ntag2xx_read16(confPage, card_datas)) {
+ if (unsetPasswd) {
+ card_datas[3]=0xFF;
+ return ntag2xx_writeN(confPage,1,card_datas);
+ }
+ card_datas[3]=0; // Set AUTH0 for protect all pages
+ card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
+ memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
+ memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
+ return ntag2xx_writeN(confPage,4,card_datas);
+ }
+ return false;
+}
+
#endif // USE_PN532_DATA_FUNCTION
void PN532_ScanForTag(void) {
@@ -532,42 +580,45 @@ void PN532_ScanForTag(void) {
if ((confPage=ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag2xx_read32(card_datas, sizeof(card_datas))) {
+ if (!ntag2xx_read32(4, card_datas)) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (ntag21x_auth()) {str_pwd=PWD_OK;} else {str_pwd=PWD_NOK;}
- if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
- if (Pn532.command == 1) {
- /* Erase */
- } else
- if (Pn532.command == 2) {
- /* Write */
+ if (ntag21x_auth()) {
+ str_pwd=PWD_OK;
+ if (Pn532.function == 3) { /* new password */
+ success = ntag21x_set_password(confPage, false);
+ }
+ if (Pn532.function == 4) { /* clear password */
+ success = ntag21x_set_password(confPage, true);
+ }
+ } else {
+ str_pwd=PWD_NOK;
}
+ if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
}
}
- }
-
+ } else {
+ if (Pn532.function == 3) { /* new password */
+ success = ntag21x_set_password(confPage, false);
+ }
+ }
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag2xx_read32(card_datas, sizeof(card_datas))) card_datas[0]=0;
+ if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
}
}
}
- } else
- if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
+ if ((Pn532.function == 1) || (Pn532.function == 2)) {
+ success = ntag2xx_writeN(4, 8, (char *)Pn532.newdata);
+ if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ }
+ }
+ else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
- if (Pn532.function == 1) { // erase blocks 1 & 2 of card
- memset(card_datas,0,sizeof(card_datas));
- if ((success=mifareclassic_WriteDataBlock(1, (uint8_t *)card_datas))) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase success"));
- }
- } else
- if (Pn532.function == 2) {
- if ((success=mifareclassic_WriteDataBlock(1, Pn532.newdata))) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Data write successful"));
- }
+ if ((Pn532.function == 1) || (Pn532.function == 2)) {
+ success=mifareclassic_WriteDataBlock(1, Pn532.newdata);
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
for (uint32_t i = 0; i < 32;i++) {
@@ -586,14 +637,33 @@ void PN532_ScanForTag(void) {
}
switch (Pn532.function) {
case 0x01:
- if (!success) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Erase fail - exiting erase mode"));
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase success"));
+ } else {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Erase fail - exiting erase mode"));
}
break;
case 0x02:
- if (!success) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Write failed - exiting set mode"));
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Data write successful"));
+ } else{
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Write failed - exiting set mode"));
}
+ break;
+ case 0x03:
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password successful"));
+ } else{
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Set password failed - exiting set mode"));
+ }
+ break;
+ case 0x04:
+ if (success) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password successful"));
+ } else{
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Unset password failed - exiting set mode"));
+ }
+ break;
default:
break;
}
@@ -634,8 +704,9 @@ bool PN532_Command(void) {
ArgV(argument, 1);
UpperCase(argument,argument);
if (!strncmp_P(argument,PSTR("ERASE"),5)) {
+ memset(Pn532.newdata,0,sizeof(Pn532.newdata));
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be erased"));
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be erased"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
return serviced;
} else
@@ -649,7 +720,7 @@ bool PN532_Command(void) {
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
if (strlen(argument)>32) argument[32]=0;
Pn532.function = 2;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 NFC - Next scanned tag data block 1 will be set to '%s'"), argument);
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be set to '%s'"), argument);
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}"));
return serviced;
}
@@ -657,16 +728,15 @@ bool PN532_Command(void) {
if (!strncmp_P(argument,PSTR("AUTH"),4)) {
if (ArgC() > 1) {
Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
- AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_auth);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"NTAG_PWD\"}}"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"AUTH\"}}"));
}
if (ArgC() > 2) {
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
- AddLog(LOG_LEVEL_DEBUG, PSTR("%08x"), Pn532.pwd_pack);
}
return true;
} else
if (!strncmp_P(argument,PSTR("SET_PWD"),7)) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will set password"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}"));
Pn532.pwd_auth_new=Pn532.pwd_auth;
Pn532.pwd_pack_new=Pn532.pwd_pack;
@@ -680,8 +750,9 @@ bool PN532_Command(void) {
return true;
} else
if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) {
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
- Pn532.function = 4;
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will unset password"));
+ ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
+ Pn532.function = 4;
return true;
}
return false;
From 09b02b3325a00f7a3b49153a48423f8051cafe87 Mon Sep 17 00:00:00 2001
From: Charles
Date: Thu, 27 Oct 2022 14:16:37 +0200
Subject: [PATCH 078/319] standard mode bug fixes
Increase serial buffer size for standard mode
trimmed values for standard mode
fix (hopefully) negative total kWh counter
save energy on reset
update energy total every hour
fixed contract label display for Standard mode
---
.../tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 80 ++++++++++++++-----
1 file changed, 60 insertions(+), 20 deletions(-)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
index 04afe6af4..a17361047 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
@@ -152,7 +152,7 @@ PROGMEM
"|"
;
-#define TELEINFO_SERIAL_BUFFER_STANDARD 512 // Receive buffer size for Standard mode
+#define TELEINFO_SERIAL_BUFFER_STANDARD 1536 // Receive buffer size for Standard mode
#define TELEINFO_SERIAL_BUFFER_HISTORIQUE 512 // Receive buffer size for Legacy mode
#define TELEINFO_PROCESS_BUFFER 32 // Local processing buffer
@@ -163,6 +163,7 @@ uint8_t tic_rx_pin = NOT_A_PIN;
char serialNumber[13] = ""; // Serial number is 12 char long
bool tinfo_found = false;
int serial_buffer_size;
+uint32_t total_wh;
int contrat;
int tarif;
int isousc;
@@ -183,7 +184,12 @@ char * getValueFromLabelIndex(int labelIndex, char * value)
// Get the label name
GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel);
// Get value of label name
- return tinfo.valueGet(labelName, value) ;
+ tinfo.valueGet(labelName, value) ;
+ // Standard mode has values with space before/after
+ if (tinfo_mode==TINFO_MODE_STANDARD) {
+ Trim(value);
+ }
+ return value;
}
/* ======================================================================
@@ -329,12 +335,11 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
char value[32];
uint32_t hc = 0;
uint32_t hp = 0;
- uint32_t total = 0;
// Base, un seul index
if (ilabel == LABEL_BASE) {
- total = atol(me->value);
- AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Base:%ld"), total);
+ total_wh = atol(me->value);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Base:%ld"), total_wh);
// Heures creuses/pleines calculer total
} else {
// Heures creuses get heures pleines
@@ -352,15 +357,17 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
}
}
if (hc>0 && hp>0) {
- total = hc + hp;
+ total_wh = hc + hp;
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%ld HP:%ld Total:%ld"), hc, hp, total_wh);
}
- AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %ld Wh"), total);
- if (total>0) {
- Energy.import_active[0] = (float)total/1000.0f;
- EnergyUpdateTotal();
+ AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %ld Wh"), total_wh);
+ if (total_wh>0) {
+ Energy.total[0] = (float) total_wh / 1000.0f;
+ Energy.import_active[0] = Energy.total[0];
+ //Energy.import_active[0] = (float)total/1000.0f;
+ //EnergyUpdateTotal();
AddLog (LOG_LEVEL_DEBUG_MORE, PSTR ("TIC: import_active[0]=%.3fKWh"), Energy.import_active[0] );
}
}
@@ -368,10 +375,10 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
// Wh total index (all contract)
else if ( ilabel == LABEL_EAST)
{
- uint32_t total = atol(me->value);
- Energy.import_active[0] = (float)total/1000.0f;
- EnergyUpdateTotal();
- AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%ldWh"), total);
+ total_wh = atol(me->value);
+ Energy.total[0] = (float) total_wh / 1000.0f;
+ Energy.import_active[0] = Energy.total[0];
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Total:%ldWh"), total_wh);
}
// Wh indexes (standard)
@@ -538,7 +545,7 @@ void NewFrameCallback(struct _ValueList * me)
Energy.data_valid[0] = 0;
// Deprecated see setOption108
- // send teleinfo raw data only if setup like that
+ // send teleinfo MQTT raw data only if setup like that
if (Settings->teleinfo.raw_send) {
// Do we need to skip this frame
if (raw_skip == 0 ) {
@@ -578,6 +585,7 @@ void TInfoDrvInit(void) {
Energy.voltage_available = false;
Energy.phase_count = 1;
// init hardware energy counters
+ total_wh = 0;
Settings->flag3.hardware_energy_total = true;
}
}
@@ -673,6 +681,25 @@ void TInfoInit(void)
}
}
+//
+/* ======================================================================
+Function: TInfoSaveBeforeRestart
+Purpose : Save data before ESP restart
+Input : -
+Output : -
+Comments: -
+====================================================================== */
+void TInfoSaveBeforeRestart()
+{
+ // if teleinfo enabled, set it low
+ if (PinUsed (GPIO_TELEINFO_ENABLE)) {
+ digitalWrite( Pin(GPIO_TELEINFO_ENABLE), LOW);
+ }
+
+ // update energy total (in kwh)
+ EnergyUpdateTotal();
+
+}
/* ======================================================================
Function: TInfoCmd
@@ -842,6 +869,7 @@ Comments: -
void TInfoProcess(void)
{
static char buff[TELEINFO_PROCESS_BUFFER];
+ static uint32_t tick_update = 0;
#ifdef MEASURE_PERF
static unsigned long max_time = 0;
unsigned long duration = millis();
@@ -872,6 +900,14 @@ void TInfoProcess(void)
if (duration > max_time) { max_time = duration; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_time=%lu"), max_time); }
if (tmp_size > max_size) { max_size = tmp_size; AddLog(LOG_LEVEL_INFO,PSTR("TIC: max_size=%d"), max_size); }
#endif
+
+ // if needed, update energy total every hour
+ if (tick_update++ > 3600 * 4) {
+ EnergyUpdateTotal();
+ AddLog (LOG_LEVEL_INFO, PSTR ("TIC: Total counter updated to %lu Wh"), total_wh);
+ tick_update = 0;
+ }
+
}
/* ======================================================================
@@ -886,7 +922,8 @@ const char HTTP_ENERGY_ID_TELEINFO[] PROGMEM = "{s}ID{m}%s{e}" ;
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
//const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "%s{m}%d " D_UNIT_AMPERE "{e}" ;
-const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s%s{e}" ;
+const char HTTP_ENERGY_TARIF_TELEINFO_STD[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s{e}" ;
+const char HTTP_ENERGY_TARIF_TELEINFO_HISTO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}Heures %s{e}" ;
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}" D_CONTRACT "{m}%s %d" D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}" D_POWER_LOAD "{m}%d" D_UNIT_PERCENT "{e}" ;
const char HTTP_ENERGY_IMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d" D_UNIT_AMPERE "{e}" ;
@@ -977,9 +1014,9 @@ void TInfoShow(bool json)
if (tarif) {
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
if (tinfo_mode==TINFO_MODE_STANDARD ) {
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "", name);
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, name);
} else {
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "Heures ", name);
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_HISTO, name);
}
}
if (contrat && isousc) {
@@ -1006,7 +1043,7 @@ void TInfoShow(bool json)
WSContentSend_P(HTTP_ENERGY_PMAX_TELEINFO, atoi(value));
}
if (getValueFromLabelIndex(LABEL_LTARF, value) ) {
- WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, value);
+ WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO_STD, value);
}
if (getValueFromLabelIndex(LABEL_NGTF, value) ) {
if (isousc) {
@@ -1035,6 +1072,9 @@ bool Xnrg15(uint8_t function)
case FUNC_INIT:
TInfoInit();
break;
+ case FUNC_SAVE_BEFORE_RESTART:
+ if (tinfo_found) { TInfoSaveBeforeRestart(); }
+ break;
case FUNC_PRE_INIT:
TInfoDrvInit();
break;
From 90a9ebc3e1cf9b31761e1272053a7ebf37f376ba Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 27 Oct 2022 17:52:44 +0200
Subject: [PATCH 079/319] Fix Shelly Pro ethernet stability
---
tasmota/tasmota.ino | 1 +
.../xdrv_88_esp32_shelly_pro.ino | 15 +++++++++++++++
tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino | 8 ++++----
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index d33d122f6..707f95771 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -559,6 +559,7 @@ void setup(void) {
bitWrite(Settings->rule_enabled, i, 0); // Disable rules causing boot loop
}
}
+ Settings->flag4.network_wifi = 1; // Enable wifi if disabled
}
if (RtcReboot.fast_reboot_count > Settings->param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times
Settings->rule_enabled = 0; // Disable all rules
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 486d79037..60f0f0a88 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -85,6 +85,18 @@ void ShellyProPreInit(void) {
}
}
+void ShellyProInit(void) {
+ int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
+// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
+ digitalWrite(pin_lan_reset, 0);
+ pinMode(pin_lan_reset, OUTPUT);
+ delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
+ digitalWrite(pin_lan_reset, 1);
+
+ AddLog(LOG_LEVEL_INFO, PSTR("HDW: Shelly Pro %d%s initialized"),
+ TasmotaGlobal.devices_present, (PinUsed(GPIO_ADE7953_CS))?"PM":"");
+}
+
void ShellyProPower(void) {
SPro.power = XdrvMailbox.index &3;
ShellyProUpdate();
@@ -147,6 +159,9 @@ bool Xdrv88(uint8_t function) {
case FUNC_LED_LINK:
ShellyProLedLink();
break;
+ case FUNC_INIT:
+ ShellyProInit();
+ break;
}
}
return result;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index fc8e3411e..49686aca8 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -370,8 +370,8 @@ void Ade7953Init(void) {
Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120
Ade7953Write(0x120, 0x0030); // Configure optimum setting
#ifdef USE_ESP32_SPI
- int32_t value = Ade7953Read(0x702); // Silicon version
- AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Chip%d version %d"), chip +1, value);
+// int32_t value = Ade7953Read(0x702); // Silicon version
+// AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Chip%d version %d"), chip +1, value);
#endif // USE_ESP32_SPI
}
@@ -645,8 +645,8 @@ void Ade7953DrvInit(void) {
}
} else {
#endif // USE_ESP32_SPI
- if (!I2cSetDevice(ADE7953_ADDR)) {
- return;
+ if (!I2cSetDevice(ADE7953_ADDR)) {
+ return;
}
I2cSetActiveFound(ADE7953_ADDR, "ADE7953");
#ifdef USE_ESP32_SPI
From b877c174b1fd5923041663ab91c9c87e55c1805a Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Thu, 27 Oct 2022 19:23:11 +0300
Subject: [PATCH 080/319] Ready fo test (32 bytes)
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 639a3a8c8..e55a9d94d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -83,8 +83,8 @@ struct PN532 {
uint8_t command = 0; // Carry command code between functions
uint8_t scantimer = 0; // Prevent multiple successful reads within 2 second window
bool present = false; // Maintain detection flag
-#ifdef USE_PN532_DATA_FUNCTION
uint16_t atqa;
+#ifdef USE_PN532_DATA_FUNCTION
uint8_t newdata[32];
uint8_t function = 0;
uint32_t pwd_auth=0x64636261;
@@ -336,15 +336,6 @@ bool PN532_SAMConfig(void) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
-void PN532_inRelease(void) {
- Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
- Pn532.packetbuffer[1] = 1;
- if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
- return;
- }
- PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
-}
-
/* void PN532_inSelect(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INSELECT;
Pn532.packetbuffer[1] = 1;
@@ -356,6 +347,15 @@ void PN532_inRelease(void) {
#ifdef USE_PN532_DATA_FUNCTION
+void PN532_inRelease(void) {
+ Pn532.packetbuffer[0] = PN532_COMMAND_INRELEASE;
+ Pn532.packetbuffer[1] = 1;
+ if (PN532_writeCommand(Pn532.packetbuffer, 2)) {
+ return;
+ }
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+}
+
uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
uint8_t i;
uint8_t _key[6];
@@ -679,12 +679,12 @@ void PN532_ScanForTag(void) {
ResponseAppend_P(PSTR(",\"Auth\":\"NOk\""));
}
ResponseAppend_P(PSTR("}}"));
+ PN532_inRelease();
#else
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\"}}"), Pn532.uids);
#endif // USE_PN532_DATA_FUNCTION
MqttPublishTeleSensor();
- PN532_inRelease();
Pn532.scantimer = 7; // Ignore tags found for two seconds
}
}
@@ -706,7 +706,7 @@ bool PN532_Command(void) {
if (!strncmp_P(argument,PSTR("ERASE"),5)) {
memset(Pn532.newdata,0,sizeof(Pn532.newdata));
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be erased"));
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block will be erased"));
ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
return serviced;
} else
From 3cccdd9c4f73ebdedd18bf28f0669147d78a87a3 Mon Sep 17 00:00:00 2001
From: barkow
Date: Thu, 27 Oct 2022 21:46:07 +0200
Subject: [PATCH 081/319] Change modbus rx message length check
Start evaluating messages already after message length information byte is received. Necessary to support read coil status messages.
---
tasmota/tasmota_xsns_sensor/xsns_53_sml.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
index 62e06f3ac..451044a8e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
@@ -1683,7 +1683,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
meter_spos[meters] = 0;
}
// modbus
- if (meter_spos[meters] >= 8) {
+ if (meter_spos[meters] >= 3) {
uint32_t mlen = smltbuf[meters][2] + 5;
if (mlen > SML_BSIZ) mlen = SML_BSIZ;
if (meter_spos[meters] >= mlen) {
From 116affb2fa8dd2cf928eb1a3069a40fe50843901 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:12:33 +0300
Subject: [PATCH 082/319] 16 bytes operational
---
tasmota/my_user_config.h | 4 +-
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 177 ++++++++----------
2 files changed, 82 insertions(+), 99 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 1838b9096..6bafe2c6a 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -776,8 +776,8 @@
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
-#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
- #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
+#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
+ #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index e55a9d94d..0819e2d4c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -16,8 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem)
- #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+1k7 code, 388 bytes mem)
#ifdef USE_PN532_HSU
/*********************************************************************************************\
@@ -85,7 +83,7 @@ struct PN532 {
bool present = false; // Maintain detection flag
uint16_t atqa;
#ifdef USE_PN532_DATA_FUNCTION
- uint8_t newdata[32];
+ uint8_t newdata[16];
uint8_t function = 0;
uint32_t pwd_auth=0x64636261;
uint16_t pwd_pack=0x6665;
@@ -395,50 +393,47 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the command */
- for (uint8_t i = 0; i < 2; i++) {
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
- Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
/* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
- return 0;
- }
-
- /* Read the response packet */
- PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
-
- /* If byte 8 isn't 0x00 we probably have an error */
- if (Pn532.packetbuffer[0] != 0x00) {
- return 0;
- }
-
- /* Copy the 16 data bytes to the output buffer */
- /* Block content starts at byte 9 of a valid response */
- memcpy (&data[i<<4], &Pn532.packetbuffer[1], 16);
+ if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
+ return 0;
}
+
+ /* Read the response packet */
+ PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
+
+ /* If byte 8 isn't 0x00 we probably have an error */
+ if (Pn532.packetbuffer[0] != 0x00) {
+ return 0;
+ }
+
+ /* Copy the 16 data bytes to the output buffer */
+ /* Block content starts at byte 9 of a valid response */
+ memcpy (data, &Pn532.packetbuffer[1], 16);
return 1;
}
bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
- for (uint8_t i = 0; i < 2; i++) {
- Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
- Pn532.packetbuffer[1] = 1; /* Card number */
- Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
- Pn532.packetbuffer[3] = blockNumber + i; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- memcpy(&Pn532.packetbuffer[4], &data[i<<4], 16); /* Data Payload */
+ Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+ Pn532.packetbuffer[1] = 1; /* Card number */
+ Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
/* Send the command */
- if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return false;
- }
- /* Read the response packet */
- if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
- return false;
- }
+ if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
+ return false;
}
+ /* Read the response packet */
+ if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
+ return false;
+ }
+
return true;
}
@@ -504,18 +499,6 @@ bool ntag2xx_read16 (const uint8_t page, char *out) {
return true;
}
-bool ntag2xx_read32 (const uint8_t page, char *out) { /* Size of oun must be >= 33 */
-
- if (!ntag2xx_read16(page, out)) {
- return false;
- }
- if (!ntag2xx_read16(page + 4, &out[16])) {
- return false;
- }
- out[32]=0;
- return true;
-}
-
bool ntag2xx_write4(uint8_t page, char *in) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
@@ -533,9 +516,9 @@ bool ntag2xx_write4(uint8_t page, char *in) {
return true;
}
-bool ntag2xx_writeN(uint8_t page, uint8_t numPages, char *in) {
+bool ntag2xx_write16(uint8_t page, char *in) {
- for (uint8_t i = 0; i < numPages; i++) {
+ for (uint8_t i = 0; i < 4; i++) {
if (!ntag2xx_write4(page +i, &in[i << 2])) {
return false;
}
@@ -549,13 +532,13 @@ bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
if (ntag2xx_read16(confPage, card_datas)) {
if (unsetPasswd) {
card_datas[3]=0xFF;
- return ntag2xx_writeN(confPage,1,card_datas);
+ return ntag2xx_write4(confPage, card_datas);
}
card_datas[3]=0; // Set AUTH0 for protect all pages
card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
- return ntag2xx_writeN(confPage,4,card_datas);
+ return ntag2xx_write16(confPage, card_datas);
}
return false;
}
@@ -570,7 +553,7 @@ void PN532_ScanForTag(void) {
#ifdef USE_PN532_DATA_FUNCTION
bool success = false;
- char card_datas[34]={0};
+ char card_datas[17]={0};
enum {NOPWD, PWD_NONE, PWD_OK, PWD_NOK} str_pwd=NOPWD;
if (Pn532.atqa == 0x44) {
@@ -580,7 +563,7 @@ void PN532_ScanForTag(void) {
if ((confPage=ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag2xx_read32(4, card_datas)) {
+ if (!ntag2xx_read16(4, card_datas)) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
if (ntag21x_auth()) {
@@ -594,7 +577,7 @@ void PN532_ScanForTag(void) {
} else {
str_pwd=PWD_NOK;
}
- if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
} else {
@@ -605,13 +588,13 @@ void PN532_ScanForTag(void) {
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
}
if ((Pn532.function == 1) || (Pn532.function == 2)) {
- success = ntag2xx_writeN(4, 8, (char *)Pn532.newdata);
- if (!ntag2xx_read32(4, card_datas)) card_datas[0]=0;
+ success = ntag2xx_write16(4, (char *)Pn532.newdata);
+ if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
@@ -621,13 +604,12 @@ void PN532_ScanForTag(void) {
success=mifareclassic_WriteDataBlock(1, Pn532.newdata);
}
if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
- for (uint32_t i = 0; i < 32;i++) {
+ for (uint32_t i = 0; i < 16; i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
card_datas[i] = 0;
}
}
- card_datas[32] = 0;
} else {
card_datas[0] = 0;
}
@@ -668,6 +650,7 @@ void PN532_ScanForTag(void) {
break;
}
Pn532.function = 0;
+ card_datas[16] = 0;
ResponseTime_P(PSTR(",\"PN532\":{\"UID\":\"%s\",\"" D_JSON_DATA "\":\"%s\""), Pn532.uids, card_datas);
if (str_pwd == PWD_NONE) {
ResponseAppend_P(PSTR(",\"Auth\":\"None\""));
@@ -692,52 +675,45 @@ void PN532_ScanForTag(void) {
#ifdef USE_PN532_DATA_FUNCTION
bool PN532_Command(void) {
- bool serviced = true;
- uint8_t paramcount = 0;
- if (XdrvMailbox.data_len > 0) {
- paramcount=1;
- } else {
- serviced = false;
+ bool serviced = false;
+ char command[10];
+ char log[70];
+ if (ArgC() < 1) {
return serviced;
}
+
char argument[XdrvMailbox.data_len];
ArgV(argument, 1);
- UpperCase(argument,argument);
- if (!strncmp_P(argument,PSTR("ERASE"),5)) {
+ strncpy(command,UpperCase(argument,argument),sizeof(command));
+
+ if (!strcmp_P(argument,PSTR("ERASE"))) {
memset(Pn532.newdata,0,sizeof(Pn532.newdata));
Pn532.function = 1; // Block 1 of next card/tag will be reset to 0x00...
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block will be erased"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"ERASE\"}}"));
- return serviced;
- } else
- if (!strncmp_P(argument,PSTR("WRITE"),5)) {
+ snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be erased"));
+ serviced = true;
+ }
+ if (!strcmp_P(argument,PSTR("WRITE"))) {
if (ArgC() > 1) {
- if (XdrvMailbox.data[XdrvMailbox.data_len-1] == ',') {
- serviced = false;
- return serviced;
- }
ArgV(argument, 2);
+ memset(Pn532.newdata,0,sizeof(Pn532.newdata));
strncpy((char *)Pn532.newdata,argument,sizeof(Pn532.newdata));
- if (strlen(argument)>32) argument[32]=0;
+ if (strlen(argument)>16) argument[16]=0;
Pn532.function = 2;
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag data block 1 will be set to '%s'"), argument);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"WRITE\"}}"));
- return serviced;
+ snprintf_P(log, sizeof(log), PSTR("data block 1 (4-7 for NTAG) will be set to '%s'"), argument);
+ serviced = true;
}
- } else
- if (!strncmp_P(argument,PSTR("AUTH"),4)) {
+ }
+ if (!strcmp_P(argument,PSTR("AUTH"))) {
if (ArgC() > 1) {
Pn532.pwd_auth=strtoul(ArgV(argument,2),nullptr,0);
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"AUTH\"}}"));
}
if (ArgC() > 2) {
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
}
- return true;
- } else
- if (!strncmp_P(argument,PSTR("SET_PWD"),7)) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will set password"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"SET_PWD\"}}"));
+ serviced = true;
+ }
+ if (!strcmp_P(argument,PSTR("SET_PWD"))) {
+ snprintf_P(log, sizeof(log), PSTR("will be protected"));
Pn532.pwd_auth_new=Pn532.pwd_auth;
Pn532.pwd_pack_new=Pn532.pwd_pack;
if (ArgC() > 1) {
@@ -747,15 +723,22 @@ bool PN532_Command(void) {
Pn532.pwd_pack_new=strtoul(ArgV(argument,3),nullptr,0);
}
Pn532.function = 3;
- return true;
- } else
- if (!strncmp_P(argument,PSTR("UNSET_PWD"),9)) {
- AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag will unset password"));
- ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"UNSET_PWD\"}}"));
- Pn532.function = 4;
- return true;
+ serviced = true;
}
- return false;
+ if (!strcmp_P(argument,PSTR("UNSET_PWD"))) {
+ snprintf_P(log, sizeof(log), PSTR("will be unprotected"));
+ Pn532.function = 4;
+ serviced = true;
+ }
+ if (!strcmp_P(argument,PSTR("CANCEL"))) {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Job canceled"));
+ Pn532.function = 0;
+ serviced = true;
+ } else {
+ AddLog(LOG_LEVEL_INFO, PSTR("NFC: PN532 - Next scanned tag %s"), log);
+ }
+ if (serviced) ResponseTime_P(PSTR(",\"PN532\":{\"COMMAND\":\"%s\"}}"),command);
+ return serviced;
}
#endif // USE_PN532_DATA_FUNCTION
From 0d22a162401a4c5bef51d11474844ea9dee1856e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:13:27 +0300
Subject: [PATCH 083/319] Disable in default config
---
tasmota/my_user_config.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 6bafe2c6a..858a3725e 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -776,8 +776,8 @@
#define MP3_VOLUME 30 // Set the startup volume on init, the range can be 0..100(max)
// #define USE_DY_SV17F // Use of DY-SV17F MP3 Player commands: play, stop, track and volume
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
-#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
- #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
+//#define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k7 code, 156 bytes mem)
+// #define USE_PN532_DATA_FUNCTION // Add sensor40 command support for erase, setting data block content (+3k code, 32 bytes mem)
//#define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8)
//#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module)
//#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM)
From d152199aee6a181305faffaefe483b5a9218fe6e Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:24:22 +0300
Subject: [PATCH 084/319] Edit formats
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 0819e2d4c..def685769 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -396,9 +396,9 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
Pn532.packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
- /* Send the command */
+ /* Send the command */
if (PN532_writeCommand(Pn532.packetbuffer, 4)) {
return 0;
}
@@ -414,27 +414,25 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Copy the 16 data bytes to the output buffer */
/* Block content starts at byte 9 of a valid response */
memcpy (data, &Pn532.packetbuffer[1], 16);
+
return 1;
}
-bool mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
+uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
Pn532.packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
- Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
+ Pn532.packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
memcpy(&Pn532.packetbuffer[4], data, 16); /* Data Payload */
/* Send the command */
if (PN532_writeCommand(Pn532.packetbuffer, 20)) {
- return false;
- }
- /* Read the response packet */
- if (PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)) < 1) {
- return false;
+ return 0;
}
- return true;
+ /* Read the response packet */
+return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
uint8_t ntag21x_probe (void) {
From 25079bb86b1fc57525be30af79e245f5c1c5a130 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Fri, 28 Oct 2022 01:26:24 +0300
Subject: [PATCH 085/319] Ready for PR
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index def685769..c5afefa9f 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -432,7 +432,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
}
/* Read the response packet */
-return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
+ return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
uint8_t ntag21x_probe (void) {
From cc9832634923f7f04fbb46bf3dac0090153def2b Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 28 Oct 2022 11:51:51 +0200
Subject: [PATCH 086/319] Tasmota Core 2.0.5.2
---
platformio_tasmota32.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini
index 90db20366..1e64da35b 100644
--- a/platformio_tasmota32.ini
+++ b/platformio_tasmota32.ini
@@ -40,7 +40,7 @@ extra_scripts = pre:pio-tools/add_c_flags.py
${esp_defaults.extra_scripts}
[core32]
-platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.1/platform-espressif32-2.0.5.1.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.2/platform-espressif32-2.0.5.2.zip
platform_packages =
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
From 7cd934fd1628919f92905d8804308879ecb9c4f8 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 28 Oct 2022 15:00:34 +0200
Subject: [PATCH 087/319] Tasmota ESP32 Core v2.0.5.2
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 637f44d9d..4b4db35d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Prepare for extended calibration and move some persistent data (PowerLow)
+- Tasmota ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
### Fixed
From 1bf69fd3108a0ca10d4271375d759c78c191b14f Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 17:08:02 +0300
Subject: [PATCH 088/319] dali
---
tasmota/include/tasmota_template.h | 11 +
tasmota/language/af_AF.h | 7 +
tasmota/language/bg_BG.h | 7 +
tasmota/language/ca_AD.h | 7 +
tasmota/language/cs_CZ.h | 7 +
tasmota/language/de_DE.h | 7 +
tasmota/language/el_GR.h | 7 +
tasmota/language/en_GB.h | 7 +
tasmota/language/es_ES.h | 7 +
tasmota/language/fr_FR.h | 7 +
tasmota/language/fy_NL.h | 7 +
tasmota/language/he_HE.h | 7 +
tasmota/language/hu_HU.h | 7 +
tasmota/language/it_IT.h | 7 +
tasmota/language/ko_KO.h | 7 +
tasmota/language/nl_NL.h | 7 +
tasmota/language/pl_PL.h | 7 +
tasmota/language/pt_BR.h | 7 +
tasmota/language/pt_PT.h | 7 +
tasmota/language/ro_RO.h | 7 +
tasmota/language/ru_RU.h | 7 +
tasmota/language/sk_SK.h | 7 +
tasmota/language/sv_SE.h | 7 +
tasmota/language/tr_TR.h | 7 +
tasmota/language/uk_UA.h | 7 +
tasmota/language/vi_VN.h | 7 +
tasmota/language/zh_CN.h | 7 +
tasmota/language/zh_TW.h | 7 +
.../xdrv_89_esp32_dali.ino | 643 ++++++++++++++++++
29 files changed, 843 insertions(+)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 869e92a8c..76977bde0 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -198,6 +198,9 @@ enum UserSelectablePins {
GPIO_ADE7953_RST, // ADE7953 Reset
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
+#ifdef ESP32
+ GPIO_DALI_RX, GPIO_DALI_TX, // Dali
+#endif
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -443,6 +446,9 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ADE7953_RST "|"
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
+#ifdef ESP32
+ D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
+#endif
;
const char kSensorNamesFixed[] PROGMEM =
@@ -527,6 +533,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
* Protocol specifics
\*-------------------------------------------------------------------------------------------*/
+#if defined(USE_DALI) && defined(ESP32)
+ AGPIO(GPIO_DALI_RX), // DALI RX
+ AGPIO(GPIO_DALI_TX), // DALI TX
+#endif // USE_DALI
+
#ifdef USE_I2C
AGPIO(GPIO_I2C_SCL) + MAX_I2C, // I2C SCL
AGPIO(GPIO_I2C_SDA) + MAX_I2C, // I2C SDA
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 58b48a17a..39dc3126b 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie Vandag"
#define D_ENERGY_YESTERDAY "Energie Gister"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 968746cd4..21ecbce73 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Консумация за днес"
#define D_ENERGY_YESTERDAY "Консумация за вчера"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 26bafafd8..01cf177b1 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
#define D_ENERGY_YESTERDAY "Energy Yesterday"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 2d32dcc9a..f1fea69ec 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotřeba Dnes"
#define D_ENERGY_YESTERDAY "Spotřeba Včera"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 05f940706..df8a827b1 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gefunden an Adresse"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zufällige Zigbee Parameter erstellt, Überprüfung mit 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie heute"
#define D_ENERGY_YESTERDAY "Energie gestern"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index d7cdbfe65..0d7500450 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
#define D_ENERGY_YESTERDAY "Ενέργεια χθες"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index ea85e0861..d59a97f01 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
#define D_ENERGY_YESTERDAY "Energy Yesterday"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index fa8dd2b67..b75beec9a 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Encontrada EEPROM de ZBBridge en"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Configurando parámetros Zigbee de forma aleatoria. Usar 'ZbConfig' para revisarlos."
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energía Hoy"
#define D_ENERGY_YESTERDAY "Energía Ayer"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 3364ff482..5f3eac5a3 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge trouvée à l'adresse"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomisation des paramètres ZigBee, veuillez vérifier avec 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xsns_03_energy.ino
#define D_ENERGY_TODAY "Énergie aujourd'hui"
#define D_ENERGY_YESTERDAY "Énergie hier"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 1e1a25927..a5f22689a 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM fûn op adres"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, kontrolearje asjebleaft mei 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Konsumpsje hjoed"
#define D_ENERGY_YESTERDAY "Konsumpsje juster"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 4db4cc9ff..31d969f78 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "צריכה יומית"
#define D_ENERGY_YESTERDAY "צריכה בעבר"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index d90312b00..c2204ea65 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM található a címen"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Zigbee paramétereknek véletlennek kell lenniük, ellenőrizd a 'ZbConfig'-gal"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Mai energia"
#define D_ENERGY_YESTERDAY "Tegnapi energia"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 99301cc0e..5db1e1220 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Trovata EEPROM ZBBridge all'indirizzo"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizzazione parametri Zigbee, controlla con \"ZbConfig\""
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia - oggi"
#define D_ENERGY_YESTERDAY "Energia - ieri"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 5554f07a0..7e85879cc 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "금일 전력 사용량"
#define D_ENERGY_YESTERDAY "어제 전력 사용량"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 960a8fcf2..f2355a709 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM aanwezig op adres"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Willekeurige Zigbee parameters gemaakt, controleer met 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Verbruik vandaag"
#define D_ENERGY_YESTERDAY "Verbruik gisteren"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 1157da535..c523cec6f 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "Znaleziono ZBBridge EEPROM na adresie"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Losowanie parametrów Zigbee, proszę sprawdzić 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia dzisiaj"
#define D_ENERGY_YESTERDAY "Energia wczoraj"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index fe96b16b8..b87b1a618 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "EEPROM ZBBridge encontrada no endereço" // "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizando parametros Zigbee, por favor congira em 'ZbConfig'" // "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 3607f8252..c050785fa 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM encontrada no edereço"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomização de parâmetros Zigbee, por-favor verifique a 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
#define D_ENERGY_YESTERDAY "Consumo energético de ontem"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index f51f0d07a..77ca813dc 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia de Azi"
#define D_ENERGY_YESTERDAY "Energia de Ieri"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index d45530605..fd9c3a7ee 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Конфигурация DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Энергия Сегодня"
#define D_ENERGY_YESTERDAY "Энергия Вчера"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 945bd72c1..8b1f107df 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotreba dnes"
#define D_ENERGY_YESTERDAY "Spotreba včera"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index ffc3e2764..a603635c3 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energi idag"
#define D_ENERGY_YESTERDAY "Energi igår"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index a19995a43..4c6d46b49 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
#define D_ENERGY_YESTERDAY "Energy Yesterday"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 8e832b9d8..1a6f34161 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Енергія Сьогодні"
#define D_ENERGY_YESTERDAY "Енергія Вчора"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index f87ba1029..7416d1dae 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Năng lượng tiêu thụ hôm nay"
#define D_ENERGY_YESTERDAY "Năng lượng tiêu thụ hôm qua"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 348718091..4f93019fc 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "找到 ZBBridge EEPROM, 地址:"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "正在随机化 Zigbee 参数, 请通过 'ZbConfig' 检查"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用电量"
#define D_ENERGY_YESTERDAY "昨日用电量"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 50c8c5dfb..641f8192c 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -511,6 +511,13 @@
#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address"
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'"
+// xdrv_89_dali.ino
+#define D_SENSOR_DALI_RX "Dali RX"
+#define D_SENSOR_DALI_TX "Dali TX"
+#define D_CONFIGURE_DALI "Config DALI"
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用電量"
#define D_ENERGY_YESTERDAY "昨日用電量"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
new file mode 100644
index 000000000..222f91bac
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -0,0 +1,643 @@
+/*
+ xdrv_89_esp32_dali.ino - DALI support for Tasmota
+
+ Copyright (C) 2022 Andrei Kazmirtsuk aka eeak
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ --------------------------------------------------------------------------------------------
+ Version yyyymmdd Action Description
+ --------------------------------------------------------------------------------------------
+ 0.0.0.1 20221027 publish - initial version
+*/
+
+#ifdef ESP32
+#ifdef USE_DALI
+
+/*********************************************************************************************\
+ * DALI support for Tasmota
+\*********************************************************************************************/
+
+#define XDRV_89 89
+
+#define BROADCAST_DP 0b11111110 // 0xFE
+
+enum
+{
+ DALI_NO_ACTION,
+ DALI_SENDING_DATA,
+ DALI_RECEIVING_DATA,
+ DALI_ERROR
+};
+
+struct DALI {
+ bool present = false;
+} Dali;
+
+// http and json defines
+#define D_NAME_DALI "DALI"
+
+const char S_JSON_DALI_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_DALI "\":{\"%s\":%d}}";
+const char kDALI_Commands[] PROGMEM = D_CMND_DALI_POWER "|" D_CMND_DALI_DIMMER;
+
+enum DALI_Commands { // commands for Console
+ CMND_DALI_PWR,
+ CMND_DALI_DIM,
+};
+
+/* Private variables ---------------------------------------------------------*/
+// Communication ports and pins
+bool DALIOUT_invert = false;
+bool DALIIN_invert = false;
+// Data variables
+uint16_t send_dali_data; // data to send to DALI bus
+uint16_t received_dali_data; // data received from DALI bus
+// Processing variables
+uint8_t flag; // DALI status flag
+uint8_t bit_count; // nr of rec/send bits
+uint16_t tick_count; // nr of ticks of the timer
+
+bool bit_value; // value of actual bit
+bool actual_val; // bit value in this tick of timer
+bool former_val; // bit value in previous tick of timer
+
+hw_timer_t *DALI_timer = NULL;
+
+/*********************************************************************************************\
+ * DALI low level
+\*********************************************************************************************/
+
+/**
+* @brief This function handles hardware timer Handler.
+* @param None
+* @retval None
+*/
+void IRAM_ATTR DALI_Tick_Handler(void)
+{
+ if (get_flag() == DALI_RECEIVING_DATA)
+ {
+ receive_tick();
+ }
+ else if (get_flag() == DALI_SENDING_DATA)
+ {
+ send_tick();
+ }
+}
+
+/**
+* @brief This function enable data transfer start interrupt.
+* @param None
+* @retval None
+*/
+void enableDaliRxInterrupt() {
+ flag = DALI_NO_ACTION;
+ timerAlarmDisable(DALI_timer);
+ attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
+}
+
+/**
+* @brief This function disable data transfer start interrupt.
+* @param None
+* @retval None
+*/
+void disableRxInterrupt() {
+ timerAlarmEnable(DALI_timer);
+ detachInterrupt(Pin(GPIO_DALI_RX));
+}
+
+/**
+* @brief receiving flag status
+* @param None
+* @retval uint8_t flag
+*/
+uint8_t get_flag(void)
+{
+ return flag;
+}
+
+/**
+* @brief DALI data received callback
+* @param None
+* @retval uint8_t flag
+*/
+void DataReceivedCallback() {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), received_dali_data>>9, received_dali_data&0xff);
+}
+
+/*************** R E C E I V E * P R O C E D U R E S *******/
+
+/**
+* @brief receive data from DALI bus
+* @param None
+* @retval None
+*/
+void receiveDaliData()
+{
+ // null variables
+ received_dali_data = 0;
+ bit_count = 0;
+ tick_count = 0;
+ former_val = true;
+
+ flag = DALI_RECEIVING_DATA;
+
+ disableRxInterrupt();
+}
+
+/**
+* @brief Get state of DALIIN pin
+* @param None
+* @retval bool status
+*/
+bool get_DALIIN(void)
+{
+ bool dali_read = digitalRead(Pin(GPIO_DALI_RX));
+ return (false == DALIIN_invert) ? dali_read : !dali_read;
+}
+
+/**
+* @brief receiving data from DALI bus
+* @param None
+* @retval None
+*
+* |--------|----|---------------------------|----|
+* 0 24 32 160 176
+* wait start data stop
+*/
+void receive_tick(void)
+{
+ // four ticks per bit
+ actual_val = get_DALIIN();
+ tick_count++;
+
+ // edge detected
+ if(actual_val != former_val)
+ {
+ switch(bit_count)
+ {
+ case 0:
+ if (tick_count > 2)
+ {
+ tick_count = 0;
+ bit_count = 1; // start bit
+ }
+ break;
+ case 17: // 1st stop bit
+ if(tick_count > 6) { // stop bit error, no edge should exist
+ flag = DALI_ERROR;
+ }
+ break;
+ default: // other bits
+ if(tick_count > 6)
+ {
+ received_dali_data |= (actual_val << (16-bit_count));
+ bit_count++;
+ tick_count = 0;
+ }
+ break;
+ }
+ }else // voltage level stable
+ {
+ switch(bit_count)
+ {
+ case 0:
+ if(tick_count==8) { // too long start bit
+ flag = DALI_ERROR;
+ Serial.println("Too long start bit.");
+ }
+ break;
+ case 17:
+ // First stop bit
+ if (tick_count==8)
+ {
+ if (actual_val==0) // wrong level of stop bit
+ {
+ flag = DALI_ERROR;
+ }
+ else
+ {
+ bit_count++;
+ tick_count = 0;
+ }
+ }
+ break;
+ case 18:
+ // Second stop bit
+ if (tick_count==8)
+ {
+ enableDaliRxInterrupt();
+ DataReceivedCallback();
+
+ }
+ break;
+ default: // normal bits
+ if(tick_count==10)
+ { // too long delay before edge
+ flag = DALI_ERROR;
+ }
+ break;
+ }
+ }
+ former_val = actual_val;
+ if(flag==DALI_ERROR)
+ {
+ enableDaliRxInterrupt();
+ }
+}
+
+
+/*************** S E N D * P R O C E D U R E S *************/
+
+/**
+* @brief Set value to the DALIOUT pin
+* @param bool
+* @retval None
+*/
+void set_DALIOUT(bool pin_value)
+{
+ digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALIOUT_invert ? LOW : HIGH);
+}
+
+/**
+* @brief gets state of the DALIOUT pin
+* @param None
+* @retval bool state of the DALIOUT pin
+*/
+bool get_DALIOUT(void)
+{
+ bool dali_read = digitalRead(Pin(GPIO_DALI_TX));
+ return (false == DALIOUT_invert) ? dali_read : !dali_read;
+}
+
+/**
+* @brief Send data to DALI bus
+* @param byteToSend
+* @retval None
+*/
+void sendDaliData(uint8_t firstByte, uint8_t secondByte)
+{
+ send_dali_data = firstByte << 8;
+ send_dali_data += secondByte & 0xff;
+ bit_count = 0;
+ tick_count = 0;
+
+ flag = DALI_SENDING_DATA;
+
+ disableRxInterrupt();
+}
+
+/**
+* @brief DALI protocol physical layer for slave device
+* @param None
+* @retval None
+*
+* |--------|----|---------------------------|----|
+* 0 24 32 160 176
+* wait start data stop
+*/
+void send_tick(void)
+{
+ // access to the routine just every 4 ticks = every half bit
+ if ((tick_count & 0x03) == 0)
+ {
+ if (tick_count < 160)
+ {
+ // settling time between forward and backward frame
+ if (tick_count < 24)
+ {
+ tick_count++;
+ return;
+ }
+
+ // start of the start bit
+ if (tick_count == 24)
+ {
+ // GPIOB->ODR ^= GPIO_ODR_7;
+ set_DALIOUT(false);
+ tick_count++;
+ return;
+ }
+
+ // edge of the start bit
+ // 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
+ if (tick_count == 28)
+ {
+ set_DALIOUT(true);
+ tick_count++;
+ return;
+ }
+
+ // bit value (edge) selection
+ bit_value = (bool)((send_dali_data >> (15 - bit_count)) & 0x01);
+
+ // Every half bit -> Manchester coding
+ if (!((tick_count - 24) & 0x0007))
+ { // div by 8
+ if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
+ set_DALIOUT((bool)(1 - bit_value));
+ }
+
+ // Generate edge for actual bit
+ if (!((tick_count - 28) & 0x0007))
+ {
+ set_DALIOUT(bit_value);
+ bit_count++;
+ }
+ }
+ else
+ { // end of data byte, start of stop bits
+ if (tick_count == 160)
+ {
+ set_DALIOUT(true); // start of stop bit
+ }
+
+ // end of stop bits, no settling time
+ if (tick_count == 176)
+ {
+ enableDaliRxInterrupt();
+ }
+ }
+ }
+ tick_count++;
+
+ return;
+}
+
+/***********************************************************/
+
+void DaliPreInit() {
+ if (!PinUsed(GPIO_DALI_TX) || !PinUsed(GPIO_DALI_RX)) { return; }
+ AddLog(LOG_LEVEL_INFO, PSTR("DLI: Init - RX-pin: %d, TX-pin: %d"), Pin(GPIO_DALI_RX), Pin(GPIO_DALI_TX));
+ // pinMode(LED, OUTPUT);
+ pinMode(Pin(GPIO_DALI_TX), OUTPUT);
+ digitalWrite(Pin(GPIO_DALI_TX), HIGH);
+ pinMode(Pin(GPIO_DALI_RX), INPUT);
+
+ DALI_timer = timerBegin(0, 13, true);
+ timerAttachInterrupt(DALI_timer, &DALI_Tick_Handler, true);
+ timerAlarmWrite(DALI_timer, 641, true);
+
+ attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
+ enableDaliRxInterrupt();
+ Dali.present = true;
+}
+
+void DaliPwr(uint8_t val){
+ // AddLog(LOG_LEVEL_INFO, PSTR("DLI: Send to address %d value %d"), 0, val);
+ sendDaliData(BROADCAST_DP, val);
+}
+
+bool DaliCmd(void)
+{
+ char command[CMDSZ];
+ uint8_t name_len = strlen(D_NAME_DALI);
+ if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_DALI), name_len))
+ {
+ uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kDALI_Commands);
+ switch (command_code)
+ {
+ case CMND_DALI_PWR:
+ if (XdrvMailbox.data_len)
+ {
+ // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.data_len %d"), XdrvMailbox.data_len);
+ // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.payload %d"), XdrvMailbox.payload);
+ if (254 >= XdrvMailbox.payload)
+ {
+ DaliPwr(XdrvMailbox.payload);
+ }
+ }
+ // Response_P(S_JSON_DALI_COMMAND_NVALUE, command, DaliGetPwr());
+ Response_P(S_JSON_DALI_COMMAND_NVALUE, command, XdrvMailbox.payload);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/*********************************************************************************************\
+ * Presentation
+\*********************************************************************************************/
+
+#ifdef USE_WEBSERVER
+
+#define WEB_HANDLE_DALI "dali"
+
+const char HTTP_BTN_MENU_DALI[] PROGMEM =
+ "
";
+
+#endif // USE_WEBSERVER
+
+
+
+#define DALI_TOPIC "DALI"
+static char tmp[120];
+
+bool DaliMqtt()
+{
+ char stopic[TOPSZ];
+ strncpy(stopic, XdrvMailbox.topic, TOPSZ);
+ XdrvMailbox.topic[TOPSZ - 1] = 0;
+
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DALI mqtt: %s:%s"), stopic, XdrvMailbox.data);
+
+ // Разберем топик на слова по "/"
+ char *items[10];
+ char *p = stopic;
+ int cnt = 0;
+ do
+ {
+ items[cnt] = strtok(p, "/");
+ cnt++;
+ p = nullptr;
+ } while (items[cnt - 1]);
+ cnt--; // repreents the number of items
+
+ if (cnt < 3)
+ { // not for us?
+ AddLog(LOG_LEVEL_INFO,PSTR("cnt: %d < 3"), cnt);
+ return false;
+ }
+
+ // cnt-4 cnt -3 cnt-2 cnt-1
+ // cmnd/tasmota_078480/DALI/power :70
+ // cnt-5 cnt -4 cnt-3 cnt-2 cnt-1
+ // cmnd/tasmota_078480/DALI/power/0 :70
+ int DALIindex = 0;
+ int ADRindex = 0;
+ int CMDindex = 0;
+ uint8_t DALIaddr = BROADCAST_DP;
+ if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0)
+ {
+ // AddLog(LOG_LEVEL_INFO,PSTR("cnt-3 not %s"), PSTR(DALI_TOPIC));
+ if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0)
+ {
+ // AddLog(LOG_LEVEL_INFO,PSTR("cnt-2 not %s"), PSTR(DALI_TOPIC));
+ if (strcasecmp_P(items[cnt - 1], PSTR(DALI_TOPIC)) != 0)
+ {
+ return false; // not for us
+ }
+ else
+ {
+ // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle json"));
+ if (true == DaliJsonParse()) { return true; }
+ }
+ }
+ else
+ {
+ DALIindex = cnt - 2;
+ CMDindex = cnt - 1;
+ }
+ }
+ else
+ {
+ DALIindex = cnt - 3;
+ CMDindex = cnt - 2;
+ ADRindex = cnt - 1;
+ DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
+
+ }
+
+ // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle topic + data"));
+ uint8_t level;
+ uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data);
+ if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) {
+ float percent = (float)(254 * value * 0.01);
+ level = (uint8_t)percent;
+ }
+ else if (strcasecmp_P(items[CMDindex], PSTR("level")) == 0) {
+ level = value;
+ }
+ else {
+ AddLog(LOG_LEVEL_INFO,PSTR("command not recognized: %s"), items[CMDindex]);
+ return false; // not for us
+ }
+
+ AddLog(LOG_LEVEL_INFO,PSTR("Dali value %d on address %d"), value, DALIaddr);
+ sendDaliData(DALIaddr, level);
+
+ return true;
+}
+
+bool DaliJsonParse()
+{
+ bool served = false;
+
+ // if (strlen(XdrvMailbox.data) > 8) { // Workaround exception if empty JSON like {} - Needs checks
+ JsonParser parser((char *)XdrvMailbox.data);
+ JsonParserObject root = parser.getRootObject();
+ if (root)
+ {
+ int DALIindex = 0;
+ int ADRindex = 0;
+ int8_t DALIdim = -1;
+ uint8_t DALIaddr = BROADCAST_DP;
+
+ JsonParserToken val = root[PSTR("cmd")]; // Команда
+ if (val)
+ {
+ uint8_t cmd = val.getUInt();
+ val = root[PSTR("addr")];
+ if (val)
+ {
+ uint8_t addr = val.getUInt();
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
+ sendDaliData(addr, cmd);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ val = root[PSTR("addr")];
+ if (val)
+ {
+ uint8_t addr = val.getUInt();
+ if ((addr >= 0) && (addr < 64))
+ DALIaddr = addr << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json addr = %d"), val.getUInt());
+ }
+ val = root[PSTR("dim")];
+ if (val)
+ {
+ uint8_t dim = val.getUInt();
+ if ((dim >= 0) && (dim < 255))
+ DALIdim = dim;
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json dimmer = %d"), val.getUInt());
+ }
+ // val = root[PSTR("power")];
+ // if (val)
+ // {
+ // // FMqtt.file_type = val.getUInt();
+ // // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json power = %d"), val.getUInt());
+ // }
+ sendDaliData(DALIaddr, DALIdim);
+ served = true;
+ }
+ // else {
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json ERROR - not json"));
+ // }
+ // }
+
+ return served;
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xdrv89(uint8_t function)
+{
+ bool result = false;
+
+ if (FUNC_INIT == function)
+ {
+ DaliPreInit();
+ }
+ else if (Dali.present)
+ {
+ switch (function)
+ {
+ case FUNC_MQTT_DATA:
+ result = DaliMqtt();
+ break;
+ case FUNC_COMMAND:
+ result = DaliCmd();
+ break;
+#ifdef USE_WEBSERVER
+ // case FUNC_WEB_ADD_BUTTON:
+ // WSContentSend_P(HTTP_BTN_MENU_DALI);
+ // break;
+ // case FUNC_WEB_ADD_HANDLER:
+ // WebServer_on(PSTR("/" WEB_HANDLE_DALI), HandleDali);
+ // break;
+#ifdef USE_DALI_DISPLAYINPUT
+ // case FUNC_WEB_SENSOR:
+ // DaliShow(0);
+ // break;
+#endif // #ifdef USE_DALI_DISPLAYINPUT
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_DALI
+#endif // ESP32
\ No newline at end of file
From c1c0b25c174034adbb96578e228a77ed712fb7e0 Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 19:47:55 +0300
Subject: [PATCH 089/319] Clean up some comments and little refactor
---
tasmota/my_user_config.h | 4 +
.../xdrv_89_esp32_dali.ino | 138 +++++-------------
2 files changed, 43 insertions(+), 99 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 51ea0d677..8a4de54f0 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1034,6 +1034,10 @@
#define USE_ESP32_SENSORS // Add support for ESP32 temperature and optional hall effect sensor
+#define USE_DALI // Add support for DALI
+ #define DALI_IN_INVERT 0 // DALI RX inverted ?
+ #define DALI_OUT_INVERT 0 // DALI TX inverted ?
+
//#define USE_SONOFF_SPM // Add support for ESP32 based Sonoff Smart Stackable Power Meter (+11k code)
//#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 dsiplay driver used by Sonoff POWR3xxD and THR3xxD
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 222f91bac..844b71af6 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -32,6 +32,7 @@
#define XDRV_89 89
#define BROADCAST_DP 0b11111110 // 0xFE
+#define DALI_TOPIC "DALI"
enum
{
@@ -57,9 +58,6 @@ enum DALI_Commands { // commands for Console
};
/* Private variables ---------------------------------------------------------*/
-// Communication ports and pins
-bool DALIOUT_invert = false;
-bool DALIIN_invert = false;
// Data variables
uint16_t send_dali_data; // data to send to DALI bus
uint16_t received_dali_data; // data received from DALI bus
@@ -163,7 +161,7 @@ void receiveDaliData()
bool get_DALIIN(void)
{
bool dali_read = digitalRead(Pin(GPIO_DALI_RX));
- return (false == DALIIN_invert) ? dali_read : !dali_read;
+ return (false == DALI_IN_INVERT) ? dali_read : !dali_read;
}
/**
@@ -266,7 +264,7 @@ void receive_tick(void)
*/
void set_DALIOUT(bool pin_value)
{
- digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALIOUT_invert ? LOW : HIGH);
+ digitalWrite(Pin(GPIO_DALI_TX), pin_value == DALI_OUT_INVERT ? LOW : HIGH);
}
/**
@@ -277,7 +275,7 @@ void set_DALIOUT(bool pin_value)
bool get_DALIOUT(void)
{
bool dali_read = digitalRead(Pin(GPIO_DALI_TX));
- return (false == DALIOUT_invert) ? dali_read : !dali_read;
+ return (false == DALI_OUT_INVERT) ? dali_read : !dali_read;
}
/**
@@ -394,7 +392,6 @@ void DaliPreInit() {
}
void DaliPwr(uint8_t val){
- // AddLog(LOG_LEVEL_INFO, PSTR("DLI: Send to address %d value %d"), 0, val);
sendDaliData(BROADCAST_DP, val);
}
@@ -410,14 +407,11 @@ bool DaliCmd(void)
case CMND_DALI_PWR:
if (XdrvMailbox.data_len)
{
- // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.data_len %d"), XdrvMailbox.data_len);
- // AddLog(LOG_LEVEL_INFO, PSTR("DLI: XdrvMailbox.payload %d"), XdrvMailbox.payload);
if (254 >= XdrvMailbox.payload)
{
DaliPwr(XdrvMailbox.payload);
}
}
- // Response_P(S_JSON_DALI_COMMAND_NVALUE, command, DaliGetPwr());
Response_P(S_JSON_DALI_COMMAND_NVALUE, command, XdrvMailbox.payload);
break;
default:
@@ -431,23 +425,6 @@ bool DaliCmd(void)
}
}
-/*********************************************************************************************\
- * Presentation
-\*********************************************************************************************/
-
-#ifdef USE_WEBSERVER
-
-#define WEB_HANDLE_DALI "dali"
-
-const char HTTP_BTN_MENU_DALI[] PROGMEM =
- "";
-
-#endif // USE_WEBSERVER
-
-
-
-#define DALI_TOPIC "DALI"
-static char tmp[120];
bool DaliMqtt()
{
@@ -455,9 +432,6 @@ bool DaliMqtt()
strncpy(stopic, XdrvMailbox.topic, TOPSZ);
XdrvMailbox.topic[TOPSZ - 1] = 0;
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DALI mqtt: %s:%s"), stopic, XdrvMailbox.data);
-
- // Разберем топик на слова по "/"
char *items[10];
char *p = stopic;
int cnt = 0;
@@ -475,27 +449,20 @@ bool DaliMqtt()
return false;
}
- // cnt-4 cnt -3 cnt-2 cnt-1
- // cmnd/tasmota_078480/DALI/power :70
- // cnt-5 cnt -4 cnt-3 cnt-2 cnt-1
- // cmnd/tasmota_078480/DALI/power/0 :70
int DALIindex = 0;
int ADRindex = 0;
int CMDindex = 0;
uint8_t DALIaddr = BROADCAST_DP;
if (strcasecmp_P(items[cnt - 3], PSTR(DALI_TOPIC)) != 0)
{
- // AddLog(LOG_LEVEL_INFO,PSTR("cnt-3 not %s"), PSTR(DALI_TOPIC));
if (strcasecmp_P(items[cnt - 2], PSTR(DALI_TOPIC)) != 0)
{
- // AddLog(LOG_LEVEL_INFO,PSTR("cnt-2 not %s"), PSTR(DALI_TOPIC));
if (strcasecmp_P(items[cnt - 1], PSTR(DALI_TOPIC)) != 0)
{
return false; // not for us
}
else
{
- // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle json"));
if (true == DaliJsonParse()) { return true; }
}
}
@@ -510,11 +477,10 @@ bool DaliMqtt()
DALIindex = cnt - 3;
CMDindex = cnt - 2;
ADRindex = cnt - 1;
- DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
+ DALIaddr = ((int)CharToFloat(items[ADRindex])) << 1;
}
- // AddLog(LOG_LEVEL_INFO,PSTR("DLI: handle topic + data"));
uint8_t level;
uint8_t value = (uint8_t)CharToFloat(XdrvMailbox.data);
if (strcasecmp_P(items[CMDindex], PSTR("percent")) == 0) {
@@ -538,63 +504,50 @@ bool DaliMqtt()
bool DaliJsonParse()
{
bool served = false;
+ JsonParser parser((char *)XdrvMailbox.data);
+ JsonParserObject root = parser.getRootObject();
+ if (root)
+ {
+ int DALIindex = 0;
+ int ADRindex = 0;
+ int8_t DALIdim = -1;
+ uint8_t DALIaddr = BROADCAST_DP;
- // if (strlen(XdrvMailbox.data) > 8) { // Workaround exception if empty JSON like {} - Needs checks
- JsonParser parser((char *)XdrvMailbox.data);
- JsonParserObject root = parser.getRootObject();
- if (root)
+ JsonParserToken val = root[PSTR("cmd")];
+ if (val)
{
- int DALIindex = 0;
- int ADRindex = 0;
- int8_t DALIdim = -1;
- uint8_t DALIaddr = BROADCAST_DP;
-
- JsonParserToken val = root[PSTR("cmd")]; // Команда
- if (val)
- {
- uint8_t cmd = val.getUInt();
- val = root[PSTR("addr")];
- if (val)
- {
- uint8_t addr = val.getUInt();
- AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
- sendDaliData(addr, cmd);
- return true;
- }
- else
- {
- return false;
- }
- }
+ uint8_t cmd = val.getUInt();
val = root[PSTR("addr")];
if (val)
{
uint8_t addr = val.getUInt();
- if ((addr >= 0) && (addr < 64))
- DALIaddr = addr << 1; // !!! ВАЖНО !!! Номер лампы должен быть сдвинут << 1
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json addr = %d"), val.getUInt());
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: cmd = %d, addr = %d"), cmd, addr);
+ sendDaliData(addr, cmd);
+ return true;
}
- val = root[PSTR("dim")];
- if (val)
+ else
{
- uint8_t dim = val.getUInt();
- if ((dim >= 0) && (dim < 255))
- DALIdim = dim;
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json dimmer = %d"), val.getUInt());
+ return false;
}
- // val = root[PSTR("power")];
- // if (val)
- // {
- // // FMqtt.file_type = val.getUInt();
- // // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json power = %d"), val.getUInt());
- // }
- sendDaliData(DALIaddr, DALIdim);
- served = true;
}
- // else {
- // AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: mqtt->json ERROR - not json"));
- // }
- // }
+ val = root[PSTR("addr")];
+ if (val)
+ {
+ uint8_t addr = val.getUInt();
+ if ((addr >= 0) && (addr < 64))
+ DALIaddr = addr << 1;
+ }
+ val = root[PSTR("dim")];
+ if (val)
+ {
+ uint8_t dim = val.getUInt();
+ if (dim < 255)
+ DALIdim = dim;
+ }
+
+ sendDaliData(DALIaddr, DALIdim);
+ served = true;
+ }
return served;
}
@@ -621,19 +574,6 @@ bool Xdrv89(uint8_t function)
case FUNC_COMMAND:
result = DaliCmd();
break;
-#ifdef USE_WEBSERVER
- // case FUNC_WEB_ADD_BUTTON:
- // WSContentSend_P(HTTP_BTN_MENU_DALI);
- // break;
- // case FUNC_WEB_ADD_HANDLER:
- // WebServer_on(PSTR("/" WEB_HANDLE_DALI), HandleDali);
- // break;
-#ifdef USE_DALI_DISPLAYINPUT
- // case FUNC_WEB_SENSOR:
- // DaliShow(0);
- // break;
-#endif // #ifdef USE_DALI_DISPLAYINPUT
-#endif // USE_WEBSERVER
}
}
return result;
From 76c5be76346ef1fb85918b6e91a10963cd30d263 Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 20:16:45 +0300
Subject: [PATCH 090/319] Packed global variables into a struct
---
.../xdrv_89_esp32_dali.ino | 146 +++++++++---------
1 file changed, 77 insertions(+), 69 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 844b71af6..39ac47a3f 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -42,10 +42,6 @@ enum
DALI_ERROR
};
-struct DALI {
- bool present = false;
-} Dali;
-
// http and json defines
#define D_NAME_DALI "DALI"
@@ -59,16 +55,29 @@ enum DALI_Commands { // commands for Console
/* Private variables ---------------------------------------------------------*/
// Data variables
-uint16_t send_dali_data; // data to send to DALI bus
-uint16_t received_dali_data; // data received from DALI bus
+// uint16_t send_dali_data; // data to send to DALI bus
+// uint16_t received_dali_data; // data received from DALI bus
// Processing variables
-uint8_t flag; // DALI status flag
-uint8_t bit_count; // nr of rec/send bits
-uint16_t tick_count; // nr of ticks of the timer
+// uint8_t flag; // DALI status flag
+// uint8_t bit_count; // nr of rec/send bits
+// uint16_t tick_count; // nr of ticks of the timer
-bool bit_value; // value of actual bit
-bool actual_val; // bit value in this tick of timer
-bool former_val; // bit value in previous tick of timer
+// bool bit_value; // value of actual bit
+// bool actual_val; // bit value in this tick of timer
+// bool former_val; // bit value in previous tick of timer
+
+struct DALI {
+ // Data variables
+ uint16_t send_dali_data; // data to send to DALI bus
+ uint16_t received_dali_data; // data received from DALI bus
+ // Processing variables
+ uint8_t flag; // DALI status flag
+ uint8_t bit_count; // nr of rec/send bits
+ uint16_t tick_count; // nr of ticks of the timer
+ bool former_val; // bit value in previous tick of timer
+
+ bool present = false;// DALI initialized
+} Dali;
hw_timer_t *DALI_timer = NULL;
@@ -83,11 +92,11 @@ hw_timer_t *DALI_timer = NULL;
*/
void IRAM_ATTR DALI_Tick_Handler(void)
{
- if (get_flag() == DALI_RECEIVING_DATA)
+ if (getDaliFlag() == DALI_RECEIVING_DATA)
{
receive_tick();
}
- else if (get_flag() == DALI_SENDING_DATA)
+ else if (getDaliFlag() == DALI_SENDING_DATA)
{
send_tick();
}
@@ -99,7 +108,7 @@ void IRAM_ATTR DALI_Tick_Handler(void)
* @retval None
*/
void enableDaliRxInterrupt() {
- flag = DALI_NO_ACTION;
+ Dali.flag = DALI_NO_ACTION;
timerAlarmDisable(DALI_timer);
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
}
@@ -119,9 +128,9 @@ void disableRxInterrupt() {
* @param None
* @retval uint8_t flag
*/
-uint8_t get_flag(void)
+uint8_t getDaliFlag(void)
{
- return flag;
+ return Dali.flag;
}
/**
@@ -130,7 +139,7 @@ uint8_t get_flag(void)
* @retval uint8_t flag
*/
void DataReceivedCallback() {
- AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), received_dali_data>>9, received_dali_data&0xff);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali.received_dali_data>>9, Dali.received_dali_data&0xff);
}
/*************** R E C E I V E * P R O C E D U R E S *******/
@@ -143,12 +152,12 @@ void DataReceivedCallback() {
void receiveDaliData()
{
// null variables
- received_dali_data = 0;
- bit_count = 0;
- tick_count = 0;
- former_val = true;
+ Dali.received_dali_data = 0;
+ Dali.bit_count = 0;
+ Dali.tick_count = 0;
+ Dali.former_val = true;
- flag = DALI_RECEIVING_DATA;
+ Dali.flag = DALI_RECEIVING_DATA;
disableRxInterrupt();
}
@@ -176,63 +185,62 @@ bool get_DALIIN(void)
void receive_tick(void)
{
// four ticks per bit
- actual_val = get_DALIIN();
- tick_count++;
+ bool actual_val = get_DALIIN();
+ Dali.tick_count++;
// edge detected
- if(actual_val != former_val)
+ if(actual_val != Dali.former_val)
{
- switch(bit_count)
+ switch(Dali.bit_count)
{
case 0:
- if (tick_count > 2)
+ if (Dali.tick_count > 2)
{
- tick_count = 0;
- bit_count = 1; // start bit
+ Dali.tick_count = 0;
+ Dali.bit_count = 1; // start bit
}
break;
case 17: // 1st stop bit
- if(tick_count > 6) { // stop bit error, no edge should exist
- flag = DALI_ERROR;
+ if(Dali.tick_count > 6) { // stop bit error, no edge should exist
+ Dali.flag = DALI_ERROR;
}
break;
default: // other bits
- if(tick_count > 6)
+ if(Dali.tick_count > 6)
{
- received_dali_data |= (actual_val << (16-bit_count));
- bit_count++;
- tick_count = 0;
+ Dali.received_dali_data |= (actual_val << (16-Dali.bit_count));
+ Dali.bit_count++;
+ Dali.tick_count = 0;
}
break;
}
}else // voltage level stable
{
- switch(bit_count)
+ switch(Dali.bit_count)
{
case 0:
- if(tick_count==8) { // too long start bit
- flag = DALI_ERROR;
- Serial.println("Too long start bit.");
+ if(Dali.tick_count==8) { // too long start bit
+ Dali.flag = DALI_ERROR;
}
break;
case 17:
// First stop bit
- if (tick_count==8)
+ if (Dali.tick_count==8)
{
if (actual_val==0) // wrong level of stop bit
{
- flag = DALI_ERROR;
+ Dali.flag = DALI_ERROR;
}
else
{
- bit_count++;
- tick_count = 0;
+ Dali.bit_count++;
+ Dali.tick_count = 0;
}
}
break;
case 18:
// Second stop bit
- if (tick_count==8)
+ if (Dali.tick_count==8)
{
enableDaliRxInterrupt();
DataReceivedCallback();
@@ -240,15 +248,15 @@ void receive_tick(void)
}
break;
default: // normal bits
- if(tick_count==10)
+ if(Dali.tick_count==10)
{ // too long delay before edge
- flag = DALI_ERROR;
+ Dali.flag = DALI_ERROR;
}
break;
}
}
- former_val = actual_val;
- if(flag==DALI_ERROR)
+ Dali.former_val = actual_val;
+ if(getDaliFlag() == DALI_ERROR)
{
enableDaliRxInterrupt();
}
@@ -285,12 +293,12 @@ bool get_DALIOUT(void)
*/
void sendDaliData(uint8_t firstByte, uint8_t secondByte)
{
- send_dali_data = firstByte << 8;
- send_dali_data += secondByte & 0xff;
- bit_count = 0;
- tick_count = 0;
+ Dali.send_dali_data = firstByte << 8;
+ Dali.send_dali_data += secondByte & 0xff;
+ Dali.bit_count = 0;
+ Dali.tick_count = 0;
- flag = DALI_SENDING_DATA;
+ Dali.flag = DALI_SENDING_DATA;
disableRxInterrupt();
}
@@ -307,67 +315,67 @@ void sendDaliData(uint8_t firstByte, uint8_t secondByte)
void send_tick(void)
{
// access to the routine just every 4 ticks = every half bit
- if ((tick_count & 0x03) == 0)
+ if ((Dali.tick_count & 0x03) == 0)
{
- if (tick_count < 160)
+ if (Dali.tick_count < 160)
{
// settling time between forward and backward frame
- if (tick_count < 24)
+ if (Dali.tick_count < 24)
{
- tick_count++;
+ Dali.tick_count++;
return;
}
// start of the start bit
- if (tick_count == 24)
+ if (Dali.tick_count == 24)
{
// GPIOB->ODR ^= GPIO_ODR_7;
set_DALIOUT(false);
- tick_count++;
+ Dali.tick_count++;
return;
}
// edge of the start bit
// 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
- if (tick_count == 28)
+ if (Dali.tick_count == 28)
{
set_DALIOUT(true);
- tick_count++;
+ Dali.tick_count++;
return;
}
// bit value (edge) selection
- bit_value = (bool)((send_dali_data >> (15 - bit_count)) & 0x01);
+ bool bit_value = (bool)((Dali.send_dali_data >> (15 - Dali.bit_count)) & 0x01);
// Every half bit -> Manchester coding
- if (!((tick_count - 24) & 0x0007))
+ if (!((Dali.tick_count - 24) & 0x0007))
{ // div by 8
if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
set_DALIOUT((bool)(1 - bit_value));
}
// Generate edge for actual bit
- if (!((tick_count - 28) & 0x0007))
+ if (!((Dali.tick_count - 28) & 0x0007))
{
set_DALIOUT(bit_value);
- bit_count++;
+ Dali.bit_count++;
}
}
else
{ // end of data byte, start of stop bits
- if (tick_count == 160)
+ if (Dali.tick_count == 160)
{
set_DALIOUT(true); // start of stop bit
}
// end of stop bits, no settling time
- if (tick_count == 176)
+ if (Dali.tick_count == 176)
{
enableDaliRxInterrupt();
}
}
}
- tick_count++;
+ Dali.tick_count++;
return;
}
From 404db7965e84421d6cb83e4b536fc2cd0142f49b Mon Sep 17 00:00:00 2001
From: eeak
Date: Fri, 28 Oct 2022 21:57:40 +0300
Subject: [PATCH 091/319] Timer number is now declared in my_user_config.h
---
tasmota/my_user_config.h | 1 +
.../xdrv_89_esp32_dali.ino | 19 +++++--------------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 8a4de54f0..3e2d83a5b 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1037,6 +1037,7 @@
#define USE_DALI // Add support for DALI
#define DALI_IN_INVERT 0 // DALI RX inverted ?
#define DALI_OUT_INVERT 0 // DALI TX inverted ?
+ #define DALI_TIMER 0 // ESP32 hardware timer number 0-3 !!! timer 3 used in xdrv_10_scripter.ino !!!
//#define USE_SONOFF_SPM // Add support for ESP32 based Sonoff Smart Stackable Power Meter (+11k code)
//#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 dsiplay driver used by Sonoff POWR3xxD and THR3xxD
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 39ac47a3f..87523b6e0 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -31,6 +31,10 @@
#define XDRV_89 89
+#ifndef DALI_TIMER
+ #define DALI_TIMER 0 // Default timer
+#endif
+
#define BROADCAST_DP 0b11111110 // 0xFE
#define DALI_TOPIC "DALI"
@@ -53,19 +57,6 @@ enum DALI_Commands { // commands for Console
CMND_DALI_DIM,
};
-/* Private variables ---------------------------------------------------------*/
-// Data variables
-// uint16_t send_dali_data; // data to send to DALI bus
-// uint16_t received_dali_data; // data received from DALI bus
-// Processing variables
-// uint8_t flag; // DALI status flag
-// uint8_t bit_count; // nr of rec/send bits
-// uint16_t tick_count; // nr of ticks of the timer
-
-// bool bit_value; // value of actual bit
-// bool actual_val; // bit value in this tick of timer
-// bool former_val; // bit value in previous tick of timer
-
struct DALI {
// Data variables
uint16_t send_dali_data; // data to send to DALI bus
@@ -390,7 +381,7 @@ void DaliPreInit() {
digitalWrite(Pin(GPIO_DALI_TX), HIGH);
pinMode(Pin(GPIO_DALI_RX), INPUT);
- DALI_timer = timerBegin(0, 13, true);
+ DALI_timer = timerBegin(DALI_TIMER, 13, true);
timerAttachInterrupt(DALI_timer, &DALI_Tick_Handler, true);
timerAlarmWrite(DALI_timer, 641, true);
From 5dc5e11dc98d65967d76b051f838f5c0b32a41d4 Mon Sep 17 00:00:00 2001
From: Staars
Date: Sat, 29 Oct 2022 10:56:53 +0200
Subject: [PATCH 092/319] check for valid cdc config: board vs env
---
pio-tools/post_esp32.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py
index 3ded90386..370934845 100644
--- a/pio-tools/post_esp32.py
+++ b/pio-tools/post_esp32.py
@@ -139,6 +139,11 @@ def esp32_create_combined_bin(source, target, env):
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
chip = env.get("BOARD_MCU")
tasmota_platform = esp32_create_chip_string(chip)
+
+ if "-DUSE_USB_CDC_CONSOLE" in env.BoardConfig().get("build.extra_flags") and "cdc" not in tasmota_platform:
+ tasmota_platform += "cdc"
+ print("WARNING: board definition uses CDC configuration, but environment name does not -> changing tasmota safeboot binary to:", tasmota_platform + "-safeboot.bin")
+
if not os.path.exists(variants_dir):
os.makedirs(variants_dir)
if("safeboot" in firmware_name):
From 6c0e38e38d783646b0ed12d3485ceb244ff9d61b Mon Sep 17 00:00:00 2001
From: eeak
Date: Sat, 29 Oct 2022 12:50:41 +0300
Subject: [PATCH 093/319] Data struct rebuilded. Thanks barbudor for help
---
tasmota/my_user_config.h | 2 +-
.../xdrv_89_esp32_dali.ino | 135 +++++++++---------
2 files changed, 69 insertions(+), 68 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 3e2d83a5b..24077f12f 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1034,7 +1034,7 @@
#define USE_ESP32_SENSORS // Add support for ESP32 temperature and optional hall effect sensor
-#define USE_DALI // Add support for DALI
+// #define USE_DALI // Add support for DALI
#define DALI_IN_INVERT 0 // DALI RX inverted ?
#define DALI_OUT_INVERT 0 // DALI TX inverted ?
#define DALI_TIMER 0 // ESP32 hardware timer number 0-3 !!! timer 3 used in xdrv_10_scripter.ino !!!
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 87523b6e0..0a247a2bd 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -58,19 +58,16 @@ enum DALI_Commands { // commands for Console
};
struct DALI {
- // Data variables
uint16_t send_dali_data; // data to send to DALI bus
uint16_t received_dali_data; // data received from DALI bus
- // Processing variables
- uint8_t flag; // DALI status flag
- uint8_t bit_count; // nr of rec/send bits
- uint16_t tick_count; // nr of ticks of the timer
- bool former_val; // bit value in previous tick of timer
+ uint8_t flag; // DALI status flag
+ uint8_t bit_count; // nr of rec/send bits
+ uint16_t tick_count; // nr of ticks of the timer
+ bool former_val; // bit value in previous tick of timer
+ hw_timer_t *timer; // hardware timer
+} *Dali = nullptr;
- bool present = false;// DALI initialized
-} Dali;
-hw_timer_t *DALI_timer = NULL;
/*********************************************************************************************\
* DALI low level
@@ -99,8 +96,8 @@ void IRAM_ATTR DALI_Tick_Handler(void)
* @retval None
*/
void enableDaliRxInterrupt() {
- Dali.flag = DALI_NO_ACTION;
- timerAlarmDisable(DALI_timer);
+ Dali->flag = DALI_NO_ACTION;
+ timerAlarmDisable(Dali->timer);
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
}
@@ -110,7 +107,7 @@ void enableDaliRxInterrupt() {
* @retval None
*/
void disableRxInterrupt() {
- timerAlarmEnable(DALI_timer);
+ timerAlarmEnable(Dali->timer);
detachInterrupt(Pin(GPIO_DALI_RX));
}
@@ -121,7 +118,7 @@ void disableRxInterrupt() {
*/
uint8_t getDaliFlag(void)
{
- return Dali.flag;
+ return Dali->flag;
}
/**
@@ -130,7 +127,7 @@ uint8_t getDaliFlag(void)
* @retval uint8_t flag
*/
void DataReceivedCallback() {
- AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali.received_dali_data>>9, Dali.received_dali_data&0xff);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DLI: Received: %d %d"), Dali->received_dali_data>>9, Dali->received_dali_data&0xff);
}
/*************** R E C E I V E * P R O C E D U R E S *******/
@@ -143,12 +140,12 @@ void DataReceivedCallback() {
void receiveDaliData()
{
// null variables
- Dali.received_dali_data = 0;
- Dali.bit_count = 0;
- Dali.tick_count = 0;
- Dali.former_val = true;
+ Dali->received_dali_data = 0;
+ Dali->bit_count = 0;
+ Dali->tick_count = 0;
+ Dali->former_val = true;
- Dali.flag = DALI_RECEIVING_DATA;
+ Dali->flag = DALI_RECEIVING_DATA;
disableRxInterrupt();
}
@@ -177,61 +174,61 @@ void receive_tick(void)
{
// four ticks per bit
bool actual_val = get_DALIIN();
- Dali.tick_count++;
+ Dali->tick_count++;
// edge detected
- if(actual_val != Dali.former_val)
+ if(actual_val != Dali->former_val)
{
- switch(Dali.bit_count)
+ switch(Dali->bit_count)
{
case 0:
- if (Dali.tick_count > 2)
+ if (Dali->tick_count > 2)
{
- Dali.tick_count = 0;
- Dali.bit_count = 1; // start bit
+ Dali->tick_count = 0;
+ Dali->bit_count = 1; // start bit
}
break;
case 17: // 1st stop bit
- if(Dali.tick_count > 6) { // stop bit error, no edge should exist
- Dali.flag = DALI_ERROR;
+ if(Dali->tick_count > 6) { // stop bit error, no edge should exist
+ Dali->flag = DALI_ERROR;
}
break;
default: // other bits
- if(Dali.tick_count > 6)
+ if(Dali->tick_count > 6)
{
- Dali.received_dali_data |= (actual_val << (16-Dali.bit_count));
- Dali.bit_count++;
- Dali.tick_count = 0;
+ Dali->received_dali_data |= (actual_val << (16-Dali->bit_count));
+ Dali->bit_count++;
+ Dali->tick_count = 0;
}
break;
}
}else // voltage level stable
{
- switch(Dali.bit_count)
+ switch(Dali->bit_count)
{
case 0:
- if(Dali.tick_count==8) { // too long start bit
- Dali.flag = DALI_ERROR;
+ if(Dali->tick_count==8) { // too long start bit
+ Dali->flag = DALI_ERROR;
}
break;
case 17:
// First stop bit
- if (Dali.tick_count==8)
+ if (Dali->tick_count==8)
{
if (actual_val==0) // wrong level of stop bit
{
- Dali.flag = DALI_ERROR;
+ Dali->flag = DALI_ERROR;
}
else
{
- Dali.bit_count++;
- Dali.tick_count = 0;
+ Dali->bit_count++;
+ Dali->tick_count = 0;
}
}
break;
case 18:
// Second stop bit
- if (Dali.tick_count==8)
+ if (Dali->tick_count==8)
{
enableDaliRxInterrupt();
DataReceivedCallback();
@@ -239,14 +236,14 @@ void receive_tick(void)
}
break;
default: // normal bits
- if(Dali.tick_count==10)
+ if(Dali->tick_count==10)
{ // too long delay before edge
- Dali.flag = DALI_ERROR;
+ Dali->flag = DALI_ERROR;
}
break;
}
}
- Dali.former_val = actual_val;
+ Dali->former_val = actual_val;
if(getDaliFlag() == DALI_ERROR)
{
enableDaliRxInterrupt();
@@ -284,12 +281,12 @@ bool get_DALIOUT(void)
*/
void sendDaliData(uint8_t firstByte, uint8_t secondByte)
{
- Dali.send_dali_data = firstByte << 8;
- Dali.send_dali_data += secondByte & 0xff;
- Dali.bit_count = 0;
- Dali.tick_count = 0;
+ Dali->send_dali_data = firstByte << 8;
+ Dali->send_dali_data += secondByte & 0xff;
+ Dali->bit_count = 0;
+ Dali->tick_count = 0;
- Dali.flag = DALI_SENDING_DATA;
+ Dali->flag = DALI_SENDING_DATA;
disableRxInterrupt();
}
@@ -306,67 +303,67 @@ void sendDaliData(uint8_t firstByte, uint8_t secondByte)
void send_tick(void)
{
// access to the routine just every 4 ticks = every half bit
- if ((Dali.tick_count & 0x03) == 0)
+ if ((Dali->tick_count & 0x03) == 0)
{
- if (Dali.tick_count < 160)
+ if (Dali->tick_count < 160)
{
// settling time between forward and backward frame
- if (Dali.tick_count < 24)
+ if (Dali->tick_count < 24)
{
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
// start of the start bit
- if (Dali.tick_count == 24)
+ if (Dali->tick_count == 24)
{
// GPIOB->ODR ^= GPIO_ODR_7;
set_DALIOUT(false);
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
// edge of the start bit
// 28 ticks = 28/9600 = 2,92ms = delay between forward and backward message frame
- if (Dali.tick_count == 28)
+ if (Dali->tick_count == 28)
{
set_DALIOUT(true);
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
// bit value (edge) selection
- bool bit_value = (bool)((Dali.send_dali_data >> (15 - Dali.bit_count)) & 0x01);
+ bool bit_value = (bool)((Dali->send_dali_data >> (15 - Dali->bit_count)) & 0x01);
// Every half bit -> Manchester coding
- if (!((Dali.tick_count - 24) & 0x0007))
+ if (!((Dali->tick_count - 24) & 0x0007))
{ // div by 8
if (get_DALIOUT() == bit_value) // former value of bit = new value of bit
set_DALIOUT((bool)(1 - bit_value));
}
// Generate edge for actual bit
- if (!((Dali.tick_count - 28) & 0x0007))
+ if (!((Dali->tick_count - 28) & 0x0007))
{
set_DALIOUT(bit_value);
- Dali.bit_count++;
+ Dali->bit_count++;
}
}
else
{ // end of data byte, start of stop bits
- if (Dali.tick_count == 160)
+ if (Dali->tick_count == 160)
{
set_DALIOUT(true); // start of stop bit
}
// end of stop bits, no settling time
- if (Dali.tick_count == 176)
+ if (Dali->tick_count == 176)
{
enableDaliRxInterrupt();
}
}
}
- Dali.tick_count++;
+ Dali->tick_count++;
return;
}
@@ -381,13 +378,17 @@ void DaliPreInit() {
digitalWrite(Pin(GPIO_DALI_TX), HIGH);
pinMode(Pin(GPIO_DALI_RX), INPUT);
- DALI_timer = timerBegin(DALI_TIMER, 13, true);
- timerAttachInterrupt(DALI_timer, &DALI_Tick_Handler, true);
- timerAlarmWrite(DALI_timer, 641, true);
+ Dali = (DALI*)calloc(1,sizeof(DALI));
+ if (!Dali) {
+ AddLog(LOG_LEVEL_INFO, PSTR("DLI: Memory allocation error"));
+ return;
+ }
+ Dali->timer = timerBegin(DALI_TIMER, 13, true);
+ timerAttachInterrupt(Dali->timer, &DALI_Tick_Handler, true);
+ timerAlarmWrite(Dali->timer, 641, true);
attachInterrupt(Pin(GPIO_DALI_RX), receiveDaliData, FALLING);
enableDaliRxInterrupt();
- Dali.present = true;
}
void DaliPwr(uint8_t val){
@@ -563,7 +564,7 @@ bool Xdrv89(uint8_t function)
{
DaliPreInit();
}
- else if (Dali.present)
+ else if (Dali)
{
switch (function)
{
From 4e98cbb387d619a2e4d93a785acecc81b680111a Mon Sep 17 00:00:00 2001
From: eeak
Date: Sat, 29 Oct 2022 16:09:09 +0300
Subject: [PATCH 094/319] moved D_CMND_xx to i18n.h
---
tasmota/include/i18n.h | 4 ++++
tasmota/language/af_AF.h | 2 --
tasmota/language/bg_BG.h | 2 --
tasmota/language/ca_AD.h | 2 --
tasmota/language/cs_CZ.h | 2 --
tasmota/language/de_DE.h | 2 --
tasmota/language/el_GR.h | 2 --
tasmota/language/en_GB.h | 2 --
tasmota/language/es_ES.h | 2 --
tasmota/language/fr_FR.h | 2 --
tasmota/language/fy_NL.h | 2 --
tasmota/language/he_HE.h | 2 --
tasmota/language/hu_HU.h | 2 --
tasmota/language/it_IT.h | 2 --
tasmota/language/ko_KO.h | 2 --
tasmota/language/nl_NL.h | 2 --
tasmota/language/pl_PL.h | 2 --
tasmota/language/pt_BR.h | 2 --
tasmota/language/pt_PT.h | 2 --
tasmota/language/ro_RO.h | 2 --
tasmota/language/ru_RU.h | 2 --
tasmota/language/sk_SK.h | 2 --
tasmota/language/sv_SE.h | 2 --
tasmota/language/tr_TR.h | 2 --
tasmota/language/uk_UA.h | 2 --
tasmota/language/vi_VN.h | 2 --
tasmota/language/zh_CN.h | 2 --
tasmota/language/zh_TW.h | 2 --
28 files changed, 4 insertions(+), 54 deletions(-)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 84c0a78a6..1c46f3df4 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -753,6 +753,10 @@
// Commands xdrv_60_shift595.ino - 74x595 family shift register driver
#define D_CMND_SHIFT595_DEVICE_COUNT "Shift595DeviceCount"
+// Commands xdrv_89_dali.ino
+#define D_CMND_DALI_POWER "power"
+#define D_CMND_DALI_DIMMER "dim"
+
// Commands xsns_02_analog.ino
#define D_CMND_ADCPARAM "AdcParam"
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 39dc3126b..53f836a14 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie Vandag"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 21ecbce73..784a15f90 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Консумация за днес"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 01cf177b1..c01ee0d66 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index f1fea69ec..eb3d4d797 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotřeba Dnes"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index df8a827b1..d4ba67d4a 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energie heute"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index 0d7500450..a7e79adf7 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Ενέργεια σήμερα"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index d59a97f01..392abdb0e 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index b75beec9a..62043d5c5 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energía Hoy"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 5f3eac5a3..3a26c486f 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xsns_03_energy.ino
#define D_ENERGY_TODAY "Énergie aujourd'hui"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index a5f22689a..4e2bb00a1 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Konsumpsje hjoed"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 31d969f78..afde4734d 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "צריכה יומית"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index c2204ea65..1d753de1b 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Mai energia"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 5db1e1220..15b933509 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia - oggi"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 7e85879cc..7fd6d1864 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "금일 전력 사용량"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index f2355a709..d0f96fe48 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Verbruik vandaag"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index c523cec6f..a4237e480 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia dzisiaj"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index b87b1a618..ed31fc1f9 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index c050785fa..e1bde2d58 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Consumo energético de hoje"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 77ca813dc..b9db344a1 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia de Azi"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index fd9c3a7ee..5e38b74f9 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Конфигурация DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Энергия Сегодня"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 8b1f107df..2565fd648 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Spotreba dnes"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index a603635c3..6c85c366f 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energi idag"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index 4c6d46b49..a32bd177a 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energy Today"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 1a6f34161..b786a6700 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Енергія Сьогодні"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index 7416d1dae..c054ed967 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Năng lượng tiêu thụ hôm nay"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 4f93019fc..63d885088 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用电量"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 641f8192c..30db4a4f1 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -515,8 +515,6 @@
#define D_SENSOR_DALI_RX "Dali RX"
#define D_SENSOR_DALI_TX "Dali TX"
#define D_CONFIGURE_DALI "Config DALI"
-#define D_CMND_DALI_POWER "power"
-#define D_CMND_DALI_DIMMER "dim"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "今日用電量"
From 06350618b7a312be04fc90578880e9c00ca78577 Mon Sep 17 00:00:00 2001
From: eeak
Date: Sat, 29 Oct 2022 16:12:10 +0300
Subject: [PATCH 095/319] cleanup tasmota_template.h
---
tasmota/include/tasmota_template.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 76977bde0..831115456 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -198,9 +198,7 @@ enum UserSelectablePins {
GPIO_ADE7953_RST, // ADE7953 Reset
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
-#ifdef ESP32
GPIO_DALI_RX, GPIO_DALI_TX, // Dali
-#endif
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -446,9 +444,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ADE7953_RST "|"
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
-#ifdef ESP32
D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
-#endif
;
const char kSensorNamesFixed[] PROGMEM =
From 7fac661b2eda447ccb6176aea61bfe4fe750888e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 29 Oct 2022 16:00:47 +0200
Subject: [PATCH 096/319] Update changelogs
---
CHANGELOG.md | 6 ++++--
RELEASENOTES.md | 4 ++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4b4db35d4..1ace4e9ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,14 +5,16 @@ All notable changes to this project will be documented in this file.
## [12.2.0.2]
### Added
+- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
### Breaking Changed
### Changed
-- Prepare for extended calibration and move some persistent data (PowerLow)
-- Tasmota ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
+- Prepare for two phase power calibration and move some persistent data (PowerLow)
+- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
### Fixed
+- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
### Removed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index a56da4e9f..3c44ef42c 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -112,17 +112,21 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
+- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
### Breaking Changed
### Changed
+- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
+- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
+
### Removed
From 314dbf5e6b498b6d37ed403bc517a7d1efac1eac Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 29 Oct 2022 19:08:06 +0200
Subject: [PATCH 097/319] Add support for second energy channel calibration
---
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 75 ++++++++++++-------
.../tasmota_xnrg_energy/xnrg_01_hlw8012.ino | 6 +-
.../tasmota_xnrg_energy/xnrg_02_cse7766.ino | 9 ++-
.../tasmota_xnrg_energy/xnrg_04_mcp39f501.ino | 8 +-
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 23 ++++--
.../tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 17 +++--
.../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 16 ++--
.../tasmota_xnrg_energy/xnrg_22_bl6523.ino | 60 +++++++--------
tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino | 11 ++-
9 files changed, 135 insertions(+), 90 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index f6e90ca2b..d0a308a16 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -637,11 +637,6 @@ void EnergyEverySecond(void)
* Commands
\*********************************************************************************************/
-void EnergyCommandCalResponse(uint32_t nvalue) {
- snprintf_P(XdrvMailbox.command, CMDSZ, PSTR("%sCal"), XdrvMailbox.command);
- ResponseCmndNumber(nvalue);
-}
-
void ResponseCmndEnergyTotalYesterdayToday(void) {
char value_chr[TOPSZ]; // Used by EnergyFormatIndex
char value2_chr[TOPSZ];
@@ -835,71 +830,101 @@ void CmndTariff(void) {
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
}
+void EnergyCommandCalSetResponse(uint32_t cal_type) {
+ if (XdrvMailbox.payload > 999) {
+ uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
+ if (channel) {
+ switch (cal_type) {
+ case 0: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
+ case 1: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
+ case 2: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
+ case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ }
+ } else {
+ switch (cal_type) {
+ case 0: Settings->energy_power_calibration = XdrvMailbox.payload; break;
+ case 1: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
+ case 2: Settings->energy_current_calibration = XdrvMailbox.payload; break;
+ case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ }
+ }
+ }
+ if (3 == cal_type) {
+ ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration);
+ } else {
+ uint32_t cal_array[2][3];
+ memcpy(&cal_array, &Settings->energy_power_calibration, 24);
+ if (2 == Energy.phase_count) {
+ ResponseAppend_P(PSTR("[%d,%d]}"), cal_array[0][cal_type], cal_array[1][cal_type]);
+ } else {
+ ResponseAppend_P(PSTR("%d}"), cal_array[0][cal_type]);
+ }
+ }
+}
+
+void EnergyCommandCalResponse(uint32_t cal_type) {
+ Response_P(PSTR("{\"%s\":"), XdrvMailbox.command);
+ EnergyCommandCalSetResponse(cal_type);
+}
+
+void EnergyCommandSetCalResponse(uint32_t cal_type) {
+ Response_P(PSTR("{\"%sCal\":"), XdrvMailbox.command);
+ EnergyCommandCalSetResponse(cal_type);
+}
+
void CmndPowerCal(void) {
Energy.command_code = CMND_POWERCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_power_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_power_calibration);
+ EnergyCommandCalResponse(0);
}
}
void CmndVoltageCal(void) {
Energy.command_code = CMND_VOLTAGECAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_voltage_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_voltage_calibration);
+ EnergyCommandCalResponse(1);
}
}
void CmndCurrentCal(void) {
Energy.command_code = CMND_CURRENTCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_current_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_current_calibration);
+ EnergyCommandCalResponse(2);
}
}
void CmndFrequencyCal(void) {
Energy.command_code = CMND_FREQUENCYCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- if (XdrvMailbox.payload > 999) {
- Settings->energy_frequency_calibration = XdrvMailbox.payload;
- }
- ResponseCmndNumber(Settings->energy_frequency_calibration);
+ EnergyCommandCalResponse(3);
}
}
void CmndPowerSet(void) {
Energy.command_code = CMND_POWERSET;
if (XnrgCall(FUNC_COMMAND)) { // Watt
- EnergyCommandCalResponse(Settings->energy_power_calibration);
+ EnergyCommandSetCalResponse(0);
}
}
void CmndVoltageSet(void) {
Energy.command_code = CMND_VOLTAGESET;
if (XnrgCall(FUNC_COMMAND)) { // Volt
- EnergyCommandCalResponse(Settings->energy_voltage_calibration);
+ EnergyCommandSetCalResponse(1);
}
}
void CmndCurrentSet(void) {
Energy.command_code = CMND_CURRENTSET;
if (XnrgCall(FUNC_COMMAND)) { // milliAmpere
- EnergyCommandCalResponse(Settings->energy_current_calibration);
+ EnergyCommandSetCalResponse(2);
}
}
void CmndFrequencySet(void) {
Energy.command_code = CMND_FREQUENCYSET;
if (XnrgCall(FUNC_COMMAND)) { // Hz
- EnergyCommandCalResponse(Settings->energy_frequency_calibration);
+ EnergyCommandSetCalResponse(3);
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
index 883dfdbb2..d28347af5 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
@@ -290,17 +290,17 @@ bool HlwCommand(void) {
}
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Hlw.cf_power_pulse_length ) {
- Settings->energy_power_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio;
+ XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf_power_pulse_length ) / Hlw.power_ratio;
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Hlw.cf1_voltage_pulse_length ) {
- Settings->energy_voltage_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio;
+ XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data) * 10) * Hlw.cf1_voltage_pulse_length ) / Hlw.voltage_ratio;
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Hlw.cf1_current_pulse_length) {
- Settings->energy_current_calibration = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio;
+ XdrvMailbox.payload = ((uint32_t)(CharToFloat(XdrvMailbox.data)) * Hlw.cf1_current_pulse_length) / Hlw.current_ratio;
}
}
else serviced = false; // Unknown command
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
index 296bd6520..6717304cf 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
@@ -63,7 +63,8 @@ void CseReceived(void) {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load
// 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W)
- // 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok
+ // 55 5A 02 F7 60 00 03 AB 00 40 10 02 60 5D 51 A6 58 03 E9 EF 71 0B 7A 36 - 55 = Ok, 71 = Ok, F1 = CF overflow, no problem
+ // 55 5A 02 F1 E8 00 07 9D 00 3F 3E 00 35 F8 50 DB 38 00 B2 A2 F1 D6 97 3E - CF overflow
// 55 5A 02 DB 40 00 03 25 00 3D 18 03 8E CD 4F 0A 60 2A 56 85 61 01 02 1A - OK voltage
// 55 5A 02 DB 40 07 17 1D 00 3D 18 03 8E CD 4F 0A 60 2B EF EA 61 01 02 2C - Wrong voltage
@@ -256,17 +257,17 @@ bool CseCommand(void) {
if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Cse.power_cycle) {
- Settings->energy_power_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF;
+ XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.power_cycle) / CSE_PREF;
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Cse.voltage_cycle) {
- Settings->energy_voltage_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF;
+ XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.voltage_cycle) / CSE_UREF;
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Cse.current_cycle) {
- Settings->energy_current_calibration = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000;
+ XdrvMailbox.payload = (unsigned long)(CharToFloat(XdrvMailbox.data) * Cse.current_cycle) / 1000;
}
}
else serviced = false; // Unknown command
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
index 7601731a4..807176c64 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
@@ -602,7 +602,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_active_power) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 100);
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
- Settings->energy_power_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_POWER;
McpGetCalibration();
}
@@ -612,7 +612,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_voltage_rms) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
if ((value > 1000) && (value < 2600)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_VOLTAGE;
McpGetCalibration();
}
@@ -622,7 +622,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_current_rms) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 10);
if ((value > 100) && (value < 80000)) { // Between 10mA and 8A
- Settings->energy_current_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_CURRENT;
McpGetCalibration();
}
@@ -632,7 +632,7 @@ bool McpCommand(void)
if (XdrvMailbox.data_len && mcp_line_frequency) {
value = (unsigned long)(CharToFloat(XdrvMailbox.data) * 1000);
if ((value > 45000) && (value < 65000)) { // Between 45Hz and 65Hz
- Settings->energy_frequency_calibration = value;
+ XdrvMailbox.payload = value;
mcp_calibrate |= MCP_CALIBRATE_FREQUENCY;
McpGetFrequency();
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 49686aca8..4cf12061b 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -463,12 +463,16 @@ void Ade7953GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
+ float power_calibration = ((channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration) / 10;
+ float voltage_calibration = (channel) ? Settings->energy_voltage_calibration2 : Settings->energy_voltage_calibration;
+ float current_calibration = ((channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration) * 10;
+
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
if (ADE7953_SHELLY_EM == Ade7953.model) {
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
@@ -478,12 +482,12 @@ void Ade7953GetData(void) {
Energy.reactive_power[channel] *= -1;
}
}
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : current_calibration;
Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider;
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
}
@@ -657,6 +661,9 @@ void Ade7953DrvInit(void) {
Settings->energy_power_calibration = ADE7953_PREF;
Settings->energy_voltage_calibration = ADE7953_UREF;
Settings->energy_current_calibration = ADE7953_IREF;
+ Settings->energy_power_calibration2 = ADE7953_PREF;
+ Settings->energy_voltage_calibration2 = ADE7953_UREF;
+ Settings->energy_current_calibration2 = ADE7953_IREF;
}
Ade7953Defaults();
@@ -705,21 +712,21 @@ bool Ade7953Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
- Settings->energy_power_calibration = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
+ XdrvMailbox.payload = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) {
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
+ XdrvMailbox.payload = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.current_rms[channel]) {
if ((value > 2000) && (value < 1000000)) { // Between 20mA and 10A
- Settings->energy_current_calibration = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
+ XdrvMailbox.payload = ((Ade7953.current_rms[channel] * 100) / value) * 100; // 0.00 mA
}
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
index f73a276b8..dd44ac14f 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
@@ -193,9 +193,11 @@ void Bl09XXUpdateEnergy() {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature);
#endif
for (uint32_t chan = 0; chan < Energy.phase_count; chan++) {
- if (Bl09XX.power[chan] > Settings->energy_power_calibration) { // We need at least 1W
- Energy.active_power[chan] = (float)Bl09XX.power[chan] / Settings->energy_power_calibration;
- Energy.current[chan] = (float)Bl09XX.current[chan] / Settings->energy_current_calibration;
+ uint32_t power_calibration = (chan) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
+ uint32_t current_calibration = (chan) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
+ if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W
+ Energy.active_power[chan] = (float)Bl09XX.power[chan] / power_calibration;
+ Energy.current[chan] = (float)Bl09XX.current[chan] / current_calibration;
} else {
Energy.active_power[chan] = 0;
Energy.current[chan] = 0;
@@ -289,6 +291,9 @@ void Bl09XXInit(void) {
Settings->energy_voltage_calibration = bl09xx_uref[Bl09XX.model];
Settings->energy_current_calibration = bl09xx_iref[Bl09XX.model];
Settings->energy_power_calibration = bl09xx_pref[Bl09XX.model];
+ Settings->energy_voltage_calibration2 = bl09xx_uref[Bl09XX.model];
+ Settings->energy_current_calibration2 = bl09xx_iref[Bl09XX.model];
+ Settings->energy_power_calibration2 = bl09xx_pref[Bl09XX.model];
}
if ((BL0940_MODEL == Bl09XX.model) && (Settings->energy_current_calibration < (BL0940_IREF / 20))) {
Settings->energy_current_calibration *= 100;
@@ -357,17 +362,17 @@ bool Bl09XXCommand(void) {
if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Bl09XX.power[channel]) {
- Settings->energy_power_calibration = (Bl09XX.power[channel] * 100) / value;
+ XdrvMailbox.payload = (Bl09XX.power[channel] * 100) / value;
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Bl09XX.voltage) {
- Settings->energy_voltage_calibration = (Bl09XX.voltage * 100) / value;
+ XdrvMailbox.payload = (Bl09XX.voltage * 100) / value;
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && Bl09XX.current[channel]) {
- Settings->energy_current_calibration = (Bl09XX.current[channel] * 100) / value;
+ XdrvMailbox.payload = (Bl09XX.current[channel] * 100) / value;
}
}
else serviced = false; // Unknown command
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
index ec6647a76..02c13e121 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
@@ -226,6 +226,8 @@ bool Cse7761ChipInit(void) {
Settings->energy_voltage_calibration = Cse7761Ref(RmsUC);
Settings->energy_current_calibration = Cse7761Ref(RmsIAC);
Settings->energy_power_calibration = Cse7761Ref(PowerPAC);
+ Settings->energy_current_calibration2 = Settings->energy_current_calibration;
+ Settings->energy_power_calibration2 = Settings->energy_power_calibration;
}
// Just to fix intermediate users
if (Settings->energy_frequency_calibration < CSE7761_FREF / 2) {
@@ -466,15 +468,17 @@ void Cse7761GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
+ uint32_t power_calibration = (channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
// Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
- Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / Settings->energy_power_calibration; // W
+ Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
+ uint32_t current_calibration = (channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
// Current = RmsIA * RmsIAC / 0x800000
// Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
- Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / Settings->energy_current_calibration; // A
+ Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A
CSE7761Data.energy[channel] += Energy.active_power[channel];
CSE7761Data.energy_update[channel]++;
}
@@ -616,7 +620,7 @@ bool Cse7761Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.active_power[channel]) {
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
- Settings->energy_power_calibration = ((CSE7761Data.active_power[channel]) / value) * 100;
+ XdrvMailbox.payload = ((CSE7761Data.active_power[channel]) / value) * 100;
}
}
}
@@ -627,7 +631,7 @@ bool Cse7761Command(void) {
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.voltage_rms) {
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
- Settings->energy_voltage_calibration = (CSE7761Data.voltage_rms * 100) / value;
+ XdrvMailbox.payload = (CSE7761Data.voltage_rms * 100) / value;
}
}
}
@@ -638,7 +642,7 @@ bool Cse7761Command(void) {
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.current_rms[channel]) {
if ((value > 1000) && (value < 1000000)) { // Between 10mA and 10A
- Settings->energy_current_calibration = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000;
+ XdrvMailbox.payload = ((CSE7761Data.current_rms[channel] * 100) / value) * 1000;
}
}
}
@@ -650,7 +654,7 @@ bool Cse7761Command(void) {
else if (CMND_FREQUENCYSET == Energy.command_code) {
if (XdrvMailbox.data_len && CSE7761Data.frequency) {
if ((value > 4500) && (value < 6500)) { // Between 45.00Hz and 65.00Hz
- Settings->energy_frequency_calibration = (CSE7761Data.frequency * 8 * value) / 100;
+ XdrvMailbox.payload = (CSE7761Data.frequency * 8 * value) / 100;
}
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
index f9714b052..c87fd2a30 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
@@ -22,24 +22,24 @@
/*********************************************************************************************\
* Chinese BL6523 based Watt hour meter
*
- * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
+ * This meter provides accurate Voltage, Frequency, Ampere, Wattage, Power Factor, KWh
* To use Tasmota the user needs to add an ESP8266 or ESP32
* Three lines need to be connected via 1KOhh resistors to ESP from the main board(RX,TX GND)
- *
+ *
* Connection Eg (ESP8266) - Non - Isolated:
* BL6523 RX ->1KOhm-> ESP IO4(D2) (Should be Input Capable)
* BL6523 TX ->1KOhm-> ESP IO5(D1) (Should be Input Capable)
* BL6523 GND -> ESP GND
- *
+ *
* Connection Eg (ESP32) - Non - Isolated:
* BL6523 RX ->1KOhm-> ESP IO4 (Should be Input Capable)
* BL6523 TX ->1KOhm-> ESP IO5 (Should be Input Capable)
* BL6523 GND -> ESP GND
- *
+ *
* To build add the below to user_config_override.h
* #define USE_ENERGY_SENSOR // Enable Energy sensor framework
* #define USE_BL6523 // Add support for Chinese BL6523 based Watt hour meter (+1k code)¸
- *
+ *
* After Installation use the below template sample:
* {"NAME":"BL6523 Smart Meter","GPIO":[0,0,0,0,7488,7520,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18}
\*********************************************************************************************/
@@ -106,7 +106,7 @@ bool Bl6523ReadData(void)
Bl6523RxSerial->flush(); // Make room for another burst
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, rx_buffer, BL6523_RX_DATASET_SIZE);
-
+
i=0;
while (Bl6523TxSerial->available() < BL6523_TX_DATASET_SIZE)
{
@@ -116,15 +116,15 @@ bool Bl6523ReadData(void)
break;
}
}
-
+
uint8_t tx_buffer[BL6523_TX_DATASET_SIZE];
Bl6523TxSerial->readBytes(tx_buffer, BL6523_TX_DATASET_SIZE);
Bl6523TxSerial->flush(); // Make room for another burst
-
+
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, tx_buffer, BL6523_TX_DATASET_SIZE);
-
+
/* Checksum: (Addr+Data_L+Data_M+Data_H) & 0xFF, then byte invert */
uint8_t crc = rx_buffer[1]; //Addr
for (uint32_t i = 0; i < (BL6523_TX_DATASET_SIZE - 1); i++)
@@ -136,15 +136,15 @@ bool Bl6523ReadData(void)
if (crc != tx_buffer[BL6523_TX_DATASET_SIZE - 1])
{
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL6:" D_CHECKSUM_FAILURE));
- Bl6523TxSerial->flush();
- Bl6523RxSerial->flush();
+ Bl6523TxSerial->flush();
+ Bl6523RxSerial->flush();
return false;
}
/* WRITE DATA (format: command(write->0xCA) address data_low data_mid data_high checksum )
WRITE Sample(RX):
RX: CA 3E 55 00 00 6C (WRPROT - allow)
-RX: CA 14 00 00 10 DB (MODE)
+RX: CA 14 00 00 10 DB (MODE)
RX: CA 15 04 00 00 E6 (GAIN - IB 16x gain )
RX: CA 19 08 00 00 DE (WA_CFDIV )
RX: CA 3E AA 00 00 17 (WRPROT - disable)
@@ -154,8 +154,8 @@ RX: CA 3E AA 00 00 17 (WRPROT - disable)
READ Sample(RX-TX) Data:
RX: 35 05 TX: E4 00 00 16 (IA rms )
RX: 35 07 TX: D5 A3 2E 52 (V rms )
-RX: 35 09 TX: F0 FB 02 09 (FREQ)
-RX: 35 0A TX: 00 00 00 F5 (WATT)
+RX: 35 09 TX: F0 FB 02 09 (FREQ)
+RX: 35 0A TX: 00 00 00 F5 (WATT)
RX: 35 08 TX: 00 00 00 F7 (PF)
RX: 35 0C TX: 00 00 00 F3 (WATT_HR)
*/
@@ -169,7 +169,7 @@ switch(rx_buffer[1]) {
break;
case BL6523_REG_FREQ :
Energy.frequency[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_frequency_calibration; // 50.0 Hz
- break;
+ break;
case BL6523_REG_WATTS :
Energy.active_power[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / Settings->energy_power_calibration; // -196.3 W
break;
@@ -181,7 +181,7 @@ switch(rx_buffer[1]) {
powf_buf = ((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]);
powf_word = (powf_buf >> 23) ? ~(powf_buf & 0x7fffff) : powf_buf & 0x7fffff; //Extract the 23 bits and invert if sign bit(24) is set
for (int i = 0; i < 23; i++){ // Accumulate powf from 23 bits
- powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
+ powf += ((powf_word >> (22-i)) * pow(2,(0-(i+1))));
powf_word = powf_word & (0x7fffff >> (1+i));
}
powf = (powf_buf >> 23) ? (0.0f - (powf)) : powf; // Negate if sign bit(24) is set
@@ -190,8 +190,8 @@ switch(rx_buffer[1]) {
case BL6523_REG_WATTHR :
Energy.import_active[SINGLE_PHASE] = (float)((tx_buffer[2] << 16) | (tx_buffer[1] << 8) | tx_buffer[0]) / ( Settings->energy_power_calibration - BL6523_PWHRREF_D ); // 6.216 kWh => used in EnergyUpdateTotal()
break;
- default :
- break;
+ default :
+ break;
}
Energy.data_valid[SINGLE_PHASE] = 0;
EnergyUpdateTotal();
@@ -201,7 +201,7 @@ switch(rx_buffer[1]) {
Bl6523.discovery_triggered = true;
}
return true;
-
+
}
/*********************************************************************************************/
@@ -216,7 +216,7 @@ void Bl6523Update(void)
{
if (Bl6523.valid) {
Bl6523.valid--;
- }
+ }
}
}
@@ -224,7 +224,7 @@ void Bl6523Update(void)
void Bl6523Init(void)
{
-
+
Bl6523.type = 0;
Bl6523RxSerial = new TasmotaSerial(Pin(GPIO_BL6523_RX), -1, 1);
Bl6523TxSerial = new TasmotaSerial(Pin(GPIO_BL6523_TX), -1, 1);
@@ -247,7 +247,7 @@ void Bl6523Init(void)
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:Init Failure!" ));
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
-
+
}
bool Bl6523Command(void) {
@@ -262,28 +262,28 @@ bool Bl6523Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 100) && (abs_value < 200000)) { // Between 1.00 and 2000.00 W
- Settings->energy_power_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 10000) && (abs_value < 26000)) { // Between 100.00 and 260.00 V
- Settings->energy_voltage_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 1000) && (abs_value < 1000000)) { // Between 10.00 mA and 10.00000 A
- Settings->energy_current_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_FREQUENCYSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value > 4500) && (abs_value < 6500)) { // Between 45.00 and 65.00 Hz
- Settings->energy_frequency_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
@@ -323,7 +323,7 @@ void Bl6523DrvInit(void)
AddLog(LOG_LEVEL_DEBUG, PSTR("BL6:PreInit Failure!" ));
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
-
+
}
/*********************************************************************************************\
@@ -333,7 +333,7 @@ void Bl6523DrvInit(void)
bool Xnrg22(uint8_t function)
{
bool result = false;
-
+
switch (function)
{
case FUNC_EVERY_250_MSECOND:
@@ -341,7 +341,7 @@ bool Xnrg22(uint8_t function)
break;
case FUNC_COMMAND:
result = Bl6523Command();
- break;
+ break;
case FUNC_INIT:
Bl6523Init();
break;
@@ -349,7 +349,7 @@ bool Xnrg22(uint8_t function)
Bl6523DrvInit();
break;
}
-
+
return result;
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
index 065c909af..b77474a12 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
@@ -84,28 +84,28 @@ bool NrgDummyCommand(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 100) && (abs_value <= 16000000)) { // Between 1.00 and 160000.00 W
- Settings->energy_power_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 10000) && (abs_value <= 40000)) { // Between 100.00 and 400.00 V
- Settings->energy_voltage_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_CURRENTSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 1000) && (abs_value <= 40000000)) { // Between 10.00 mA and 400.00000 A
- Settings->energy_current_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
else if (CMND_FREQUENCYSET == Energy.command_code) {
if (XdrvMailbox.data_len) {
if ((abs_value >= 4500) && (abs_value <= 6500)) { // Between 45.00 and 65.00 Hz
- Settings->energy_frequency_calibration = abs_value;
+ XdrvMailbox.payload = abs_value;
}
}
}
@@ -134,6 +134,9 @@ void NrgDummyDrvInit(void) {
Settings->energy_voltage_calibration = NRG_DUMMY_UREF;
Settings->energy_current_calibration = NRG_DUMMY_IREF;
Settings->energy_power_calibration = NRG_DUMMY_PREF;
+ Settings->energy_voltage_calibration2 = NRG_DUMMY_UREF;
+ Settings->energy_current_calibration2 = NRG_DUMMY_IREF;
+ Settings->energy_power_calibration2 = NRG_DUMMY_PREF;
}
Energy.phase_count = (TasmotaGlobal.devices_present < ENERGY_MAX_PHASES) ? TasmotaGlobal.devices_present : ENERGY_MAX_PHASES;
From 1378d573772f7b9976a7b1013b3b1f21e3a5ac9d Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sat, 29 Oct 2022 20:13:00 +0200
Subject: [PATCH 098/319] allow webcam to reuse and share I2C bus 2
---
.../tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
index ba4dbab50..11e57f2c4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
@@ -191,8 +191,9 @@ bool WcPinUsed(void) {
}
if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) ||
!PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) ||
- !PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) {
- pin_used = false;
+ ((!PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) && !TasmotaGlobal.i2c_enabled_2) // preferred option is to reuse and share I2Cbus 2
+ ) {
+ pin_used = false;
}
return pin_used;
}
@@ -341,8 +342,14 @@ uint32_t WcSetup(int32_t fsiz) {
config.pin_pclk = Pin(GPIO_WEBCAM_PCLK); // PCLK_GPIO_NUM;
config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC); // VSYNC_GPIO_NUM;
config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM;
- config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM;
- config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM;
+ config.pin_sccb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM; - unset to use shared I2C bus 2
+ config.pin_sccb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM;
+ if(TasmotaGlobal.i2c_enabled_2){ // configure SIOD and SIOC as SDA,2 and SCL,2
+ config.sccb_i2c_port = 1; // reuse initialized bus 2, can be shared now
+ if(config.pin_sccb_sda < 0){ // GPIO_WEBCAM_SIOD must not be set to really make it happen
+ AddLog(LOG_LEVEL_INFO, PSTR("CAM: use I2C bus 2"));
+ }
+ }
config.pin_pwdn = Pin(GPIO_WEBCAM_PWDN); // PWDN_GPIO_NUM;
config.pin_reset = Pin(GPIO_WEBCAM_RESET); // RESET_GPIO_NUM;
AddLog(LOG_LEVEL_DEBUG, PSTR("CAM: Template pin config"));
From f861e8330a8ee314573cb0e1a5c01063f35ee54d Mon Sep 17 00:00:00 2001
From: barbudor
Date: Sat, 29 Oct 2022 21:38:22 +0200
Subject: [PATCH 099/319] dingtian driver take 1
---
tasmota/include/tasmota_template.h | 11 +
tasmota/language/af_AF.h | 5 +
tasmota/language/bg_BG.h | 5 +
tasmota/language/ca_AD.h | 5 +
tasmota/language/cs_CZ.h | 5 +
tasmota/language/de_DE.h | 5 +
tasmota/language/el_GR.h | 5 +
tasmota/language/en_GB.h | 5 +
tasmota/language/es_ES.h | 5 +
tasmota/language/fr_FR.h | 5 +
tasmota/language/fy_NL.h | 5 +
tasmota/language/he_HE.h | 5 +
tasmota/language/hu_HU.h | 5 +
tasmota/language/it_IT.h | 5 +
tasmota/language/ko_KO.h | 5 +
tasmota/language/nl_NL.h | 5 +
tasmota/language/pl_PL.h | 5 +
tasmota/language/pt_BR.h | 5 +
tasmota/language/pt_PT.h | 5 +
tasmota/language/ro_RO.h | 5 +
tasmota/language/ru_RU.h | 5 +
tasmota/language/sk_SK.h | 5 +
tasmota/language/sv_SE.h | 5 +
tasmota/language/tr_TR.h | 5 +
tasmota/language/uk_UA.h | 5 +
tasmota/language/vi_VN.h | 5 +
tasmota/language/zh_CN.h | 5 +
tasmota/language/zh_TW.h | 5 +
.../xdrv_90_dingtian_relay.ino | 208 ++++++++++++++++++
29 files changed, 354 insertions(+)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 869e92a8c..64da087d2 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -198,6 +198,7 @@ enum UserSelectablePins {
GPIO_ADE7953_RST, // ADE7953 Reset
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
+ GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -443,6 +444,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ADE7953_RST "|"
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
+ D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|"
;
const char kSensorNamesFixed[] PROGMEM =
@@ -457,6 +459,7 @@ const char kSensorNamesFixed[] PROGMEM =
#define MAX_SM2135_DAT 10
#define MAX_SM2335_DAT 16
#define MAX_DSB 4
+#define MAX_DINGTIAN_SHIFT 4
const uint16_t kGpioNiceList[] PROGMEM = {
GPIO_NONE, // Not used
@@ -1097,6 +1100,14 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_SHIFT595_OE),
AGPIO(GPIO_SHIFT595_SER),
#endif
+
+#if defined (ESP32) && defined(USE_DINGTIAN_RELAY)
+ AGPIO(GPIO_DINGTIAN_CLK) + MAX_DINGTIAN_SHIFT, // Dingtian Relay board - 8,16,24 or 32 relays & inputs
+ AGPIO(GPIO_DINGTIAN_SDI),
+ AGPIO(GPIO_DINGTIAN_Q7),
+ AGPIO(GPIO_DINGTIAN_PL),
+ AGPIO(GPIO_DINGTIAN_RCK),
+#endif
};
/*-------------------------------------------------------------------------------------------*\
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 58b48a17a..3f1be7cb8 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 968746cd4..906634768 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Дебитомер"
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index 26bafafd8..298302d63 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Cabal"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index 2d32dcc9a..9c610b11c 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index 05f940706..7d17dc86a 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index d7cdbfe65..d08787942 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index ea85e0861..48e822ae2 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index fa8dd2b67..741a7a03f 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 3364ff482..f5882312e 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 1e1a25927..fe2966aad 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index 4db4cc9ff..369ce1d51 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index d90312b00..03afbab60 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 99301cc0e..5a510d64f 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 - RCLK"
#define D_GPIO_SHIFT595_OE "74x595 - OE"
#define D_GPIO_SHIFT595_SER "74x595 - SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x - TX"
#define D_SENSOR_CM11_RX "CM110x - RX"
#define D_SENSOR_FLOWRATEMETER "Portata"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 5554f07a0..7a2e508f3 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 960a8fcf2..3853c69b7 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 1157da535..9eb7e64bf 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index fe96b16b8..8ea175cca 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 3607f8252..c9bc5153b 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index f51f0d07a..0d8cca5bc 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index d45530605..2354947c0 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 945bd72c1..1afb86018 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index ffc3e2764..3b80797ad 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index a19995a43..7f5ffac7e 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index 8e832b9d8..510a975fb 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index f87ba1029..8e0837bd0 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 348718091..26b7aa758 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 50c8c5dfb..2ecde2dce 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -893,6 +893,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 RCLK"
#define D_GPIO_SHIFT595_OE "74x595 OE"
#define D_GPIO_SHIFT595_SER "74x595 SER"
+#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
#define D_SENSOR_CM11_TX "CM110x TX"
#define D_SENSOR_CM11_RX "CM110x RX"
#define D_SENSOR_FLOWRATEMETER "Flowrate"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
new file mode 100644
index 000000000..d198f2cc5
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
@@ -0,0 +1,208 @@
+/*
+ xdrv_90_dingtian_relay.ino - Dingtian 8, 16, 24 and 32 relays board based on 74x595+74x165
+
+ Copyright (C) 2021 Barbudor
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef ESP32
+#ifdef USE_DINGTIAN_RELAY
+
+#define XDRV_90 90
+
+/********************************************************************************************************
+ * Global private data
+ */
+
+struct DINGTIAN_DATA {
+ uint32_t outputs; // keep ouputs state
+ uint32_t last_inputs; // previous inputs state
+ uint8_t count; // number of relay and input (8 * numver of shift registers)
+ uint8_t first; // index of 1st Tasmota relay assigned to 1st Dingtian relays
+ // pins
+ uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck;
+} *Dingtian = nullptr;
+
+
+/********************************************************************************************************
+ * Low level operations
+ */
+
+uint32_t DingtianReadWrite(uint32_t outputs)
+{
+ uint32_t inputs = 0;
+ uint32_t in_bit = 1;
+
+ // setup
+ digitalWrite(Dingtian->pin_rck, 0); // rclk and clkinh to 0
+ digitalWrite(Dingtian->pin_pl, 1); // load inputs in '165, ready for shift-in (side effect '595 in tri-state)
+ for ( int i = Dingtian->count ; i > 0 ; i-- ) {
+ // relay out to '595
+ digitalWrite(Dingtian->pin_sdi, outputs & 1);
+ outputs >>= 1;
+ // input from '165
+ inputs |= digitalRead(Dingtian->pin_q7) ? in_bit : 0;
+ in_bit <<= 1;
+ // generate CLK pulse
+ digitalWrite(Dingtian->pin_clk, 1);
+ digitalWrite(Dingtian->pin_clk, 0);
+ }
+ // ending
+ digitalWrite(Dingtian->pin_rck, 1); // rclk pulse to load '595 into output registers
+ digitalWrite(Dingtian->pin_pl, 0); // re-enable '595 ouputs
+
+ return inputs;
+}
+
+/********************************************************************************************************
+ * Driver initialisation
+ */
+
+#define DINGTIAN_SET_OUTPUT(pin,value) { pinMode((pin), OUTPUT); digitalWrite((pin), (value)); }
+#define DINGTIAN_SET_INPUT(pin) { pinMode((pin), INPUT); }
+
+void DingtianInit(void) {
+ if (PinUsed(GPIO_DINGTIAN_CLK, GPIO_ANY) && PinUsed(GPIO_DINGTIAN_SDI) && PinUsed(GPIO_DINGTIAN_Q7)
+ && PinUsed(GPIO_DINGTIAN_PL) && PinUsed(GPIO_DINGTIAN_RCK)) {
+ // allocate Dingtian data structure
+ Dingtian = (struct DINGTIAN_DATA*)calloc(1, sizeof(struct DINGTIAN_DATA));
+ if (Dingtian) {
+ // get pins
+ Dingtian->pin_clk = Pin(GPIO_DINGTIAN_CLK, GPIO_ANY); // shift clock : 595's SCLK & 165's CLK
+ Dingtian->pin_sdi = Pin(GPIO_DINGTIAN_SDI); // Serial out : 595's SER
+ Dingtian->pin_q7 = Pin(GPIO_DINGTIAN_Q7); // Serial in : 165's Q7
+ Dingtian->pin_pl = Pin(GPIO_DINGTIAN_PL); // Input load : 595's nOE & 165's PL (or SH/LD on some datasheet)
+ Dingtian->pin_rck = Pin(GPIO_DINGTIAN_RCK); // Output load : 595's RCLK & 165's CLKINH
+ // number of shift registers is the CLK index
+ Dingtian->count = ((GetPin(Dingtian->pin_clk) - AGPIO(GPIO_DINGTIAN_CLK)) + 1) * 8;
+
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: clk:%d, sdi:%d, q7:%d, pl:%d, rck:%d, count:%d"),
+ Dingtian->pin_clk, Dingtian->pin_sdi, Dingtian->pin_q7, Dingtian->pin_pl, Dingtian->pin_rck, Dingtian->count);
+
+ DINGTIAN_SET_OUTPUT(Dingtian->pin_clk, 0);
+ DINGTIAN_SET_OUTPUT(Dingtian->pin_sdi, 0);
+ DINGTIAN_SET_INPUT( Dingtian->pin_q7);
+ DINGTIAN_SET_OUTPUT(Dingtian->pin_pl, 0);
+ DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0);
+
+ Dingtian->first = TasmotaGlobal.devices_present;
+ TasmotaGlobal.devices_present += Dingtian->count;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, Dingtian->first + Dingtian->count);
+ }
+ }
+}
+
+/********************************************************************************************************
+ * Driver operations
+ */
+
+void DingtianLoop()
+{
+ uint32_t inputs = DingtianReadWrite(Dingtian->outputs);
+ uint32_t last_inputs = Dingtian->last_inputs;
+ Dingtian->last_inputs = inputs;
+ if (inputs != last_inputs) {
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DNGT: inputs=0x%08X, last=0x%08X"), inputs, last_inputs);
+ bool first_done = false;
+ ResponseTime_P(PSTR(",\"DINGTIAN_CHG\":{"));
+ for (int i = 0 ; i < Dingtian->count ; i++, last_inputs>>=1, inputs>>=1) {
+ if ((last_inputs & 1) != (inputs & 1)) {
+ if (first_done) ResponseAppend_P(PSTR(","));
+ ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, (inputs & 1));
+ //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("\"IN%d\":%d"), i +1, (inputs & 1));
+ first_done = true;
+ }
+ }
+ ResponseAppend_P(PSTR("}}"));
+ if (first_done) {
+ MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR("DINGTIAN_CHG"));
+ }
+ }
+}
+
+void DingtianSetPower(void)
+{
+ // store relay status in structure
+ Dingtian->outputs = (XdrvMailbox.index >> Dingtian->first) & ~(0xFFFF << Dingtian->count);
+ //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DNGT: outputs=0x%08X"), Dingtian->outputs);
+ //DingtianLoop();
+}
+
+/********************************************************************************************************
+ * Driver Results
+ */
+
+const char HTTP_DINGTIAN_INPUTS[] PROGMEM = "{s}DINGTIAN " D_SENSOR_INPUT "%d.." D_SENSOR_INPUT "%d{m}%s{e}";
+
+void DingtianShow(bool json)
+{
+ if (json) {
+ bool first_done = false;
+ ResponseAppend_P(PSTR(",\"DINGTIAN\":{"));
+ for (int i = 0 ; i < Dingtian->count ; i++) {
+ if (first_done) ResponseAppend_P(PSTR(","));
+ ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, bitRead(Dingtian->last_inputs, i));
+ first_done = true;
+ }
+ ResponseAppend_P(PSTR("}"));
+ }
+#ifdef USE_WEBSERVER
+ else {
+ char input_str[9];
+ for (int block_input = 0 ; block_input < Dingtian->count ; block_input += 8 ) {
+ for (int i = 0 ; i < 8 ; i++ )
+ input_str[i] = '0' + bitRead(Dingtian->last_inputs, block_input +i);
+ input_str[8] = '\0';
+ WSContentSend_P(HTTP_DINGTIAN_INPUTS, block_input, block_input +7, input_str);
+ }
+ }
+#endif
+}
+
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xdrv90(uint8_t function) {
+ bool result = false;
+
+ if (FUNC_PRE_INIT == function) {
+ DingtianInit();
+ } else if (Dingtian) {
+ switch (function) {
+ case FUNC_SET_POWER:
+ DingtianSetPower();
+ break;
+ //case FUNC_EVERY_50_MSECOND:
+ case FUNC_EVERY_250_MSECOND:
+ DingtianLoop();
+ break;
+ case FUNC_JSON_APPEND:
+ DingtianShow(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ DingtianShow(0);
+ break;
+#endif // USE_WEBSERVER
+
+ }
+ }
+ return result;
+}
+
+#endif // USE_DINGTIAN_RELAY
+#endif // ESP32
From 5711fe65a29cd61d35a4ddfdd34b001de95b7565 Mon Sep 17 00:00:00 2001
From: bovirus <1262554+bovirus@users.noreply.github.com>
Date: Sun, 30 Oct 2022 10:17:01 +0100
Subject: [PATCH 100/319] Update italian language
---
tasmota/language/it_IT.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 15b933509..05dc90c7e 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele.
*
- * Updated until v9.4.0.1 - Last update 05.10.2022
+ * Updated until v9.4.0.1 - Last update 30.10.2022
\*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@@ -512,9 +512,9 @@
#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizzazione parametri Zigbee, controlla con \"ZbConfig\""
// xdrv_89_dali.ino
-#define D_SENSOR_DALI_RX "Dali RX"
-#define D_SENSOR_DALI_TX "Dali TX"
-#define D_CONFIGURE_DALI "Config DALI"
+#define D_SENSOR_DALI_RX "Dali - RX"
+#define D_SENSOR_DALI_TX "Dali - TX"
+#define D_CONFIGURE_DALI "DALI - Config"
// xdrv_03_energy.ino
#define D_ENERGY_TODAY "Energia - oggi"
From cd14c15c41fa6e32cb3c3d298de10b19e3fb6847 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sun, 30 Oct 2022 11:03:05 +0100
Subject: [PATCH 101/319] rm cam_hal.h...
since not needed anymore with core 2.0.5.2
---
lib/default/headers/cam_hal.h | 60 -----------------------------------
1 file changed, 60 deletions(-)
delete mode 100644 lib/default/headers/cam_hal.h
diff --git a/lib/default/headers/cam_hal.h b/lib/default/headers/cam_hal.h
deleted file mode 100644
index c8e38ed47..000000000
--- a/lib/default/headers/cam_hal.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#pragma once
-
-#include "esp_camera.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @brief Uninitialize the lcd_cam module
- *
- * @param handle Provide handle pointer to release resources
- *
- * @return
- * - ESP_OK Success
- * - ESP_FAIL Uninitialize fail
- */
-esp_err_t cam_deinit(void);
-
-/**
- * @brief Initialize the lcd_cam module
- *
- * @param config Configurations - see lcd_cam_config_t struct
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Parameter error
- * - ESP_ERR_NO_MEM No memory to initialize lcd_cam
- * - ESP_FAIL Initialize fail
- */
-esp_err_t cam_init(const camera_config_t *config);
-
-esp_err_t cam_config(const camera_config_t *config, framesize_t frame_size, uint16_t sensor_pid);
-
-void cam_stop(void);
-
-void cam_start(void);
-
-camera_fb_t *cam_take(TickType_t timeout);
-
-void cam_give(camera_fb_t *dma_buffer);
-
-#ifdef __cplusplus
-}
-#endif
From 41b65fd6b73b3fbe51857e3522e28a3e61a5603c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 30 Oct 2022 11:15:17 +0100
Subject: [PATCH 102/319] Add support for two phase power calibration
Add support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
---
CHANGELOG.md | 3 +-
RELEASENOTES.md | 1 +
tasmota/tasmota_support/settings.ino | 6 +-
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 61 ++++++++++++-------
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 6 +-
.../tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 4 +-
.../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 4 +-
tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino | 16 +++--
8 files changed, 64 insertions(+), 37 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ace4e9ac..eeeab257e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,11 +6,12 @@ All notable changes to this project will be documented in this file.
## [12.2.0.2]
### Added
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
+- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
### Breaking Changed
### Changed
-- Prepare for two phase power calibration and move some persistent data (PowerLow)
+- Move some persistent data (PowerLow)
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
### Fixed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3c44ef42c..2c6521331 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,6 +109,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.2
### Added
+- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index bf1f9ba63..ecfe30063 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -45,7 +45,7 @@ void RtcSettingsSave(void) {
if (RTC_MEM_VALID != RtcSettings.valid) {
memset(&RtcSettings, 0, sizeof(RtcSettings));
RtcSettings.valid = RTC_MEM_VALID;
-// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2;
+// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
for (uint32_t i = 0; i < 3; i++) {
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
@@ -1535,8 +1535,8 @@ void SettingsDelta(void) {
memset(&Settings->energy_kWhtoday_ph, 0, 36);
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
- Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2;
- Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2;
+ Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2; // = ex_energy_kWhtoday
+ Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2; // = ex_energy_kWhyesterday
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
RtcSettings.energy_kWhtotal_ph[0] = RtcSettings.ex_energy_kWhtotal;
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index d0a308a16..57d34ab43 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -41,6 +41,9 @@
#define D_CMND_TARIFF "Tariff"
#define D_CMND_MODULEADDRESS "ModuleAddress"
+enum EnergyCalibration {
+ ENERGY_POWER_CALIBRATION, ENERGY_VOLTAGE_CALIBRATION, ENERGY_CURRENT_CALIBRATION, ENERGY_FREQUENCY_CALIBRATION };
+
enum EnergyCommands {
CMND_POWERCAL, CMND_VOLTAGECAL, CMND_CURRENTCAL, CMND_FREQUENCYCAL,
CMND_POWERSET, CMND_VOLTAGESET, CMND_CURRENTSET, CMND_FREQUENCYSET, CMND_MODULEADDRESS, CMND_ENERGYCONFIG };
@@ -830,34 +833,50 @@ void CmndTariff(void) {
GetStateText(Settings->flag3.energy_weekend)); // CMND_TARIFF
}
+uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) {
+ uint32_t channel = ((1 == chan) && (2 == Energy.phase_count)) ? 1 : 0;
+ if (channel) {
+ switch (cal_type) {
+ case ENERGY_POWER_CALIBRATION: return Settings->energy_power_calibration2;
+ case ENERGY_VOLTAGE_CALIBRATION: return Settings->energy_voltage_calibration2;
+ case ENERGY_CURRENT_CALIBRATION: return Settings->energy_current_calibration2;
+ }
+ } else {
+ switch (cal_type) {
+ case ENERGY_POWER_CALIBRATION: return Settings->energy_power_calibration;
+ case ENERGY_VOLTAGE_CALIBRATION: return Settings->energy_voltage_calibration;
+ case ENERGY_CURRENT_CALIBRATION: return Settings->energy_current_calibration;
+ }
+ }
+ return Settings->energy_frequency_calibration;
+}
+
void EnergyCommandCalSetResponse(uint32_t cal_type) {
if (XdrvMailbox.payload > 999) {
uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
if (channel) {
switch (cal_type) {
- case 0: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
- case 1: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
- case 2: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
- case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration2 = XdrvMailbox.payload; break;
+ case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration2 = XdrvMailbox.payload; break;
+ case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration2 = XdrvMailbox.payload; break;
+ case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
}
} else {
switch (cal_type) {
- case 0: Settings->energy_power_calibration = XdrvMailbox.payload; break;
- case 1: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
- case 2: Settings->energy_current_calibration = XdrvMailbox.payload; break;
- case 3: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
+ case ENERGY_POWER_CALIBRATION: Settings->energy_power_calibration = XdrvMailbox.payload; break;
+ case ENERGY_VOLTAGE_CALIBRATION: Settings->energy_voltage_calibration = XdrvMailbox.payload; break;
+ case ENERGY_CURRENT_CALIBRATION: Settings->energy_current_calibration = XdrvMailbox.payload; break;
+ case ENERGY_FREQUENCY_CALIBRATION: Settings->energy_frequency_calibration = XdrvMailbox.payload; break;
}
}
}
- if (3 == cal_type) {
+ if (ENERGY_FREQUENCY_CALIBRATION == cal_type) {
ResponseAppend_P(PSTR("%d}"), Settings->energy_frequency_calibration);
} else {
- uint32_t cal_array[2][3];
- memcpy(&cal_array, &Settings->energy_power_calibration, 24);
if (2 == Energy.phase_count) {
- ResponseAppend_P(PSTR("[%d,%d]}"), cal_array[0][cal_type], cal_array[1][cal_type]);
+ ResponseAppend_P(PSTR("[%d,%d]}"), EnergyGetCalibration(0, cal_type), EnergyGetCalibration(1, cal_type));
} else {
- ResponseAppend_P(PSTR("%d}"), cal_array[0][cal_type]);
+ ResponseAppend_P(PSTR("%d}"), EnergyGetCalibration(0, cal_type));
}
}
}
@@ -875,56 +894,56 @@ void EnergyCommandSetCalResponse(uint32_t cal_type) {
void CmndPowerCal(void) {
Energy.command_code = CMND_POWERCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(0);
+ EnergyCommandCalResponse(ENERGY_POWER_CALIBRATION);
}
}
void CmndVoltageCal(void) {
Energy.command_code = CMND_VOLTAGECAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(1);
+ EnergyCommandCalResponse(ENERGY_VOLTAGE_CALIBRATION);
}
}
void CmndCurrentCal(void) {
Energy.command_code = CMND_CURRENTCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(2);
+ EnergyCommandCalResponse(ENERGY_CURRENT_CALIBRATION);
}
}
void CmndFrequencyCal(void) {
Energy.command_code = CMND_FREQUENCYCAL;
if (XnrgCall(FUNC_COMMAND)) { // microseconds
- EnergyCommandCalResponse(3);
+ EnergyCommandCalResponse(ENERGY_FREQUENCY_CALIBRATION);
}
}
void CmndPowerSet(void) {
Energy.command_code = CMND_POWERSET;
if (XnrgCall(FUNC_COMMAND)) { // Watt
- EnergyCommandSetCalResponse(0);
+ EnergyCommandSetCalResponse(ENERGY_POWER_CALIBRATION);
}
}
void CmndVoltageSet(void) {
Energy.command_code = CMND_VOLTAGESET;
if (XnrgCall(FUNC_COMMAND)) { // Volt
- EnergyCommandSetCalResponse(1);
+ EnergyCommandSetCalResponse(ENERGY_VOLTAGE_CALIBRATION);
}
}
void CmndCurrentSet(void) {
Energy.command_code = CMND_CURRENTSET;
if (XnrgCall(FUNC_COMMAND)) { // milliAmpere
- EnergyCommandSetCalResponse(2);
+ EnergyCommandSetCalResponse(ENERGY_CURRENT_CALIBRATION);
}
}
void CmndFrequencySet(void) {
Energy.command_code = CMND_FREQUENCYSET;
if (XnrgCall(FUNC_COMMAND)) { // Hz
- EnergyCommandSetCalResponse(3);
+ EnergyCommandSetCalResponse(ENERGY_FREQUENCY_CALIBRATION);
}
}
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 4cf12061b..0bb88e293 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -463,9 +463,9 @@ void Ade7953GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
- float power_calibration = ((channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration) / 10;
- float voltage_calibration = (channel) ? Settings->energy_voltage_calibration2 : Settings->energy_voltage_calibration;
- float current_calibration = ((channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration) * 10;
+ float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 10;
+ float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION);
+ float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) * 10;
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
index dd44ac14f..740029725 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
@@ -193,8 +193,8 @@ void Bl09XXUpdateEnergy() {
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %2_f, T %2_f"), &Energy.voltage[0], &Bl09XX.temperature);
#endif
for (uint32_t chan = 0; chan < Energy.phase_count; chan++) {
- uint32_t power_calibration = (chan) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
- uint32_t current_calibration = (chan) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
+ uint32_t power_calibration = EnergyGetCalibration(chan, ENERGY_POWER_CALIBRATION);
+ uint32_t current_calibration = EnergyGetCalibration(chan, ENERGY_CURRENT_CALIBRATION);
if (Bl09XX.power[chan] > power_calibration) { // We need at least 1W
Energy.active_power[chan] = (float)Bl09XX.power[chan] / power_calibration;
Energy.current[chan] = (float)Bl09XX.current[chan] / current_calibration;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
index 02c13e121..5a282bc50 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
@@ -468,14 +468,14 @@ void Cse7761GetData(void) {
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
- uint32_t power_calibration = (channel) ? Settings->energy_power_calibration2 : Settings->energy_power_calibration;
+ uint32_t power_calibration = EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION);
// Active power = PowerPA * PowerPAC * 1000 / 0x80000000
// Energy.active_power[channel] = (float)(((uint64_t)CSE7761Data.active_power[channel] * CSE7761Data.coefficient[PowerPAC + channel] * 1000) >> 31) / 1000; // W
Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] / power_calibration; // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- uint32_t current_calibration = (channel) ? Settings->energy_current_calibration2 : Settings->energy_current_calibration;
+ uint32_t current_calibration = EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION);
// Current = RmsIA * RmsIAC / 0x800000
// Energy.current[channel] = (float)(((uint64_t)CSE7761Data.current_rms[channel] * CSE7761Data.coefficient[RmsIAC + channel]) >> 23) / 1000; // A
Energy.current[channel] = (float)CSE7761Data.current_rms[channel] / current_calibration; // A
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
index b77474a12..021003e3a 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
@@ -55,14 +55,20 @@ struct {
void NrgDummyEverySecond(void) {
if (Energy.power_on) { // Powered on
for (uint32_t channel = 0; channel < Energy.phase_count; channel++) {
- Energy.voltage[channel] = ((float)Settings->energy_voltage_calibration / 100); // V
- Energy.frequency[channel] = ((float)Settings->energy_frequency_calibration / 100); // Hz
- if (bitRead(TasmotaGlobal.power, channel)) { // Emulate power read only if device is powered on
- Energy.active_power[channel] = (NrgDummy.power[channel]) ? ((float)NrgDummy.power[channel] / 1000) : ((float)Settings->energy_power_calibration / 100); // W
+
+ float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 100;
+ float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION) / 100;
+ float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) / 100000;
+ float frequency_calibration = (float)EnergyGetCalibration(channel, ENERGY_FREQUENCY_CALIBRATION) / 100;
+
+ Energy.voltage[channel] = power_calibration; // V
+ Energy.frequency[channel] = frequency_calibration; // Hz
+ if (bitRead(TasmotaGlobal.power, channel)) { // Emulate power read only if device is powered on
+ Energy.active_power[channel] = (NrgDummy.power[channel]) ? ((float)NrgDummy.power[channel] / 1000) : voltage_calibration; // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
- Energy.current[channel] = (NrgDummy.current[channel]) ? ((float)NrgDummy.current[channel] / 1000) : ((float)Settings->energy_current_calibration / 100000); // A
+ Energy.current[channel] = (NrgDummy.current[channel]) ? ((float)NrgDummy.current[channel] / 1000) : current_calibration; // A
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
}
Energy.data_valid[channel] = 0;
From 7167eb2f46e83d0ae63cfd105ed6537d871a47c2 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 30 Oct 2022 12:20:56 +0100
Subject: [PATCH 103/319] Changed ADE7953 monitoring
Changed ADE7953 monitoring from instant power to accumulated energy (#16941)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 51 ++++++++++++++-----
4 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eeeab257e..27bc3984c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Move some persistent data (PowerLow)
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
+- ADE7953 monitoring from instant power to accumulated energy (#16941)
### Fixed
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 2c6521331..7a1468d74 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -124,6 +124,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
+- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 57d34ab43..4aaa4e4ee 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -852,7 +852,7 @@ uint32_t EnergyGetCalibration(uint32_t chan, uint32_t cal_type) {
}
void EnergyCommandCalSetResponse(uint32_t cal_type) {
- if (XdrvMailbox.payload > 999) {
+ if (XdrvMailbox.payload > 99) {
uint32_t channel = ((2 == XdrvMailbox.index) && (2 == Energy.phase_count)) ? 1 : 0;
if (channel) {
switch (cal_type) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 0bb88e293..0cef9b6ab 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -69,6 +69,8 @@
/*********************************************************************************************/
+#define ADE7953_ACCU_ENERGY // Use accumulating energy instead of instant power
+
//#define ADE7953_DUMP_REGS
#define ADE7953_PREF 1540 // 4194304 / (1540 / 1000) = 2723574 (= WGAIN, VAGAIN and VARGAIN)
@@ -201,10 +203,22 @@ const uint16_t Ade7953CalibRegs[2][ADE7953_CALIBREGS] {
const uint8_t ADE7953_REGISTERS = 6;
const uint16_t Ade7953Registers[2][ADE7953_REGISTERS] {
+#ifdef ADE7953_ACCU_ENERGY
+ { ADE7953_IRMSA, ADE7953_AENERGYA, ADE7953_APENERGYA, ADE7953_RENERGYA, ADE7953_VRMS, ADE7943_Period },
+ { ADE7953_IRMSB, ADE7953_AENERGYB, ADE7953_APENERGYB, ADE7953_RENERGYB, ADE7953_VRMS, ADE7943_Period }
+#else // No ADE7953_ACCU_ENERGY
{ ADE7953_IRMSA, ADE7953_AWATT, ADE7953_AVA, ADE7953_AVAR, ADE7953_VRMS, ADE7943_Period },
{ ADE7953_IRMSB, ADE7953_BWATT, ADE7953_BVA, ADE7953_BVAR, ADE7953_VRMS, ADE7943_Period }
+#endif // ADE7953_ACCU_ENERGY
};
+#ifdef ADE7953_ACCU_ENERGY
+const float ADE7953_LSB_PER_WATTSECOND = 2.5;
+const float ADE7953_POWER_CORRECTION = 23.41494; // See https://github.com/arendst/Tasmota/pull/16941
+#else // No ADE7953_ACCU_ENERGY
+const float ADE7953_LSB_PER_WATTSECOND = 44;
+#endif // ADE7953_ACCU_ENERGY
+
struct Ade7953 {
uint32_t voltage_rms[2] = { 0, 0 };
uint32_t current_rms[2] = { 0, 0 };
@@ -272,7 +286,7 @@ void Ade7953Write(uint16_t reg, uint32_t val) {
}
int32_t Ade7953Read(uint16_t reg) {
- uint32_t response = 0;
+ uint32_t response = 0;
int size = Ade7953RegSize(reg);
if (size) {
@@ -304,7 +318,7 @@ int32_t Ade7953Read(uint16_t reg) {
}
#endif // USE_ESP32_SPI
}
- return response;
+ return response;
}
#ifdef ADE7953_DUMP_REGS
@@ -439,6 +453,9 @@ void Ade7953GetData(void) {
acc_mode, reg[0][4], reg[1][4], reg[0][5], reg[1][5],
reg[0][0], reg[1][0], reg[0][1], reg[1][1], reg[0][2], reg[1][2], reg[0][3], reg[1][3]);
+ // If the device is initializing, we read the energy registers to reset them, but don't report the values as the first read may be inaccurate
+ if (Ade7953.init_step) { return; }
+
uint32_t apparent_power[2] = { 0, 0 };
uint32_t reactive_power[2] = { 0, 0 };
@@ -464,15 +481,18 @@ void Ade7953GetData(void) {
Energy.data_valid[channel] = 0;
float power_calibration = (float)EnergyGetCalibration(channel, ENERGY_POWER_CALIBRATION) / 10;
+#ifdef ADE7953_ACCU_ENERGY
+ power_calibration /= ADE7953_POWER_CORRECTION;
+#endif // ADE7953_ACCU_ENERGY
float voltage_calibration = (float)EnergyGetCalibration(channel, ENERGY_VOLTAGE_CALIBRATION);
float current_calibration = (float)EnergyGetCalibration(channel, ENERGY_CURRENT_CALIBRATION) * 10;
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : voltage_calibration;
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
if (ADE7953_SHELLY_EM == Ade7953.model) {
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
@@ -482,7 +502,7 @@ void Ade7953GetData(void) {
Energy.reactive_power[channel] *= -1;
}
}
- divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : power_calibration;
+ divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? ADE7953_LSB_PER_WATTSECOND : power_calibration;
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
@@ -497,14 +517,13 @@ void Ade7953GetData(void) {
}
void Ade7953EnergyEverySecond(void) {
- if (Ade7953.init_step) {
- if (1 == Ade7953.init_step) {
- Ade7953Init();
- }
+ if (Ade7953.init_step) {
+ if (2 == Ade7953.init_step) { Ade7953Init(); }
+ if (1 == Ade7953.init_step) { Ade7953GetData(); } // Read registers but do not display yet
Ade7953.init_step--;
- } else {
- Ade7953GetData();
- }
+ } else {
+ Ade7953GetData();
+ }
}
/*********************************************************************************************/
@@ -668,7 +687,7 @@ void Ade7953DrvInit(void) {
Ade7953Defaults();
- Ade7953.init_step = 2;
+ Ade7953.init_step = 3;
// Energy.phase_count = 1;
// Energy.voltage_common = false;
@@ -712,7 +731,13 @@ bool Ade7953Command(void) {
else if (CMND_POWERSET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.active_power[channel]) {
if ((value > 100) && (value < 200000)) { // Between 1W and 2000W
+#ifdef ADE7953_ACCU_ENERGY
+ float power_calibration = (float)(Ade7953.active_power[channel] * 1000) / value; // 0.00 W
+ power_calibration *= ADE7953_POWER_CORRECTION;
+ XdrvMailbox.payload = (uint32_t)power_calibration; // 0.00 W
+#else // No ADE7953_ACCU_ENERGY
XdrvMailbox.payload = (Ade7953.active_power[channel] * 1000) / value; // 0.00 W
+#endif // ADE7953_ACCU_ENERGY
}
}
}
From f1f8d27079d39832f740f0260f12700c14cde36a Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Sun, 30 Oct 2022 20:09:52 +0300
Subject: [PATCH 104/319] Added prefix to all functions
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 54 +++++++++----------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index c5afefa9f..aaad8602a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -1,7 +1,7 @@
/*
xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader on Tasmota
- Copyright (C) 2021 Andre Thomas and Theo Arends
+ Copyright (C) 2021 Andre Thomas, Theo Arends and md5sum-as (https://github.com/md5sum-as)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -354,7 +354,7 @@ void PN532_inRelease(void) {
PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer));
}
-uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
+uint8_t PN532_mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) {
uint8_t i;
uint8_t _key[6];
uint8_t _uid[7];
@@ -391,7 +391,7 @@ uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t
return 1;
}
-uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
+uint8_t PN532_mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the command */
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
@@ -418,7 +418,7 @@ uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data) {
return 1;
}
-uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
+uint8_t PN532_mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
/* Prepare the first command */
Pn532.packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
Pn532.packetbuffer[1] = 1; /* Card number */
@@ -435,7 +435,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) {
return (0 < PN532_readResponse(Pn532.packetbuffer, sizeof(Pn532.packetbuffer)));
}
-uint8_t ntag21x_probe (void) {
+uint8_t PN532_ntag21x_probe (void) {
uint8_t result=0;
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
@@ -461,7 +461,7 @@ uint8_t ntag21x_probe (void) {
return result; //Return configuration page address
}
-bool ntag21x_auth(void) {
+bool PN532_ntag21x_auth(void) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG21X_CMD_PWD_AUTH;
@@ -479,7 +479,7 @@ bool ntag21x_auth(void) {
return memcmp(&Pn532.packetbuffer[1],&Pn532.pwd_pack,2)==0;
}
-bool ntag2xx_read16 (const uint8_t page, char *out) {
+bool PN532_ntag2xx_read16 (const uint8_t page, char *out) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG2XX_CMD_READ;
@@ -497,7 +497,7 @@ bool ntag2xx_read16 (const uint8_t page, char *out) {
return true;
}
-bool ntag2xx_write4(uint8_t page, char *in) {
+bool PN532_ntag2xx_write4(uint8_t page, char *in) {
Pn532.packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
Pn532.packetbuffer[1] = NTAG2XX_CMD_WRITE;
@@ -514,29 +514,29 @@ bool ntag2xx_write4(uint8_t page, char *in) {
return true;
}
-bool ntag2xx_write16(uint8_t page, char *in) {
+bool PN532_ntag2xx_write16(uint8_t page, char *in) {
for (uint8_t i = 0; i < 4; i++) {
- if (!ntag2xx_write4(page +i, &in[i << 2])) {
+ if (!PN532_ntag2xx_write4(page +i, &in[i << 2])) {
return false;
}
}
return true;
}
-bool ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
+bool PN532_ntag21x_set_password(uint8_t confPage, bool unsetPasswd) {
char card_datas[16];
- if (ntag2xx_read16(confPage, card_datas)) {
+ if (PN532_ntag2xx_read16(confPage, card_datas)) {
if (unsetPasswd) {
card_datas[3]=0xFF;
- return ntag2xx_write4(confPage, card_datas);
+ return PN532_ntag2xx_write4(confPage, card_datas);
}
card_datas[3]=0; // Set AUTH0 for protect all pages
card_datas[4] |= 0x80; // Set PROT flag for read and write access is protected by the password verification
memcpy(&card_datas[8],&Pn532.pwd_auth_new, 4); // New password
memcpy(&card_datas[12],&Pn532.pwd_pack_new, 2); // New password ack
- return ntag2xx_write16(confPage, card_datas);
+ return PN532_ntag2xx_write16(confPage, card_datas);
}
return false;
}
@@ -558,50 +558,50 @@ void PN532_ScanForTag(void) {
uint8_t confPage=0;
uint8_t nuid[] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t nuid_len = 0;
- if ((confPage=ntag21x_probe())>0) {
+ if ((confPage=PN532_ntag21x_probe())>0) {
/* NTAG EV1 found*/
str_pwd=PWD_NONE;
- if (!ntag2xx_read16(4, card_datas)) {
+ if (!PN532_ntag2xx_read16(4, card_datas)) {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (ntag21x_auth()) {
+ if (PN532_ntag21x_auth()) {
str_pwd=PWD_OK;
if (Pn532.function == 3) { /* new password */
- success = ntag21x_set_password(confPage, false);
+ success = PN532_ntag21x_set_password(confPage, false);
}
if (Pn532.function == 4) { /* clear password */
- success = ntag21x_set_password(confPage, true);
+ success = PN532_ntag21x_set_password(confPage, true);
}
} else {
str_pwd=PWD_NOK;
}
- if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
+ if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
} else {
if (Pn532.function == 3) { /* new password */
- success = ntag21x_set_password(confPage, false);
+ success = PN532_ntag21x_set_password(confPage, false);
}
}
} else {
if (PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, nuid, &nuid_len)) {
if (memcmp(uid, nuid, sizeof(uid))==0) {
- if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
+ if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
}
if ((Pn532.function == 1) || (Pn532.function == 2)) {
- success = ntag2xx_write16(4, (char *)Pn532.newdata);
- if (!ntag2xx_read16(4, card_datas)) card_datas[0]=0;
+ success = PN532_ntag2xx_write16(4, (char *)Pn532.newdata);
+ if (!PN532_ntag2xx_read16(4, card_datas)) card_datas[0]=0;
}
}
else if (uid_len == 4) { // Lets try to read blocks 1 & 2 of the mifare classic card for more information
uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
+ if (PN532_mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) {
if ((Pn532.function == 1) || (Pn532.function == 2)) {
- success=mifareclassic_WriteDataBlock(1, Pn532.newdata);
+ success=PN532_mifareclassic_WriteDataBlock(1, Pn532.newdata);
}
- if (mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
+ if (PN532_mifareclassic_ReadDataBlock(1, (uint8_t *)card_datas)) {
for (uint32_t i = 0; i < 16; i++) {
if (!isprint(card_datas[i])) {
// do not output non-printable characters to the console
From 87b403f10d59e9cda2c7e13d5efc5d7a250deb4f Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sun, 30 Oct 2022 18:40:32 +0100
Subject: [PATCH 105/319] support RISCV ULP for ESP32S2 and ESP32S3
---
.../xdrv_52_3_berry_ulp.ino | 58 +++++++++++++++----
1 file changed, 46 insertions(+), 12 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino
index 4dbc24b3c..9d154a8da 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_ulp.ino
@@ -1,5 +1,5 @@
/*
- xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32
+ xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32, ESP32S2, ESP32S3
Copyright (C) 2021 Stephan Hadinger & Christian Baars, Berry language by Guan Wenliang https://github.com/Skiars/berry
@@ -21,9 +21,21 @@
#ifdef USE_BERRY_ULP
#include
-#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
+#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
+#if defined(CONFIG_IDF_TARGET_ESP32)
#include "esp32/ulp.h"
+#endif // esp32
+#if defined(CONFIG_IDF_TARGET_ESP32S2)
+#include "esp32s2/ulp.h"
+#include "esp32s2/ulp_riscv.h"
+#include "esp32s2/ulp_riscv_adc.h"
+#endif // s2
+#if defined(CONFIG_IDF_TARGET_ESP32S3)
+#include "esp32s3/ulp.h"
+#include "esp32s3/ulp_riscv.h"
+#include "esp32s3/ulp_riscv_adc.h"
+#endif //s3
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
@@ -36,7 +48,11 @@ extern "C" {
//
// `ULP.run() -> nil`
void be_ULP_run(int32_t entry) {
+#if defined(CONFIG_IDF_TARGET_ESP32)
ulp_run(entry); // entry point should be at the beginning of program
+#else // S2 or S3
+ ulp_riscv_run();
+#endif
}
// `ULP.wake_period(period_index:int, period_us:int) -> nil`
@@ -52,7 +68,11 @@ extern "C" {
// `ULP.get_mem(position:int) -> int`
int32_t be_ULP_get_mem(int32_t pos) {
- return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
+#else
+ return RTC_SLOW_MEM[pos]; // full 32bit for RISCV ULP
+#endif
}
// `ULP.gpio_init(pin:int, mode:int) -> rtc_pin:int`
@@ -70,25 +90,40 @@ extern "C" {
// `ULP.adc_config(channel:int, attenuation:int, width:int) -> nil`
//
// enums: channel 0-7, attenuation 0-3, width 0-3
- void be_ULP_adc_config(struct bvm *vm, adc1_channel_t channel, adc_atten_t attenuation, adc_bits_width_t width) {
- esp_err_t err = adc1_config_channel_atten(channel, attenuation);
- err += adc1_config_width(width);
+ void be_ULP_adc_config(struct bvm *vm, int32_t channel, int32_t attenuation, int32_t width) {
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ esp_err_t err = adc1_config_channel_atten((adc1_channel_t)channel, (adc_atten_t)attenuation);
+ err += adc1_config_width((adc_bits_width_t)width);
if (err != ESP_OK) {
be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
} else {
adc1_ulp_enable();
}
+#else // S2 or S3
+ ulp_riscv_adc_cfg_t cfg = {
+ .channel = (adc_channel_t)channel,
+ .atten = (adc_atten_t)attenuation,
+ .width = (adc_bits_width_t)width
+ };
+ esp_err_t err = ulp_riscv_adc_init(&cfg);
+ if (err != ESP_OK) {
+ be_raisef(vm, "ulp_adc_config_error", "ULP: invalid code err=%i", err);
+ }
+#endif
}
/**
* @brief Load a Berry byte buffer containing a ULP program as raw byte data
*
* @param vm as `ULP.load(code:bytes) -> nil`
- * @return void
+ * @return void for ESP32 or binary type as int32_t on RISCV capable SOC's
*/
void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size) {
- // AddLog(LOG_LEVEL_INFO, "ULP: load addr=%p size=%i %*_H", buf, size/4, size, buf);
- esp_err_t err = ulp_load_binary(0, buf, size / 4);
+#if defined(CONFIG_IDF_TARGET_ESP32)
+ esp_err_t err = ulp_load_binary(0, buf, size / 4); // FSM type only, specific header, size in long words
+#else // S2 or S3
+ esp_err_t err = ulp_riscv_load_binary(buf, size); // there are no header bytes, just load and hope for a valid binary - size in bytes
+#endif // defined(CONFIG_IDF_TARGET_ESP32)
if (err != ESP_OK) {
be_raisef(vm, "ulp_load_error", "ULP: invalid code err=%i", err);
}
@@ -109,10 +144,9 @@ extern "C" {
esp_deep_sleep_start();
}
-
} //extern "C"
-#endif //CONFIG_IDF_TARGET_ESP32
+#endif //CONFIG_IDF_TARGET_ESP32 .. S2 .. S3
#endif // USE_BERRY_ULP
-#endif // USE_BERRY
\ No newline at end of file
+#endif // USE_BERRY
From ed6c21ad806f9cdb43e25d719b75906402b9feaa Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sun, 30 Oct 2022 18:42:47 +0100
Subject: [PATCH 106/319] allow ULP not only for ESP32
---
lib/libesp32/berry/default/be_modtab.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index c02e2ca6d..c4a2147d1 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -166,7 +166,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_ALEXA_AVS
&be_native_module(crypto),
#endif
-#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
+#if defined(USE_BERRY_ULP)
&be_native_module(ULP),
#endif // USE_BERRY_ULP
#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
From 0b063f62dfa505f67dfb12ca68cc1ac409710803 Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Sun, 30 Oct 2022 18:43:37 +0100
Subject: [PATCH 107/319] allow ULP on ESP32, S2 and S3
---
lib/libesp32/berry_tasmota/src/be_ULP_lib.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/lib/libesp32/berry_tasmota/src/be_ULP_lib.c b/lib/libesp32/berry_tasmota/src/be_ULP_lib.c
index 7edf43206..a5fe0e417 100644
--- a/lib/libesp32/berry_tasmota/src/be_ULP_lib.c
+++ b/lib/libesp32/berry_tasmota/src/be_ULP_lib.c
@@ -6,9 +6,9 @@
#include "be_constobj.h"
#include "be_mapping.h"
-#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
+#if defined(USE_BERRY_ULP) && (defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
-#include "esp32/ulp.h"
+// #include "esp32/ulp.h"
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
@@ -37,8 +37,6 @@ BE_FUNC_CTYPE_DECLARE(be_ULP_sleep, "", "[i]"); // optional int arg
extern void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size);
BE_FUNC_CTYPE_DECLARE(be_ULP_load, "", "@(bytes)~"); // pass: 1/ vm, 2/ bytes point, 3/ bytes size
-#include "be_fixed_ULP.h"
-
/* @const_object_info_begin
module ULP (scope: global) {
run, ctype_func(be_ULP_run)
@@ -51,5 +49,6 @@ module ULP (scope: global) {
adc_config, ctype_func(be_ULP_adc_config)
}
@const_object_info_end */
+#include "be_fixed_ULP.h"
-#endif // USE_BERRY_ULP
\ No newline at end of file
+#endif // USE_BERRY_ULP
From 79536d8714c7be457e1a5b4fd3d8cf2a3d663f9f Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 10:59:49 +0100
Subject: [PATCH 108/319] Update changelog
---
CHANGELOG.md | 2 ++
RELEASENOTES.md | 2 ++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 27bc3984c..6f93336f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
+- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
### Breaking Changed
@@ -19,6 +20,7 @@ All notable changes to this project will be documented in this file.
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
### Removed
+- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
## [12.2.0.1] 20221026
### Added
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 7a1468d74..3177f027d 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -114,6 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
+- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
@@ -132,3 +133,4 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Removed
+- Define ``USE_PN532_DATA_RAW`` from NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
From c351c62baf015d6c05987efffe7176da7db56c5b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 11:25:00 +0100
Subject: [PATCH 109/319] Fix possible serial watchdogs
---
lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
index 99dc6caeb..f750b956f 100644
--- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
+++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
@@ -95,7 +95,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
void TasmotaSerial::end(bool turnOffDebug) {
#ifdef ESP8266
if (m_hardserial) {
- Serial.end();
+// Serial.end(); // Keep active for logging
} else {
if (m_rx_pin > -1) {
detachInterrupt(m_rx_pin);
From 817819e603b3cf066b4263a03db52143727ee479 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 13:38:26 +0100
Subject: [PATCH 110/319] Add PN532 persistent slots (#16939)
---
tasmota/include/tasmota_types.h | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index 0fa7d6f69..7f952b8f5 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -574,8 +574,7 @@ typedef struct {
SOBitfield3 flag3; // 3A0
uint16_t energy_kWhdoy; // 3A4
uint16_t energy_min_power; // 3A6
-
- uint8_t free_3A8[4]; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
+ uint32_t pn532_password; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
#ifdef CONFIG_IDF_TARGET_ESP32S3
// ------------------------------------
@@ -688,15 +687,15 @@ typedef struct {
uint16_t mqtt_socket_timeout; // 52E
uint8_t mqtt_wifi_timeout; // 530
uint8_t ina219_mode; // 531
- uint16_t ex_pulse_timer[8]; // 532 Free since 11.0.0.3
+
+ uint16_t ex_pulse_timer[8]; // 532 ex_pulse_timer free since 11.0.0.3
+
uint16_t button_debounce; // 542
uint32_t ipv4_address[5]; // 544
uint32_t ipv4_rgx_address; // 558
uint32_t ipv4_rgx_subnetmask; // 55C
uint16_t pwm_value_ext[16-5]; // 560 Extension to pwm_value to store up to 16 PWM for ESP32. This array stores values 5..15
-
- uint8_t free_576[2]; // 576
-
+ uint16_t pn532_pack; // 576
int32_t weight_offset; // 578
uint16_t pulse_timer[MAX_PULSETIMERS]; // 57C
SysMBitfield1 flag2; // 5BC
@@ -842,7 +841,9 @@ typedef struct {
uint16_t flowratemeter_calibration[2];// F78
int32_t energy_kWhexport_ph[3]; // F7C
uint32_t eth_ipv4_address[5]; // F88
+
uint32_t ex_energy_kWhtotal; // F9C
+
SBitfield1 sbflag1; // FA0
TeleinfoCfg teleinfo; // FA4
uint64_t rf_protocol_mask; // FA8
From 9db8a2340143ce597bff1cb37d631b5ec9429c33 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 14:01:15 +0100
Subject: [PATCH 111/319] Fix Shelly Pro detection when using buttons (#16733)
---
tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 60f0f0a88..096f46e60 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -64,9 +64,9 @@ void ShellyProPreInit(void) {
PinUsed(GPIO_SPI_CS) &&
TasmotaGlobal.gpio_optiona.shelly_pro) { // Option_A7
- if (PinUsed(GPIO_SWT1)) {
+ if (PinUsed(GPIO_SWT1) || PinUsed(GPIO_KEY1)) {
TasmotaGlobal.devices_present++; // Shelly Pro 1
- if (PinUsed(GPIO_SWT1, 1)) {
+ if (PinUsed(GPIO_SWT1, 1) || PinUsed(GPIO_KEY1, 1)) {
TasmotaGlobal.devices_present++; // Shelly Pro 2
}
From e9d99a088be44e9258c0c771dc9a3a3d83fc7f78 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 31 Oct 2022 15:02:29 +0100
Subject: [PATCH 112/319] Fix hardware watchdog at power on
---
tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 4aaa4e4ee..cef329705 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -415,8 +415,8 @@ bool EnergyMargin(bool type, uint16_t margin, uint16_t value, bool &flag, bool &
return (change != save_flag);
}
-void EnergyMarginCheck(void)
-{
+void EnergyMarginCheck(void) {
+ if (!Energy.phase_count || (TasmotaGlobal.uptime < 8)) { return; }
if (Energy.power_steady_counter) {
Energy.power_steady_counter--;
return;
@@ -1094,9 +1094,6 @@ void EnergyDrvInit(void) {
Energy.voltage_available = true; // Enable if voltage is measured
Energy.current_available = true; // Enable if current is measured
Energy.power_on = true;
-#ifdef USE_ENERGY_MARGIN_DETECTION
- Energy.power_steady_counter = 8; // Allow for power on stabilization
-#endif // USE_ENERGY_MARGIN_DETECTION
TasmotaGlobal.energy_driver = ENERGY_NONE;
XnrgCall(FUNC_PRE_INIT); // Find first energy driver
From ad484ad194a1c4316d5e7f00e26eb8adf8c2ad94 Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Mon, 31 Oct 2022 18:37:46 +0300
Subject: [PATCH 113/319] Saving the PN532 password and PACK in Settings
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index aaad8602a..68eb3c8c6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -85,8 +85,8 @@ struct PN532 {
#ifdef USE_PN532_DATA_FUNCTION
uint8_t newdata[16];
uint8_t function = 0;
- uint32_t pwd_auth=0x64636261;
- uint16_t pwd_pack=0x6665;
+ uint32_t pwd_auth;
+ uint16_t pwd_pack;
uint32_t pwd_auth_new;
uint16_t pwd_pack_new;
#endif // USE_PN532_DATA_FUNCTION
@@ -106,6 +106,8 @@ void PN532_Init(void) {
PN532_SAMConfig();
AddLog(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
Pn532.present = true;
+ Pn532.pwd_auth=Settings->pn532_password;
+ Pn532.pwd_pack=Settings->pn532_pack;
}
}
}
@@ -708,6 +710,9 @@ bool PN532_Command(void) {
if (ArgC() > 2) {
Pn532.pwd_pack=strtoul(ArgV(argument,3),nullptr,0);
}
+ Settings->pn532_password=Pn532.pwd_auth;
+ Settings->pn532_pack=Pn532.pwd_pack;
+
serviced = true;
}
if (!strcmp_P(argument,PSTR("SET_PWD"))) {
From a3391ddc2b26fa5179fd7b2d0a528d119806e71f Mon Sep 17 00:00:00 2001
From: md5sum-as
Date: Mon, 31 Oct 2022 19:07:03 +0300
Subject: [PATCH 114/319] Fixed a compilation error: added conditional
compilation
---
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 68eb3c8c6..4c39f4342 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -106,8 +106,10 @@ void PN532_Init(void) {
PN532_SAMConfig();
AddLog(LOG_LEVEL_INFO,"NFC: PN532 NFC Reader detected v%u.%u",(ver>>16) & 0xFF, (ver>>8) & 0xFF);
Pn532.present = true;
+#ifdef USE_PN532_DATA_FUNCTION
Pn532.pwd_auth=Settings->pn532_password;
Pn532.pwd_pack=Settings->pn532_pack;
+#endif
}
}
}
From 0e5592fbff395c41877ddca193f16d6d0c40c570 Mon Sep 17 00:00:00 2001
From: Thomas Hargrove
Date: Mon, 31 Oct 2022 10:40:15 -0700
Subject: [PATCH 115/319] Add support for PMSx003T modules that have
temperature+humidity
---
tasmota/include/tasmota_configurations.h | 1 +
.../include/tasmota_configurations_ESP32.h | 2 ++
tasmota/my_user_config.h | 1 +
.../tasmota_xsns_sensor/xsns_18_pms5003.ino | 32 +++++++++++++++++--
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h
index afc97f7ea..b62f3f7e3 100644
--- a/tasmota/include/tasmota_configurations.h
+++ b/tasmota/include/tasmota_configurations.h
@@ -173,6 +173,7 @@
#endif
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index b252a2275..22c163201 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -439,6 +439,7 @@
#endif
//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
@@ -655,6 +656,7 @@
#endif
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e107c385d..23f8e66a0 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -762,6 +762,7 @@
#define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+1k5 code)
#define STARTING_OFFSET 30 // Turn on NovaSDS XX-seconds before tele_period is reached
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
index b1cac1a81..1639ba8c4 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
@@ -26,6 +26,7 @@
* Hardware Serial will be selected if GPIO3 = [PMS5003]
* You can either support PMS3003 or PMS5003-7003 at one time. To enable the PMS3003 support
* you must enable the define PMS_MODEL_PMS3003 on your configuration file.
+ * For PMSx003T models that report temperature and humidity define PMS_MODEL_PMSx003T
\*********************************************************************************************/
#define XSNS_18 18
@@ -75,7 +76,12 @@ struct pmsX003data {
#ifdef PMS_MODEL_PMS3003
uint16_t reserved1, reserved2, reserved3;
#else
- uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
+ uint16_t particles_03um, particles_05um, particles_10um, particles_25um;
+#ifdef PMS_MODEL_PMSx003T
+ uint16_t temperature10x, humidity10x;
+#else
+ uint16_t particles_50um, particles_100um;
+#endif
uint16_t unused;
#endif // PMS_MODEL_PMS3003
uint16_t checksum;
@@ -289,24 +295,40 @@ const char HTTP_PMS5003_SNS[] PROGMEM =
"{s}PMS5003 " D_PARTICALS_BEYOND " 0.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
"{s}PMS5003 " D_PARTICALS_BEYOND " 1 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
"{s}PMS5003 " D_PARTICALS_BEYOND " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
+#ifdef PMS_MODEL_PMSx003T
+ "{s}PMS5003 " D_TEMPERATURE "{m}%*_f " D_UNIT_DEGREE "%c{e}"
+ "{s}PMS5003 " D_HUMIDITY "{m}%*_f " D_UNIT_PERCENT "{e}";
+#else
"{s}PMS5003 " D_PARTICALS_BEYOND " 5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
"{s}PMS5003 " D_PARTICALS_BEYOND " 10 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"; // {s} = , {m} = | , {e} = |
+#endif // PMS_MODEL_PMSx003T
#endif // PMS_MODEL_PMS3003
#endif // USE_WEBSERVER
void PmsShow(bool json)
{
if (Pms.valid) {
+#ifdef PMS_MODEL_PMSx003T
+ float temperature = ConvertTemp(pms_data.temperature10x/10.0);
+ float humidity = ConvertHumidity(pms_data.humidity10x/10.0);
+#endif // PMS_MODEL_PMSx003T
if (json) {
#ifdef PMS_MODEL_PMS3003
ResponseAppend_P(PSTR(",\"PMS3003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"),
pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env);
#else
- ResponseAppend_P(PSTR(",\"PMS5003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d,\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,\"PB5\":%d,\"PB10\":%d}"),
+ ResponseAppend_P(PSTR(",\"PMS5003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d,\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,"),
pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
- pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, pms_data.particles_50um, pms_data.particles_100um);
+ pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um);
+#ifdef PMS_MODEL_PMSx003T
+ ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f,\"" D_JSON_HUMIDITY "\":%*_f}"),
+ Settings->flag2.temperature_resolution, &temperature, Settings->flag2.humidity_resolution, &humidity);
+#else
+ ResponseAppend_P(PSTR("\"PB5\":%d,\"PB10\":%d}"),
+ pms_data.particles_50um, pms_data.particles_100um);
+#endif // PMS_MODEL_PMSx003T
#endif // PMS_MODEL_PMS3003
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
@@ -322,6 +344,10 @@ void PmsShow(bool json)
WSContentSend_PD(HTTP_PMS3003_SNS,
// pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env);
+#elif defined(PMS_MODEL_PMSx003T)
+ WSContentSend_PD(HTTP_PMS5003_SNS,
+ pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
+ pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, Settings->flag2.temperature_resolution, &temperature, TempUnit(), Settings->flag2.humidity_resolution, &humidity);
#else
WSContentSend_PD(HTTP_PMS5003_SNS,
// pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
From 2d3b5c5a76dbb9811b3ed51d66d1aaf7e0368322 Mon Sep 17 00:00:00 2001
From: Thomas Hargrove
Date: Mon, 31 Oct 2022 10:58:13 -0700
Subject: [PATCH 116/319] Add comment to endif
---
tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
index 1639ba8c4..aa9666241 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
@@ -81,7 +81,7 @@ struct pmsX003data {
uint16_t temperature10x, humidity10x;
#else
uint16_t particles_50um, particles_100um;
-#endif
+#endif // PMS_MODEL_PMSx003T
uint16_t unused;
#endif // PMS_MODEL_PMS3003
uint16_t checksum;
From 644f9da9af0d85e733db65786dd4d3c02ca8398c Mon Sep 17 00:00:00 2001
From: Thomas Hargrove
Date: Mon, 31 Oct 2022 13:41:37 -0700
Subject: [PATCH 117/319] Change define name to be more consistent with
existing defines
---
tasmota/include/tasmota_configurations.h | 2 +-
.../include/tasmota_configurations_ESP32.h | 4 ++--
tasmota/my_user_config.h | 2 +-
.../tasmota_xsns_sensor/xsns_18_pms5003.ino | 20 +++++++++----------
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h
index b62f3f7e3..90ea85518 100644
--- a/tasmota/include/tasmota_configurations.h
+++ b/tasmota/include/tasmota_configurations.h
@@ -173,7 +173,7 @@
#endif
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
- //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMS5003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index 22c163201..e6cb4c28b 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -439,7 +439,7 @@
#endif
//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
- //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMS5003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
@@ -656,7 +656,7 @@
#endif
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
- //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMS5003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 23f8e66a0..4493517b4 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -762,7 +762,7 @@
#define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
//#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
//#define PMS_MODEL_PMS3003 // Enable support of PMS3003 instead of PMS5003/PMS7003 (needs the USE_PMS5003 above)
- //#define PMS_MODEL_PMSx003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
+ //#define PMS_MODEL_PMS5003T // Enable support for PMSx003T models that report temperature and humidity (needs the USE_PMS5003 above)
//#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+1k5 code)
#define STARTING_OFFSET 30 // Turn on NovaSDS XX-seconds before tele_period is reached
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
index aa9666241..d1bdf5599 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
@@ -26,7 +26,7 @@
* Hardware Serial will be selected if GPIO3 = [PMS5003]
* You can either support PMS3003 or PMS5003-7003 at one time. To enable the PMS3003 support
* you must enable the define PMS_MODEL_PMS3003 on your configuration file.
- * For PMSx003T models that report temperature and humidity define PMS_MODEL_PMSx003T
+ * For PMSx003T models that report temperature and humidity define PMS_MODEL_PMS5003T
\*********************************************************************************************/
#define XSNS_18 18
@@ -77,11 +77,11 @@ struct pmsX003data {
uint16_t reserved1, reserved2, reserved3;
#else
uint16_t particles_03um, particles_05um, particles_10um, particles_25um;
-#ifdef PMS_MODEL_PMSx003T
+#ifdef PMS_MODEL_PMS5003T
uint16_t temperature10x, humidity10x;
#else
uint16_t particles_50um, particles_100um;
-#endif // PMS_MODEL_PMSx003T
+#endif // PMS_MODEL_PMS5003T
uint16_t unused;
#endif // PMS_MODEL_PMS3003
uint16_t checksum;
@@ -295,23 +295,23 @@ const char HTTP_PMS5003_SNS[] PROGMEM =
"{s}PMS5003 " D_PARTICALS_BEYOND " 0.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
"{s}PMS5003 " D_PARTICALS_BEYOND " 1 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
"{s}PMS5003 " D_PARTICALS_BEYOND " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
-#ifdef PMS_MODEL_PMSx003T
+#ifdef PMS_MODEL_PMS5003T
"{s}PMS5003 " D_TEMPERATURE "{m}%*_f " D_UNIT_DEGREE "%c{e}"
"{s}PMS5003 " D_HUMIDITY "{m}%*_f " D_UNIT_PERCENT "{e}";
#else
"{s}PMS5003 " D_PARTICALS_BEYOND " 5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"
"{s}PMS5003 " D_PARTICALS_BEYOND " 10 " D_UNIT_MICROMETER "{m}%d " D_UNIT_PARTS_PER_DECILITER "{e}"; // {s} = , {m} = | , {e} = |
-#endif // PMS_MODEL_PMSx003T
+#endif // PMS_MODEL_PMS5003T
#endif // PMS_MODEL_PMS3003
#endif // USE_WEBSERVER
void PmsShow(bool json)
{
if (Pms.valid) {
-#ifdef PMS_MODEL_PMSx003T
+#ifdef PMS_MODEL_PMS5003T
float temperature = ConvertTemp(pms_data.temperature10x/10.0);
float humidity = ConvertHumidity(pms_data.humidity10x/10.0);
-#endif // PMS_MODEL_PMSx003T
+#endif // PMS_MODEL_PMS5003T
if (json) {
#ifdef PMS_MODEL_PMS3003
ResponseAppend_P(PSTR(",\"PMS3003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"),
@@ -322,13 +322,13 @@ void PmsShow(bool json)
pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um);
-#ifdef PMS_MODEL_PMSx003T
+#ifdef PMS_MODEL_PMS5003T
ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%*_f,\"" D_JSON_HUMIDITY "\":%*_f}"),
Settings->flag2.temperature_resolution, &temperature, Settings->flag2.humidity_resolution, &humidity);
#else
ResponseAppend_P(PSTR("\"PB5\":%d,\"PB10\":%d}"),
pms_data.particles_50um, pms_data.particles_100um);
-#endif // PMS_MODEL_PMSx003T
+#endif // PMS_MODEL_PMS5003T
#endif // PMS_MODEL_PMS3003
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
@@ -344,7 +344,7 @@ void PmsShow(bool json)
WSContentSend_PD(HTTP_PMS3003_SNS,
// pms_data.pm10_standard, pms_data.pm25_standard, pms_data.pm100_standard,
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env);
-#elif defined(PMS_MODEL_PMSx003T)
+#elif defined(PMS_MODEL_PMS5003T)
WSContentSend_PD(HTTP_PMS5003_SNS,
pms_data.pm10_env, pms_data.pm25_env, pms_data.pm100_env,
pms_data.particles_03um, pms_data.particles_05um, pms_data.particles_10um, pms_data.particles_25um, Settings->flag2.temperature_resolution, &temperature, TempUnit(), Settings->flag2.humidity_resolution, &humidity);
From 1011ee2cbb0a0dd1e7a1be48332c74e8218f1694 Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Tue, 1 Nov 2022 15:55:01 +0100
Subject: [PATCH 118/319] ignore USE_BERRY_ULP on unsupported platforms
---
lib/libesp32/berry/default/be_modtab.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index c4a2147d1..1cc28efee 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -166,7 +166,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_ALEXA_AVS
&be_native_module(crypto),
#endif
-#if defined(USE_BERRY_ULP)
+#if defined(USE_BERRY_ULP) && ((CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
&be_native_module(ULP),
#endif // USE_BERRY_ULP
#if defined(USE_MI_ESP32) && !defined(USE_BLE_ESP32)
From da65c8798bb192465f4fabd8a95e4c4c6b54f87b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 1 Nov 2022 17:19:42 +0100
Subject: [PATCH 119/319] Shelly Pro better light show
---
.../xdrv_88_esp32_shelly_pro.ino | 30 +++++++++++--------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index 096f46e60..a822b04c9 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -49,13 +49,15 @@ void ShellyProUpdate(void) {
// bit 3 = wifi led green
// bit 4 = wifi led red
// bit 5 - 7 = nc
- uint32_t val = SPro.power | SPro.ledlink;
+ // OE is connected to Gnd with 470 ohm resistor R62 AND a capacitor C81 to 3V3
+ // - this inhibits output of signals (also relay state) during power on for a few seconds
+ uint8_t val = SPro.power | SPro.ledlink;
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
SPI.transfer(val); // Write 74HC595 shift register
SPI.endTransaction();
- delayMicroseconds(2); // Wait for SPI clock to stop
+// delayMicroseconds(2); // Wait for SPI clock to stop
digitalWrite(SPro.pin_shift595_rclk, 1); // Latch data
- delayMicroseconds(2); // Shelly 10mS
+ delayMicroseconds(1); // Shelly 10mS
digitalWrite(SPro.pin_shift595_rclk, 0);
}
@@ -76,21 +78,18 @@ void ShellyProPreInit(void) {
// Does nothing if SPI is already initiated (by ADE7953) so no harm done
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
- SPro.power = TasmotaGlobal.power &3; // Restore power
- SPro.ledlink = 0x18; // Blue led on
- ShellyProUpdate();
-
+ SPro.ledlink = 0x18; // Blue led on - set by first call ShellyProPower()
SPro.detected = true;
}
}
}
void ShellyProInit(void) {
- int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
-// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
+ int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
+// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
digitalWrite(pin_lan_reset, 0);
pinMode(pin_lan_reset, OUTPUT);
- delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
+ delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
digitalWrite(pin_lan_reset, 1);
AddLog(LOG_LEVEL_INFO, PSTR("HDW: Shelly Pro %d%s initialized"),
@@ -123,9 +122,14 @@ void ShellyProLedLink(void) {
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
*/
SPro.last_update = TasmotaGlobal.uptime;
- uint32_t ledlink = 0x1C; // All leds off
- if (XdrvMailbox.index) { ledlink &= 0xFB; } // Blue blinks if wifi/mqtt lost
- if (!TasmotaGlobal.global_state.wifi_down) { ledlink &= 0xF7; } // Green On
+ uint32_t ledlink = 0x1C; // All leds off
+ if (XdrvMailbox.index) {
+ ledlink &= 0xFB; // Blue blinks if wifi/mqtt lost
+ }
+ else if (!TasmotaGlobal.global_state.wifi_down) {
+ ledlink &= 0xF7; // Green On
+ }
+
ShellyProUpdateLedLink(ledlink);
}
From 4c896cd8bc7c46c1c851dcb520bd60a375bf2873 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 1 Nov 2022 23:07:15 +0100
Subject: [PATCH 120/319] Added Berry ``bytes().reverse()`` method
---
CHANGELOG.md | 1 +
lib/libesp32/berry/src/be_byteslib.c | 69 ++++++++++++++++++++++++++--
lib/libesp32/berry/tests/bytes.be | 23 ++++++++++
3 files changed, 89 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f93336f0..2e4175b87 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
+- Added Berry ``bytes().reverse()`` method
### Breaking Changed
diff --git a/lib/libesp32/berry/src/be_byteslib.c b/lib/libesp32/berry/src/be_byteslib.c
index b2dc9856a..6fcd457db 100644
--- a/lib/libesp32/berry/src/be_byteslib.c
+++ b/lib/libesp32/berry/src/be_byteslib.c
@@ -957,7 +957,6 @@ static int m_setfloat(bvm *vm)
* `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
*
*/
-#include
static int m_setbytes(bvm *vm)
{
int argc = be_top(vm);
@@ -968,7 +967,7 @@ static int m_setbytes(bvm *vm)
size_t from_len_total;
const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
if (idx < 0) { idx = 0; }
- if ((size_t)idx >= attr.len) { idx = attr.len; }
+ if (idx >= attr.len) { idx = attr.len; }
int32_t from_byte = 0;
if (argc >= 4 && be_isint(vm, 4)) {
@@ -981,9 +980,9 @@ static int m_setbytes(bvm *vm)
if (argc >= 5 && be_isint(vm, 5)) {
from_len = be_toint(vm, 5);
if (from_len < 0) { from_len = 0; }
- if (from_len >= from_len_total) { from_len = from_len_total; }
+ if (from_len >= (int32_t)from_len_total) { from_len = from_len_total; }
}
- if ((size_t) idx + (size_t)from_len >= attr.len) { from_len = attr.len - idx; }
+ if (idx + from_len >= attr.len) { from_len = attr.len - idx; }
// all parameters ok
if (from_len > 0) {
@@ -993,6 +992,66 @@ static int m_setbytes(bvm *vm)
be_return_nil(vm);
}
+
+/*
+ * Reverses in-place a sub-buffer composed of groups of n-bytes packets
+ *
+ * This is useful for pixel manipulation when displaying RGB pixels
+ *
+ * `reverse([index:int, len:int, grouplen:int]) -> self`
+ *
+ */
+static int m_reverse(bvm *vm)
+{
+ int argc = be_top(vm);
+ buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
+ check_ptr(vm, &attr);
+
+ int32_t idx = 0; /* start from index 0 */
+ int32_t len = attr.len; /* entire len */
+ int32_t grouplen = 1; /* default to 1-byte group */
+
+ if (argc >= 2 && be_isint(vm, 2)) {
+ idx = be_toint(vm, 2);
+ if (idx < 0) { idx = 0; } /* railguards */
+ if (idx > attr.len) { idx = attr.len; }
+ }
+ if (argc >= 3 && be_isint(vm, 3)) {
+ len = be_toint(vm, 3);
+ if (len < 0) { len = attr.len - idx; } /* negative len means */
+ }
+ if (idx + len >= attr.len) { len = attr.len - idx; }
+
+ // truncate len to multiple of grouplen
+ if (argc >= 4 && be_isint(vm, 4)) {
+ grouplen = be_toint(vm, 4);
+ if (grouplen <= 0) { grouplen = 1; }
+ }
+ len = len - (len % grouplen);
+
+ // apply reverse
+ if (len > 0) {
+ if (grouplen == 1) {
+ /* fast version if simple byte inversion */
+ for (int32_t i = idx, j = idx + len -1; i < j; i++, j--) {
+ uint8_t temp = attr.bufptr[i];
+ attr.bufptr[i] = attr.bufptr[j];
+ attr.bufptr[j] = temp;
+ }
+ } else {
+ for (int32_t i = idx, j = idx + len - grouplen; i < j; i += grouplen, j -= grouplen) {
+ for (int32_t k = 0; k < grouplen; k++) {
+ uint8_t temp = attr.bufptr[i+k];
+ attr.bufptr[i+k] = attr.bufptr[j+k];
+ attr.bufptr[j+k] = temp;
+ }
+ }
+ }
+ }
+ be_pushvalue(vm, 1); /* push bytes object */
+ be_return(vm);
+}
+
static int m_setitem(bvm *vm)
{
int argc = be_top(vm);
@@ -1627,6 +1686,7 @@ void be_load_byteslib(bvm *vm)
{ "size", m_size },
{ "resize", m_resize },
{ "clear", m_clear },
+ { "reverse", m_reverse },
{ "copy", m_copy },
{ "+", m_merge },
{ "..", m_connect },
@@ -1672,6 +1732,7 @@ class be_class_bytes (scope: global, name: bytes) {
size, func(m_size)
resize, func(m_resize)
clear, func(m_clear)
+ reverse, func(m_reverse)
copy, func(m_copy)
+, func(m_merge)
.., func(m_connect)
diff --git a/lib/libesp32/berry/tests/bytes.be b/lib/libesp32/berry/tests/bytes.be
index 44d3f56aa..d2b2c1573 100644
--- a/lib/libesp32/berry/tests/bytes.be
+++ b/lib/libesp32/berry/tests/bytes.be
@@ -225,3 +225,26 @@ assert(a == bytes('112233445566CCDD99'))
a = b.copy()
a.setbytes(0, a0)
assert(a == bytes('112233445566'))
+
+# reverse
+assert(bytes().reverse() == bytes())
+assert(bytes("AA").reverse() == bytes("AA"))
+assert(bytes("1122334455").reverse() == bytes("5544332211"))
+assert(bytes("11223344").reverse() == bytes("44332211"))
+
+assert(bytes("0011223344").reverse(1) == bytes("0044332211"))
+assert(bytes("0011223344").reverse(3) == bytes("0011224433"))
+assert(bytes("0011223344").reverse(4) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(5) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(15) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(-2) == bytes("4433221100"))
+
+assert(bytes("0011223344").reverse(1,3) == bytes("0033221144"))
+assert(bytes("0011223344").reverse(1,0) == bytes("0011223344"))
+assert(bytes("0011223344").reverse(2,2) == bytes("0011332244"))
+assert(bytes("0011223344").reverse(0,2) == bytes("1100223344"))
+assert(bytes("0011223344").reverse(nil,2) == bytes("1100223344"))
+assert(bytes("0011223344").reverse(1, nil) == bytes("0044332211"))
+
+assert(bytes("0011223344").reverse(nil, nil, 2) == bytes("2233001144"))
+assert(bytes("001122334455").reverse(nil, nil, 3) == bytes("334455001122"))
From 0632377192d63d4b9678391e0b6a9be87fa69af9 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 2 Nov 2022 11:24:24 +0100
Subject: [PATCH 121/319] Fix serial initialization
Fix serial initialization for baudrate and config (#16970)
---
CHANGELOG.md | 3 ++-
RELEASENOTES.md | 4 +++-
tasmota/tasmota.ino | 2 +-
tasmota/tasmota_support/support.ino | 7 +++++++
4 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e4175b87..cd5d59493 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
-- Added Berry ``bytes().reverse()`` method
+- Berry ``bytes().reverse()`` method (#16977)
### Breaking Changed
@@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
### Fixed
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
+- Serial initialization for baudrate and config (#16970)
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3177f027d..ab0e97a8a 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -115,7 +115,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
-- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
+- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
+- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
### Breaking Changed
@@ -130,6 +131,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
+- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
### Removed
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 707f95771..c0652c563 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -516,7 +516,7 @@ void setup(void) {
Settings->baudrate = APP_BAUDRATE / 300;
Settings->serial_config = TS_SERIAL_8N1;
}
- SetSerialBaudrate(Settings->baudrate * 300); // Reset serial interface if current baudrate is different from requested baudrate
+ SetSerialInitBegin(); // Reset serial interface if current baudrate and/or config is different from requested settings
if (1 == RtcReboot.fast_reboot_count) { // Allow setting override only when all is well
UpdateQuickPowerCycle(true);
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index 3dbebd6e0..f082a2206 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -1977,6 +1977,13 @@ void SetSerialBegin(void) {
#endif // ESP32
}
+void SetSerialInitBegin(void) {
+ TasmotaGlobal.baudrate = Settings->baudrate * 300;
+ if ((GetSerialBaudrate() != TasmotaGlobal.baudrate) || (TS_SERIAL_8N1 != Settings->serial_config)) {
+ SetSerialBegin();
+ }
+}
+
void SetSerialConfig(uint32_t serial_config) {
if (serial_config > TS_SERIAL_8O2) {
serial_config = TS_SERIAL_8N1;
From b2e9001ca29f6f9b68d74debea15c6d086ca79db Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 2 Nov 2022 22:37:53 +0100
Subject: [PATCH 122/319] Support for DMX ArtNet Led matrix animations
---
CHANGELOG.md | 1 +
tasmota/berry/artnet/artnet.be | 89 +++++++++++++++++++
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 11 ++-
3 files changed, 98 insertions(+), 3 deletions(-)
create mode 100644 tasmota/berry/artnet/artnet.be
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd5d59493..4ac716257 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
- Berry ``bytes().reverse()`` method (#16977)
+- Support for DMX ArtNet Led matrix animations
### Breaking Changed
diff --git a/tasmota/berry/artnet/artnet.be b/tasmota/berry/artnet/artnet.be
new file mode 100644
index 000000000..001987736
--- /dev/null
+++ b/tasmota/berry/artnet/artnet.be
@@ -0,0 +1,89 @@
+# Art-Net driver
+
+class ArtNet
+ var matrix # the led matrix
+ var port # port number for listening for incoming packets
+ var udp_server # instance of `udp` class
+ var universe_start # base universe number
+ var universe_end # last universe number allowed (excluded)
+ static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
+
+ var packet # try reusing the same packer bytes() object for performance
+
+ # local copy of led matrix attributes for faster access
+ var alternate # field from matrix, alternate lines (reversed). Contains 0 if not alternate, or the number of bytes per pixel
+
+ def init(matrix, universe_start, port, ip_addr)
+ self.matrix = matrix
+ self.alternate = matrix.alternate ? matrix.pixel_size() : 0
+ # self.v = self.matrix.v
+ if universe_start == nil universe_start = 0 end
+ self.universe_start = universe_start
+ self.universe_end = universe_start + matrix.h
+
+ if port == nil port = 6454 end
+ # self.artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes
+ self.port = int(port)
+ if ip_addr == nil ip_addr = "" end
+
+ self.udp_server = udp()
+ self.udp_server.begin(ip_addr, self.port)
+
+ # register as fast_loop
+ tasmota.add_fast_loop(/-> self.fast_loop())
+ # set sleep to 5 for a smooth animation
+ tasmota.global.sleep = 5
+ end
+
+ def fast_loop()
+ var universe_start = self.universe_start
+ var universe_end = self.universe_end
+ var dirty = false
+ var packet = self.udp_server.read(self.packet)
+ while (packet != nil)
+ if size(packet) >= 18 && packet[0..7] == self.artnet_sig # check that we have a packet containing the 8 bytes header
+ var opcode = packet.get(8, 2) # should be 0x5000
+ var protocol = packet.get(10, -2) # big endian, should be 14
+ var universe = packet.get(14, 2)
+
+ if opcode == 0x5000 && protocol == 14 && universe >= universe_start && universe < universe_end
+ # tasmota.log("DMX: received Art-Net packet :" + packet.tohex())
+ # var seq = packet.get(12, 1)
+ # var phy = packet.get(13, 1)
+ var data_len = packet.get(16, -2)
+ # data starts at offset 18
+ if size(packet) >= 18 + data_len # check size
+ if self.alternate > 0 && (universe - self.universe_start) % 2
+ packet.reverse(18, self.alternate, -1)
+ end
+ self.matrix.set_bytes(universe, packet, 18, data_len)
+ dirty = true
+ end
+ # import string
+ # tasmota.log(string.format("DMX: opcode=0x%04X protocol=%i seq=%i phy=%i universe=%i data_len=%i data=%s",
+ # opcode, protocol, seq, phy, universe, data_len, packet[18..-1].tohex()))
+ end
+ end
+ packet = self.udp_server.read(packet)
+ if packet == nil
+ tasmota.delay_microseconds(20) # wait 20 us just in case
+ packet = self.udp_server.read(packet)
+ end
+ end
+ self.packet = packet # save bytes() object for next iteration and avoid allocation of new object
+
+ if dirty
+ self.matrix.dirty()
+ self.matrix.show()
+ end
+ end
+end
+
+return ArtNet
+
+#-
+# Example for M5Stack ATOM Matrix (5x5 matrix without alternate)
+var strip = Leds(25, gpio.pin(gpio.WS2812, 0))
+var m = strip.create_matrix(5, 5, 0)
+var dmx = ArtNet(m)
+-#
\ No newline at end of file
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index 27acc5ae7..538da6b09 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -1763,6 +1763,7 @@ void LightReapplyColor(void) {
void LightAnimate(void)
{
bool power_off = false;
+ static int32_t sleep_previous = -1; // previous value of sleep before changing it to PWM_MAX_SLEEP, -1 means unchanged
// make sure we update CT range in case SetOption82 was changed
Light.strip_timer_counter++;
@@ -1770,13 +1771,17 @@ void LightAnimate(void)
// set sleep parameter: either settings,
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
if (Light.power || Light.fade_running) {
- if (Settings->sleep > PWM_MAX_SLEEP) {
+ if (TasmotaGlobal.sleep > PWM_MAX_SLEEP) {
+ sleep_previous = TasmotaGlobal.sleep; // save previous value of sleep
TasmotaGlobal.sleep = PWM_MAX_SLEEP; // set a maximum value (in milliseconds) to sleep to ensure that animations are smooth
} else {
- TasmotaGlobal.sleep = Settings->sleep; // or keep the current sleep if it's low enough
+ sleep_previous = -1; // if low enough, don't change it
}
} else {
- TasmotaGlobal.sleep = Settings->sleep;
+ if (sleep_previous > 0) {
+ TasmotaGlobal.sleep = sleep_previous;
+ sleep_previous = -1; // rearm
+ }
}
if (!Light.power) { // All channels powered off
From f3b6cd1d7391d60498ebd5a84e000591ae37aa29 Mon Sep 17 00:00:00 2001
From: Dmytro Shestakov
Date: Wed, 2 Nov 2022 18:38:53 +0200
Subject: [PATCH 123/319] Add TM1637 driver written in Berry
It allows to use this type of display in addition to any standard
Tasmota display simultaneously
---
tasmota/berry/drivers/tm1637.be | 190 ++++++++++++++++++++++++++++++++
1 file changed, 190 insertions(+)
create mode 100644 tasmota/berry/drivers/tm1637.be
diff --git a/tasmota/berry/drivers/tm1637.be b/tasmota/berry/drivers/tm1637.be
new file mode 100644
index 000000000..9e7b572f0
--- /dev/null
+++ b/tasmota/berry/drivers/tm1637.be
@@ -0,0 +1,190 @@
+#-
+Simplified Tasmota TM1637 driver written in Berry
+Might be helpful in the case of using multiple displays
+Supports only the 4 digit basic display
+
+DIO_PIN and CLK_PIN are your esp32 pin numbers
+How to use
+
+> load('tm1637')
+> tm = Tm1637(DIO_PIN, CLK_PIN)
+> tm.set_on(4)
+> tm.print('0123')
+> tm.print(456)
+
+Add custom commands to the native Tasmota console:
+> tm_add_custom_commands(DIO_PIN, CLK_PIN)
+
+And then:
+TmBrightness 2
+TmPrint 0123
+TmPrint -5.67
+
+Note: adding these commands to autoexec.be should be performed via creating an additional .be file with the content:
+ tm_add_custom_commands(DIO_PIN, CLK_PIN)
+
+and then loading it in autoexec.be via load('tm1637') and load('script_name')
+The direct addition may not work
+-#
+
+class Tm1637
+ static var CMD_CTRL = 0x80
+ static var CMD_DISP_ON = 0x08
+ static var CMD_DATA = 0x40
+ static var CMD_ADDR = 0xC0
+
+ static var SYMB_DOT = 0x80
+
+ static var DIGIT_MAP = {
+ '0': 0x3F,
+ '1': 0x06,
+ '2': 0x5B,
+ '3': 0x4F,
+ '4': 0x66,
+ '5': 0x6D,
+ '6': 0x7D,
+ '7': 0x07,
+ '8': 0x7F,
+ '9': 0x6F,
+ '-': 0x40,
+ ' ': 0x00
+ }
+
+ var PIN_DIO
+ var PIN_CLK
+
+ def init(dio, clk)
+ self.PIN_DIO = dio
+ self.PIN_CLK = clk
+ gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
+ gpio.pin_mode(self.PIN_CLK, gpio.OUTPUT)
+ gpio.digital_write(self.PIN_DIO, 1)
+ gpio.digital_write(self.PIN_CLK, 1)
+ end
+
+ def start()
+ gpio.digital_write(self.PIN_DIO, 1)
+ gpio.digital_write(self.PIN_CLK, 1)
+ gpio.digital_write(self.PIN_DIO, 0)
+ end
+
+ def stop()
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.digital_write(self.PIN_DIO, 0)
+ gpio.digital_write(self.PIN_CLK, 1)
+ gpio.digital_write(self.PIN_DIO, 1)
+ end
+
+ def ack()
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.pin_mode(self.PIN_DIO, gpio.INPUT_PULLUP)
+ var ack_state = gpio.digital_read(self.PIN_DIO) == 0
+ gpio.digital_write(self.PIN_CLK, 1)
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.pin_mode(self.PIN_DIO, gpio.OUTPUT)
+ return ack_state
+ end
+
+ def write_bit(bitval)
+ gpio.digital_write(self.PIN_CLK, 0)
+ gpio.digital_write(self.PIN_DIO, bitval)
+ gpio.digital_write(self.PIN_CLK, 1)
+ end
+
+ def write_byte(byteval)
+ for pos: 0..7
+ self.write_bit((byteval >> pos) & 0x01)
+ end
+ end
+
+ def send_command(command)
+ self.start()
+ self.write_byte(command)
+ var ack_state = self.ack()
+ self.stop()
+ return ack_state
+ end
+
+ def send_data(data)
+ var ack_state = true
+ self.start()
+ for i : 0..size(data)-1
+ self.write_byte(data[i])
+ ack_state = self.ack() && ack_state
+ end
+ self.stop()
+ return ack_state
+ end
+
+ # 0-8 range, 0 to 'OFF'
+ def set_on(brightness)
+ if brightness == nil || brightness > 8
+ brightness = 8
+ elif brightness < 0
+ brightness = 0
+ end
+ var cmd = self.CMD_CTRL
+ if brightness
+ cmd |= self.CMD_DISP_ON
+ brightness -= 1
+ end
+ return self.send_command(cmd | brightness)
+ end
+
+ def print(num)
+ import string
+
+ num = str(num)
+ var max_str_len = 4
+
+ do
+ var dot_pos = string.find(num, '.')
+ if dot_pos >= 0 && dot_pos < 5
+ max_str_len = 5
+ end
+ end
+ if size(num) > max_str_len
+ num = string.split(num, max_str_len)[0]
+ end
+ num = string.format('%4s', num)
+ var payload = bytes(-5)
+ payload[0] = self.CMD_ADDR
+ var int_offset = 1
+ for i : 0..size(num)-1
+ if num[i] == '.'
+ payload[i] |= self.SYMB_DOT
+ int_offset = 0
+ else
+ payload[i + int_offset] = self.DIGIT_MAP[num[i]]
+ end
+ end
+ var ack_state = self.send_command(self.CMD_DATA) && self.send_data(payload)
+ if !ack_state
+ log('TM1637 - no ACK, please check connections')
+ end
+ return ack_state
+ end
+
+ def clear()
+ self.print(' ')
+ end
+
+ # Won't be called on the system restart
+ def deinit()
+ self.set_on(0)
+ end
+end
+
+def tm_add_custom_commands(dio, clk)
+ var tm = Tm1637(dio, clk)
+ tm.clear()
+ tm.set_on(4)
+ tasmota.add_cmd('tmprint', def(cmd, idx, payload)
+ tm.print(payload) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
+ end)
+ # 0-8 range, 0 to 'OFF'
+ tasmota.add_cmd('tmbrightness', def(cmd, idx, payload)
+ tm.set_on(int(payload)) ? tasmota.resp_cmnd_done() : tasmota.resp_cmnd_failed()
+ end)
+ log("Tasmota custom commands registered: TmPrint, TmBrightness")
+end
From 9bd458337f73763aa6ba4b24aefb3e1a9bc1adc4 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 3 Nov 2022 14:24:41 +0100
Subject: [PATCH 124/319] Zigbee fix checksum in ZBBridge Pro router firmware
---
.../SonoffZBPro_router_20220125.hex | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex b/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
index 1d220c012..19bb38b64 100644
--- a/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
+++ b/tools/fw_SonoffZigbeeBridgePro_router_only_cc2652/SonoffZBPro_router_20220125.hex
@@ -5717,6 +5717,6 @@
:20CA1800A0C902000C010020A8C9020000010020B0C9020004010020B8C902000801002086
:020000040005F5
:207FA800000080011000C0FFFDFF58003AC1B9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
-:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF90
+:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF97
:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92
:00000001FF
From 4e9cfc762929d34fe1d12588ff876ae09fd8da35 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 3 Nov 2022 17:26:54 +0100
Subject: [PATCH 125/319] Add command ``SetOption47 1..255``
Add command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge
---
CHANGELOG.md | 3 +-
RELEASENOTES.md | 2 +
tasmota/include/tasmota.h | 2 +-
tasmota/tasmota.ino | 2 +
tasmota/tasmota_support/support.ino | 5 ++
tasmota/tasmota_support/support_tasmota.ino | 52 +++++++++++++++++++--
6 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4ac716257..ac4a43954 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,8 @@ All notable changes to this project will be documented in this file.
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
- Berry ``bytes().reverse()`` method (#16977)
-- Support for DMX ArtNet Led matrix animations
+- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
+- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index ab0e97a8a..e582f6c68 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,6 +109,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.2
### Added
+- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
@@ -118,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
+- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
### Breaking Changed
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index 3dee90dad..a78a5edb1 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -362,7 +362,7 @@ enum SO32_49Index { P_HOLD_TIME, // SetOption32 - (Button/Switch) K
P_IR_TOLERANCE, // SetOption44 - (IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)
P_BISTABLE_PULSE, // SetOption45 - (Bistable) Pulse time for two coil bistable latching relays (default 40)
P_POWER_ON_DELAY, // SetOption46 - (PowerOn) Add delay of 10 x value milliseconds at power on
- P_SO47_FREE, // SetOption47
+ P_POWER_ON_DELAY2, // SetOption47 - (PowerOn) Add delay of value seconds at power on before activating relays
P_SO48_FREE, // SetOption48
P_SO49_FREE // SetOption49
}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index c0652c563..f8cebb836 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -253,6 +253,7 @@ struct TasmotaGlobal_t {
power_t blink_power; // Blink power state
power_t blink_powersave; // Blink start power save state
power_t blink_mask; // Blink relay active mask
+ power_t power_on_delay_state;
int serial_in_byte_counter; // Index in receive buffer
@@ -333,6 +334,7 @@ struct TasmotaGlobal_t {
uint8_t last_source; // Last command source
uint8_t shutters_present; // Number of actual define shutters
uint8_t discovery_counter; // Delayed discovery counter
+ uint8_t power_on_delay; // Delay relay power on to reduce power surge (SetOption47)
#ifdef USE_PWM_DIMMER
uint8_t restore_powered_off_led_counter; // Seconds before powered-off LED (LEDLink) is restored
uint8_t pwm_dimmer_led_bri; // Adjusted brightness LED level
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index f082a2206..2e1e77dd0 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -106,6 +106,11 @@ uint32_t ResetReason(void) {
return ESP_ResetInfoReason();
}
+bool ResetReasonPowerOn(void) {
+ uint32_t reset_reason = ESP_ResetInfoReason();
+ return ((reset_reason == REASON_DEFAULT_RST) || (reset_reason == REASON_EXT_SYS_RST));
+}
+
String GetResetReason(void) {
if (OsWatchBlockedLoop()) {
char buff[32];
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index b51856b4b..a2a9ba8bf 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -240,6 +240,11 @@ void SetLatchingRelay(power_t lpower, uint32_t state) {
}
void SetDevicePower(power_t rpower, uint32_t source) {
+ if (TasmotaGlobal.power_on_delay) {
+ TasmotaGlobal.power_on_delay_state = rpower;
+ return;
+ }
+
ShowSource(source);
TasmotaGlobal.last_source = source;
@@ -384,7 +389,7 @@ void SetPowerOnState(void)
SetDevicePower(1, SRC_RESTART);
} else {
power_t devices_mask = POWER_MASK >> (POWER_SIZE - TasmotaGlobal.devices_present);
- if ((ResetReason() == REASON_DEFAULT_RST) || (ResetReason() == REASON_EXT_SYS_RST)) {
+ if (ResetReasonPowerOn()) {
switch (Settings->poweronstate) {
case POWER_ALL_OFF:
case POWER_ALL_OFF_PULSETIME_ON:
@@ -422,7 +427,8 @@ void SetPowerOnState(void)
uint32_t port = 0;
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
#ifdef ESP8266
- if (!Settings->flag3.no_power_feedback) { // SetOption63 - Don't scan relay power state at restart - #5594 and #5663
+ if (!Settings->flag3.no_power_feedback && // SetOption63 - Don't scan relay power state at restart - #5594 and #5663
+ !TasmotaGlobal.power_on_delay) { // SetOption47 - Delay switching relays to reduce power surge at power on
if ((port < MAX_RELAYS) && PinUsed(GPIO_REL1, port)) {
if (bitRead(TasmotaGlobal.rel_bistable, port)) {
port++; // Skip both bistable relays as always 0
@@ -1056,6 +1062,29 @@ void PerformEverySecond(void)
#endif
}
+ if (TasmotaGlobal.power_on_delay) {
+ if (1 == Settings->param[P_POWER_ON_DELAY2]) { // SetOption47 1
+ // Allow relay power on once network is available
+ if (!TasmotaGlobal.global_state.network_down) {
+ TasmotaGlobal.power_on_delay = 0;
+ }
+ }
+ else if (2 == Settings->param[P_POWER_ON_DELAY2]) { // SetOption47 2
+ // Allow relay power on once mqtt is available
+ if (!TasmotaGlobal.global_state.mqtt_down) {
+ TasmotaGlobal.power_on_delay = 0;
+ }
+ }
+ else { // SetOption47 3..255
+ // Allow relay power on after x seconds
+ TasmotaGlobal.power_on_delay--;
+ }
+ if (!TasmotaGlobal.power_on_delay && TasmotaGlobal.power_on_delay_state) {
+ // Set relays according to last SetDevicePower() request
+ SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_RESTART);
+ }
+ }
+
if (TasmotaGlobal.mqtt_cmnd_blocked_reset) {
TasmotaGlobal.mqtt_cmnd_blocked_reset--;
if (!TasmotaGlobal.mqtt_cmnd_blocked_reset) {
@@ -2046,6 +2075,19 @@ void GpioInit(void)
// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, nitems(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0]));
+ if (ResetReasonPowerOn()) {
+ TasmotaGlobal.power_on_delay = Settings->param[P_POWER_ON_DELAY2]; // SetOption47 - Delay switching relays to reduce power surge at power on
+ if (TasmotaGlobal.power_on_delay) {
+ // This is the earliest possibility to disable relays connected to esp8266/esp32 gpios at power up to reduce power surge
+ for (uint32_t i = 0; i < MAX_RELAYS; i++) {
+ if (PinUsed(GPIO_REL1, i)) {
+ DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); // Off
+ }
+ }
+ AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 Power off relays"));
+ }
+ }
+
analogWriteRange(Settings->pwm_range); // Default is 1023 (Arduino.h)
analogWriteFreq(Settings->pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
@@ -2169,7 +2211,11 @@ void GpioInit(void)
}
}
- delay(Settings->param[P_POWER_ON_DELAY] * 10); // SetOption46 - Allow Wemos D1 power to stabilize before starting I2C polling for devices powered locally
+ if (Settings->param[P_POWER_ON_DELAY]) { // SetOption46 - Allow Wemos D1 power to stabilize before starting I2C polling for devices powered locally
+ uint32_t init_delay = Settings->param[P_POWER_ON_DELAY] * 10;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO46 Wait %d msec"), init_delay);
+ delay(init_delay);
+ }
#ifdef USE_I2C
TasmotaGlobal.i2c_enabled = (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA));
From 1caffb353c2bf246f4658945f75cf4f653f053a5 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 3 Nov 2022 17:50:47 +0100
Subject: [PATCH 126/319] Add more SO47 info
---
tasmota/include/tasmota.h | 4 ++--
tasmota/tasmota_support/support_tasmota.ino | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index a78a5edb1..99a5f780c 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -459,10 +459,10 @@ enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE
enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER,
SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER,
- SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_MAX };
+ SRC_THERMOSTAT, SRC_CHAT, SRC_TCL, SRC_BERRY, SRC_FILE, SRC_SSERIAL, SRC_USBCONSOLE, SRC_SO47, SRC_MAX };
const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|"
"Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|"
- "Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole";
+ "Thermostat|Chat|TCL|Berry|File|SSerial|UsbConsole|SO47";
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index a2a9ba8bf..00fdd00f9 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1081,7 +1081,7 @@ void PerformEverySecond(void)
}
if (!TasmotaGlobal.power_on_delay && TasmotaGlobal.power_on_delay_state) {
// Set relays according to last SetDevicePower() request
- SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_RESTART);
+ SetDevicePower(TasmotaGlobal.power_on_delay_state, SRC_SO47);
}
}
@@ -2084,7 +2084,7 @@ void GpioInit(void)
DigitalWrite(GPIO_REL1, i, bitRead(TasmotaGlobal.rel_inverted, i) ? 1 : 0); // Off
}
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 Power off relays"));
+ AddLog(LOG_LEVEL_DEBUG, PSTR("INI: SO47 %d Power off relays"), Settings->param[P_POWER_ON_DELAY2]);
}
}
From a5e791770486dcbf17db68c0ba01e0a90813b558 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 3 Nov 2022 21:54:21 +0100
Subject: [PATCH 127/319] ESP32 DMX ArtNet optimization to avoid any object
allocation and avoid garbage collector pauses
---
CHANGELOG.md | 1 +
lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 26 ++++++++--
.../berry_tasmota/src/embedded/leds.be | 12 +++--
.../src/solidify/solidified_leds.h | 51 +++++++++++++------
tasmota/berry/artnet/artnet.be | 21 +++++---
.../xdrv_52_3_berry_leds.ino | 8 ---
6 files changed, 83 insertions(+), 36 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac4a43954..d5c140e23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Berry ``bytes().reverse()`` method (#16977)
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
+- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
### Breaking Changed
diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
index 439771fba..4186673c5 100644
--- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
+++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
@@ -94,10 +94,30 @@ extern "C" {
int32_t be_udp_read(struct bvm *vm) {
WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL);
if (udp->parsePacket()) {
- int btr = udp->available();
- uint8_t * buf = (uint8_t*) be_pushbuffer(vm, btr);
+ int btr = udp->available(); // btr contains the size of bytes_to_read
+
+ int argc = be_top(vm);
+ if (argc >= 2 && be_isbytes(vm, 2)) {
+ // we have already a bytes() buffer
+ be_pushvalue(vm, 2); // push on top
+ // resize to btr
+ be_getmember(vm, -1, "resize");
+ be_pushvalue(vm, -2);
+ be_pushint(vm, btr);
+ be_call(vm, 2);
+ be_pop(vm, 3);
+ } else {
+ be_pushbytes(vm, nullptr, btr); // allocate a buffer of size btr filled with zeros
+ }
+
+ // get the address of the buffer
+ be_getmember(vm, -1, "_buffer");
+ be_pushvalue(vm, -2);
+ be_call(vm, 1);
+ uint8_t * buf = (uint8_t*) be_tocomptr(vm, -2);
+ be_pop(vm, 2);
+
int32_t btr2 = udp->read(buf, btr);
- be_pushbytes(vm, buf, btr2);
// set remotet ip
IPAddress remote_ip = udp->remoteIP();
diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be
index 82b154186..23f24ef07 100644
--- a/lib/libesp32/berry_tasmota/src/embedded/leds.be
+++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be
@@ -117,8 +117,14 @@ class Leds : Leds_ntv
def dirty()
self.call_native(5)
end
- def pixels_buffer()
- return self.call_native(6)
+ def pixels_buffer(old_buf)
+ var buf = self.call_native(6) # address of buffer in memory
+ if old_buf == nil
+ return bytes(buf, self.pixel_size() * self.pixel_count())
+ else
+ old_buf._change_buffer(buf)
+ return old_buf
+ end
end
def pixel_size()
return self.call_native(7)
@@ -275,7 +281,7 @@ class Leds : Leds_ntv
# don't trigger on segment, you will need to trigger on full strip instead
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
self.strip.show()
- self.pix_buffer = self.strip.pixels_buffer() # update buffer after show()
+ self.pix_buffer = self.strip.pixels_buffer(self.pix_buffer) # update buffer after show()
end
end
def can_show()
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
index 589c59460..8c8692405 100644
--- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
@@ -1118,7 +1118,7 @@ be_local_closure(Leds_matrix_pixel_count, /* name */
********************************************************************/
be_local_closure(Leds_matrix_show, /* name */
be_nested_proto(
- 4, /* nstack */
+ 5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
@@ -1139,29 +1139,30 @@ be_local_closure(Leds_matrix_show, /* name */
}),
&be_const_str_show,
&be_const_str_solidified,
- ( &(const binstruction[22]) { /* code */
+ ( &(const binstruction[23]) { /* code */
0x60080017, // 0000 GETGBL R2 G23
0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1
0x740A0009, // 0003 JMPT R2 #000E
0x88080100, // 0004 GETMBR R2 R0 K0
0x1C080501, // 0005 EQ R2 R2 K1
- 0x780A000D, // 0006 JMPF R2 #0015
+ 0x780A000E, // 0006 JMPF R2 #0016
0x88080102, // 0007 GETMBR R2 R0 K2
0x880C0103, // 0008 GETMBR R3 R0 K3
0x08080403, // 0009 MUL R2 R2 R3
0x880C0104, // 000A GETMBR R3 R0 K4
0x880C0705, // 000B GETMBR R3 R3 K5
0x1C080403, // 000C EQ R2 R2 R3
- 0x780A0006, // 000D JMPF R2 #0015
+ 0x780A0007, // 000D JMPF R2 #0016
0x88080104, // 000E GETMBR R2 R0 K4
0x8C080506, // 000F GETMET R2 R2 K6
0x7C080200, // 0010 CALL R2 1
0x88080104, // 0011 GETMBR R2 R0 K4
0x8C080508, // 0012 GETMET R2 R2 K8
- 0x7C080200, // 0013 CALL R2 1
- 0x90020E02, // 0014 SETMBR R0 K7 R2
- 0x80000000, // 0015 RET 0
+ 0x88100107, // 0013 GETMBR R4 R0 K7
+ 0x7C080400, // 0014 CALL R2 2
+ 0x90020E02, // 0015 SETMBR R0 K7 R2
+ 0x80000000, // 0016 RET 0
})
)
);
@@ -1452,24 +1453,44 @@ be_local_closure(Leds_create_matrix, /* name */
********************************************************************/
be_local_closure(Leds_pixels_buffer, /* name */
be_nested_proto(
- 4, /* nstack */
- 1, /* argc */
+ 8, /* nstack */
+ 2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
+ ( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str(call_native),
+ /* K1 */ be_nested_str(pixel_size),
+ /* K2 */ be_nested_str(pixel_count),
+ /* K3 */ be_nested_str(_change_buffer),
}),
&be_const_str_pixels_buffer,
&be_const_str_solidified,
- ( &(const binstruction[ 4]) { /* code */
- 0x8C040100, // 0000 GETMET R1 R0 K0
- 0x540E0005, // 0001 LDINT R3 6
- 0x7C040400, // 0002 CALL R1 2
- 0x80040200, // 0003 RET 1 R1
+ ( &(const binstruction[21]) { /* code */
+ 0x8C080100, // 0000 GETMET R2 R0 K0
+ 0x54120005, // 0001 LDINT R4 6
+ 0x7C080400, // 0002 CALL R2 2
+ 0x4C0C0000, // 0003 LDNIL R3
+ 0x1C0C0203, // 0004 EQ R3 R1 R3
+ 0x780E0009, // 0005 JMPF R3 #0010
+ 0x600C0015, // 0006 GETGBL R3 G21
+ 0x5C100400, // 0007 MOVE R4 R2
+ 0x8C140101, // 0008 GETMET R5 R0 K1
+ 0x7C140200, // 0009 CALL R5 1
+ 0x8C180102, // 000A GETMET R6 R0 K2
+ 0x7C180200, // 000B CALL R6 1
+ 0x08140A06, // 000C MUL R5 R5 R6
+ 0x7C0C0400, // 000D CALL R3 2
+ 0x80040600, // 000E RET 1 R3
+ 0x70020003, // 000F JMP #0014
+ 0x8C0C0303, // 0010 GETMET R3 R1 K3
+ 0x5C140400, // 0011 MOVE R5 R2
+ 0x7C0C0400, // 0012 CALL R3 2
+ 0x80040200, // 0013 RET 1 R1
+ 0x80000000, // 0014 RET 0
})
)
);
diff --git a/tasmota/berry/artnet/artnet.be b/tasmota/berry/artnet/artnet.be
index 001987736..1fcdd5053 100644
--- a/tasmota/berry/artnet/artnet.be
+++ b/tasmota/berry/artnet/artnet.be
@@ -6,7 +6,9 @@ class ArtNet
var udp_server # instance of `udp` class
var universe_start # base universe number
var universe_end # last universe number allowed (excluded)
- static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
+ # static var artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes # signature of packet
+ static var artnet_sig_0 = 0x4172742D # "Art-"
+ static var artnet_sig_4 = 0x4E657400 # "Net\x00"
var packet # try reusing the same packer bytes() object for performance
@@ -22,10 +24,11 @@ class ArtNet
self.universe_end = universe_start + matrix.h
if port == nil port = 6454 end
- # self.artnet_sig = bytes().fromstring("Art-Net\x00") # 8 bytes
self.port = int(port)
if ip_addr == nil ip_addr = "" end
+ self.packet = bytes() # instanciate a single bytes() buffer that will be used for all received packets
+
self.udp_server = udp()
self.udp_server.begin(ip_addr, self.port)
@@ -38,10 +41,13 @@ class ArtNet
def fast_loop()
var universe_start = self.universe_start
var universe_end = self.universe_end
+ var artnet_sig_0 = self.artnet_sig_0
+ var artnet_sig_4 = self.artnet_sig_4
var dirty = false
var packet = self.udp_server.read(self.packet)
while (packet != nil)
- if size(packet) >= 18 && packet[0..7] == self.artnet_sig # check that we have a packet containing the 8 bytes header
+ if size(packet) >= 18 &&
+ packet.get(0, -4) == artnet_sig_0 && packet.get(4, -4) == artnet_sig_4
var opcode = packet.get(8, 2) # should be 0x5000
var protocol = packet.get(10, -2) # big endian, should be 14
var universe = packet.get(14, 2)
@@ -64,13 +70,12 @@ class ArtNet
# opcode, protocol, seq, phy, universe, data_len, packet[18..-1].tohex()))
end
end
- packet = self.udp_server.read(packet)
+ packet = self.udp_server.read(self.packet)
if packet == nil
tasmota.delay_microseconds(20) # wait 20 us just in case
- packet = self.udp_server.read(packet)
+ packet = self.udp_server.read(self.packet)
end
end
- self.packet = packet # save bytes() object for next iteration and avoid allocation of new object
if dirty
self.matrix.dirty()
@@ -83,7 +88,9 @@ return ArtNet
#-
# Example for M5Stack ATOM Matrix (5x5 matrix without alternate)
+import artnet
+# var artnet = ArtNet
var strip = Leds(25, gpio.pin(gpio.WS2812, 0))
var m = strip.create_matrix(5, 5, 0)
-var dmx = ArtNet(m)
+var dmx = artnet(m)
-#
\ No newline at end of file
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino
index 54c6c2c15..3d6b8f86b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino
@@ -151,19 +151,11 @@ extern "C" {
break;
case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer)
{
- size_t pixels_bytes;
- if (s_ws2812_grb) pixels_bytes = s_ws2812_grb->PixelsSize();
- if (s_sk6812_grbw) pixels_bytes = s_sk6812_grbw->PixelsSize();
-
uint8_t * pixels;
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
- be_getbuiltin(vm, "bytes");
be_pushcomptr(vm, pixels);
- be_pushint(vm, pixels_bytes);
- be_call(vm, 2);
- be_pop(vm, 2);
}
break;
case 7: // # 07 : PixelSize void -> int
From e7ac249f8f8dc1eab70876cae10f38de80213135 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 3 Nov 2022 22:01:24 +0100
Subject: [PATCH 128/319] Berry reduce detailed GC logs
---
tasmota/my_user_config.h | 1 +
tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino | 2 ++
2 files changed, 3 insertions(+)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e107c385d..b4bc564ef 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -1074,6 +1074,7 @@
#define USE_BERRY_PSRAM // Allocate Berry memory in PSRAM if PSRAM is connected - this might be slightly slower but leaves main memory intact
#define USE_BERRY_IRAM // Allocate some data structures in IRAM (which is ususally unused) when possible and if no PSRAM is available
// #define USE_BERRY_DEBUG // Compile Berry bytecode with line number information, makes exceptions easier to debug. Adds +8% of memory consumption for compiled code
+ // #define UBE_BERRY_DEBUG_GC // Print low-level GC metrics
// #define USE_BERRY_INT64 // Add 64 bits integer support (+1.7KB Flash)
#define USE_WEBCLIENT // Enable `webclient` to make HTTP/HTTPS requests. Can be disabled for security reasons.
// #define USE_WEBCLIENT_HTTPS // Enable HTTPS outgoing requests based on BearSSL (much ligher then mbedTLS, 42KB vs 150KB) in insecure mode (no verification of server's certificate)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
index 36ac8b4e0..d28e0e41e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
@@ -231,6 +231,7 @@ void BerryObservability(bvm *vm, int event...) {
slots_used_before_gc, slots_allocated_before_gc,
slots_used_after_gc, slots_allocated_after_gc);
+#ifdef UBE_BERRY_DEBUG_GC
// Add more in-deptch metrics
AddLog(LOG_LEVEL_DEBUG_MORE, D_LOG_BERRY "GC timing (us) 1:%i 2:%i 3:%i 4:%i 5:%i total:%i",
vm->micros_gc1 - vm->micros_gc0,
@@ -254,6 +255,7 @@ void BerryObservability(bvm *vm, int event...) {
vm->gc_mark_module,
vm->gc_mark_comobj
);
+#endif
// make new threshold tighter when we reach high memory usage
if (!UsePSRAM() && vm->gc.threshold > 20*1024) {
vm->gc.threshold = vm->gc.usage + 10*1024; // increase by only 10 KB
From 4bb9b8614900bdfd3b9106d131ce7c8f0bd28a81 Mon Sep 17 00:00:00 2001
From: pkkrusty <79770016+pkkrusty@users.noreply.github.com>
Date: Sat, 5 Nov 2022 15:38:07 -0700
Subject: [PATCH 129/319] Add options to display section
Section was missing a few defines, and cleaned up the formatting.
---
tasmota/my_user_config.h | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index b4bc564ef..c51a8c9b1 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -693,12 +693,12 @@
// #define INA3221_MAX_COUNT // change the number of devices to search for (default 4).
// // Both settings together allow to limit searching for INA3221 to only a subset of addresses
-// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
-// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
-// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - found in M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code)
-// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC - found Shelly 3EM (I2C address 0x51) (+0k7 code)
+// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
+// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
+// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - found in M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code)
+// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC - found Shelly 3EM (I2C address 0x51) (+0k7 code)
-// #define USE_DISPLAY // Add I2C Display Support (+2k code)
+// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
#define USE_DISPLAY_LCD // [DisplayModel 1] [I2cDriver3] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code)
#define USE_DISPLAY_SSD1306 // [DisplayModel 2] [I2cDriver4] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code)
@@ -712,7 +712,7 @@
#define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module
#define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module
#define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code)
-// #define USE_DISPLAY_SEVENSEG_COMMON_ANODE // Enable support for common anode sevenseg displays
+// #define USE_DISPLAY_SEVENSEG_COMMON_ANODE // Enable support for common anode sevenseg displays
// Multiple sevenseg displays are logically arranged vertically with MTX_ADDRESS1 at y=0,
// MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7
// Command: DisplayText [yn]8888
@@ -720,10 +720,18 @@
// Each segment may be address Command: DisplayText [xn]m
// where n is 0..4 (4 digits and middle :) and m is decimal for bitmap of which segment to turn on.
// Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf
- // #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
-// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
+ // #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
+// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
+//. #define USE_DT_VARS // Display variables that are exposed in JSON MQTT strings e.g. in TelePeriod messages.
+// #define MAX_DT_VARS 16 // Defaults to 7
+//. #define USE_GRAPH // Enable line charts with displays
+//. #define NUM_GRAPHS 4 // Max 16
+
#endif // USE_I2C
+// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code)
+//. #define USE_DISPLAY_TM1637 // [DisplayModel 15] Enable TM1637 Module
+//. #define USE_DISPLAY_MAX7219 // [DisplayModel 15] Enable MAX7219 Module
// -- Universal Display Driver ---------------------------------
// #define USE_UNIVERSAL_DISPLAY // New universal display driver for both I2C and SPI
@@ -751,9 +759,6 @@
#endif // USE_SPI
-//#define USE_DISPLAY // Add Display support
-// #define USE_DISPLAY_TM1637 // [DisplayModel 15] Enable TM1637 module
-
// -- Serial sensors ------------------------------
//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
From e910f3071c6c03df41cb51eb7804ece1b7d4586c Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 6 Nov 2022 10:52:17 +0100
Subject: [PATCH 130/319] Berry add ``dyn`` class
---
CHANGELOG.md | 1 +
lib/libesp32/berry/default/be_modtab.c | 2 +
lib/libesp32/berry_tasmota/src/be_dyn_class.c | 4 +
.../berry_tasmota/src/embedded/dyn.be | 27 +++
.../src/solidify/solidified_dyn.h | 157 ++++++++++++++++++
5 files changed, 191 insertions(+)
create mode 100644 lib/libesp32/berry_tasmota/src/be_dyn_class.c
create mode 100644 lib/libesp32/berry_tasmota/src/embedded/dyn.be
create mode 100644 lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5c140e23..52a1b30b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
+- Berry add ``dyn`` class
### Breaking Changed
diff --git a/lib/libesp32/berry/default/be_modtab.c b/lib/libesp32/berry/default/be_modtab.c
index 1cc28efee..5b018304e 100644
--- a/lib/libesp32/berry/default/be_modtab.c
+++ b/lib/libesp32/berry/default/be_modtab.c
@@ -178,6 +178,7 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
NULL /* do not remove */
};
+be_extern_native_class(dyn);
be_extern_native_class(tasmota);
be_extern_native_class(Trigger);
be_extern_native_class(Driver);
@@ -228,6 +229,7 @@ be_extern_native_class(int64);
BERRY_LOCAL bclass_array be_class_table = {
#ifdef TASMOTA
/* first list are direct classes */
+ &be_native_class(dyn),
&be_native_class(tasmota),
&be_native_class(Trigger),
&be_native_class(Driver),
diff --git a/lib/libesp32/berry_tasmota/src/be_dyn_class.c b/lib/libesp32/berry_tasmota/src/be_dyn_class.c
new file mode 100644
index 000000000..b41ac1b29
--- /dev/null
+++ b/lib/libesp32/berry_tasmota/src/be_dyn_class.c
@@ -0,0 +1,4 @@
+/********************************************************************
+ * Tasmota dyn class
+ *******************************************************************/
+#include "solidify/solidified_dyn.h"
diff --git a/lib/libesp32/berry_tasmota/src/embedded/dyn.be b/lib/libesp32/berry_tasmota/src/embedded/dyn.be
new file mode 100644
index 000000000..5266304ba
--- /dev/null
+++ b/lib/libesp32/berry_tasmota/src/embedded/dyn.be
@@ -0,0 +1,27 @@
+#################################################################################
+# dyn class
+#
+# Allows to use a map with members
+# see https://github.com/berry-lang/berry/wiki/Chapter-8
+#################################################################################
+#@ solidify:dyn
+class dyn
+ var _attr
+ def init()
+ self._attr = {}
+ end
+ def setmember(name, value)
+ self._attr[name] = value
+ end
+ def member(name)
+ if self._attr.contains(name)
+ return self._attr[name]
+ else
+ import undefined
+ return undefined
+ end
+ end
+ def tostring()
+ return self._attr.tostring()
+ end
+end
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h
new file mode 100644
index 000000000..ccb1c98e5
--- /dev/null
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_dyn.h
@@ -0,0 +1,157 @@
+/* Solidification of dyn.h */
+/********************************************************************\
+* Generated code, don't edit *
+\********************************************************************/
+#include "be_constobj.h"
+
+/********************************************************************
+** Solidified function: tostring
+********************************************************************/
+be_local_closure(dyn_tostring, /* name */
+ be_nested_proto(
+ 3, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 2]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ /* K1 */ be_nested_str(tostring),
+ }),
+ &be_const_str_tostring,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x8C040301, // 0001 GETMET R1 R1 K1
+ 0x7C040200, // 0002 CALL R1 1
+ 0x80040200, // 0003 RET 1 R1
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: member
+********************************************************************/
+be_local_closure(dyn_member, /* name */
+ be_nested_proto(
+ 5, /* nstack */
+ 2, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 3]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ /* K1 */ be_nested_str(contains),
+ /* K2 */ be_nested_str(undefined),
+ }),
+ &be_const_str_member,
+ &be_const_str_solidified,
+ ( &(const binstruction[12]) { /* code */
+ 0x88080100, // 0000 GETMBR R2 R0 K0
+ 0x8C080501, // 0001 GETMET R2 R2 K1
+ 0x5C100200, // 0002 MOVE R4 R1
+ 0x7C080400, // 0003 CALL R2 2
+ 0x780A0003, // 0004 JMPF R2 #0009
+ 0x88080100, // 0005 GETMBR R2 R0 K0
+ 0x94080401, // 0006 GETIDX R2 R2 R1
+ 0x80040400, // 0007 RET 1 R2
+ 0x70020001, // 0008 JMP #000B
+ 0xA40A0400, // 0009 IMPORT R2 K2
+ 0x80040400, // 000A RET 1 R2
+ 0x80000000, // 000B RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: setmember
+********************************************************************/
+be_local_closure(dyn_setmember, /* name */
+ be_nested_proto(
+ 4, /* nstack */
+ 3, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ }),
+ &be_const_str_setmember,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 3]) { /* code */
+ 0x880C0100, // 0000 GETMBR R3 R0 K0
+ 0x980C0202, // 0001 SETIDX R3 R1 R2
+ 0x80000000, // 0002 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: init
+********************************************************************/
+be_local_closure(dyn_init, /* name */
+ be_nested_proto(
+ 2, /* nstack */
+ 1, /* argc */
+ 2, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_str(_attr),
+ }),
+ &be_const_str_init,
+ &be_const_str_solidified,
+ ( &(const binstruction[ 4]) { /* code */
+ 0x60040013, // 0000 GETGBL R1 G19
+ 0x7C040000, // 0001 CALL R1 0
+ 0x90020001, // 0002 SETMBR R0 K0 R1
+ 0x80000000, // 0003 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified class: dyn
+********************************************************************/
+be_local_class(dyn,
+ 1,
+ NULL,
+ be_nested_map(5,
+ ( (struct bmapnode*) &(const bmapnode[]) {
+ { be_const_key(tostring, 2), be_const_closure(dyn_tostring_closure) },
+ { be_const_key(member, 3), be_const_closure(dyn_member_closure) },
+ { be_const_key(init, 4), be_const_closure(dyn_init_closure) },
+ { be_const_key(setmember, -1), be_const_closure(dyn_setmember_closure) },
+ { be_const_key(_attr, -1), be_const_var(0) },
+ })),
+ (bstring*) &be_const_str_dyn
+);
+/*******************************************************************/
+
+void be_load_dyn_class(bvm *vm) {
+ be_pushntvclass(vm, &be_class_dyn);
+ be_setglobal(vm, "dyn");
+ be_pop(vm, 1);
+}
+/********************************************************************/
+/* End of solidification */
From 31516f2d34649c0216640b205f7f67d11b2b0618 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 6 Nov 2022 10:12:08 +0100
Subject: [PATCH 131/319] Add ModbusBridge malloc error notes
---
.../xdrv_63_modbus_bridge.ino | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 479ea560b..43bea32bf 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -187,6 +187,10 @@ uint32_t swap_endian32(uint32_t num)
((num<<24)&0xff000000); // byte 0 to byte 3
}
+void ModbusBridgeAllocError(const char* s)
+{
+ AddLog(LOG_LEVEL_ERROR, PSTR("MBS: could not allocate %s buffer"), s);
+}
/********************************************************************************************/
//
@@ -248,6 +252,11 @@ void ModbusBridgeHandle(void)
uint8_t *buffer;
if (modbusBridge.byteCount == 0) modbusBridge.byteCount = modbusBridge.dataCount * 2;
buffer = (uint8_t *)malloc(9 + modbusBridge.byteCount); // Addres(1), Function(1), Length(1), Data(1..n), CRC(2)
+ if (nullptr == buffer)
+ {
+ ModbusBridgeAllocError(PSTR("read"));
+ return;
+ }
memset(buffer, 0, 9 + modbusBridge.byteCount);
uint32_t error = tasmotaModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
@@ -562,9 +571,9 @@ void ModbusBridgeInit(void)
#ifdef USE_MODBUS_BRIDGE_TCP
// If TCP bridge is enabled allocate a TCP receive buffer
modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
- if (!modbusBridgeTCP.tcp_buf)
+ if (nullptr == modbusBridgeTCP.tcp_buf)
{
- AddLog(LOG_LEVEL_ERROR, PSTR("MBS: MBRTCP could not allocate buffer"));
+ ModbusBridgeAllocError(PSTR("TCP"));
return;
}
#endif
@@ -674,6 +683,11 @@ void ModbusTCPHandle(void)
modbusBridge.dataCount = 1;
writeData = (uint16_t *)malloc((byteCount / 2)+1);
+ if (nullptr == writeData)
+ {
+ ModbusBridgeAllocError(PSTR("write"));
+ return;
+ }
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
else count = 1;
@@ -860,6 +874,11 @@ void CmndModbusBridgeSend(void)
else
{
writeData = (uint16_t *)malloc(modbusBridge.dataCount);
+ if (nullptr == writeData)
+ {
+ ModbusBridgeAllocError(PSTR("write"));
+ return;
+ }
for (uint8_t jsonDataArrayPointer = 0; jsonDataArrayPointer < writeDataSize; jsonDataArrayPointer++)
{
From f76bed338be31a2e92f5ba290dbc47820ff6347e Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 6 Nov 2022 10:23:05 +0100
Subject: [PATCH 132/319] Localize ModbusBridge global func/var names
---
.../xdrv_63_modbus_bridge.ino | 106 ++++++++----------
1 file changed, 49 insertions(+), 57 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 43bea32bf..0e39e97a6 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -35,10 +35,10 @@
*
* -- Write multiple coils --
* ModbusSend {"deviceaddress": 1, "functioncode": 15, "startaddress": 1, "type":"bit", "count":4, "values":[1,0,1,1]}
- *
- * Info for modbusBridgeTCPServer:
+ *
+ * Info for modbusBridgeTCPServer:
* https://ipc2u.com/articles/knowledge-base/detailed-description-of-the-modbus-tcp-protocol-with-command-examples/
- *
+ *
* Info for modbus serial communications:
* https://ozeki.hu/p_5879-mobdbus-function-code-4-read-input-registers.html
* https://www.modbustools.com/modbus.html
@@ -102,7 +102,7 @@ ModbusBridgeTCP modbusBridgeTCP;
#endif
#include
-TasmotaModbus *tasmotaModbus = nullptr;
+TasmotaModbus *modbusBridgeModbus = nullptr;
enum class ModbusBridgeError
{
@@ -172,21 +172,13 @@ ModbusBridge modbusBridge;
/********************************************************************************************/
//
-// Helper functions for data conversion between little and big endian
+// Helper functions
//
-uint16_t swap_endian16(uint16_t num)
+uint16_t ModbusBridgeSwapEndian16(uint16_t num)
{
return (num>>8) | (num<<8);
}
-uint32_t swap_endian32(uint32_t num)
-{
- return ((num>>24)&0xff) | // move byte 3 to byte 0
- ((num<<8)&0xff0000) | // move byte 1 to byte 2
- ((num>>8)&0xff00) | // move byte 2 to byte 1
- ((num<<24)&0xff000000); // byte 0 to byte 3
-}
-
void ModbusBridgeAllocError(const char* s)
{
AddLog(LOG_LEVEL_ERROR, PSTR("MBS: could not allocate %s buffer"), s);
@@ -203,7 +195,7 @@ bool ModbusBridgeBegin(void)
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
Settings->modbus_sconfig = TS_SERIAL_8N1;
- int result = tasmotaModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
+ int result = modbusBridgeModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
if (result)
{
if (2 == result)
@@ -215,7 +207,7 @@ bool ModbusBridgeBegin(void)
return result;
}
-void SetModbusBridgeConfig(uint32_t serial_config)
+void ModbusBridgeSetConfig(uint32_t serial_config)
{
if (serial_config > TS_SERIAL_8O2)
{
@@ -228,7 +220,7 @@ void SetModbusBridgeConfig(uint32_t serial_config)
}
}
-void SetModbusBridgeBaudrate(uint32_t baudrate)
+void ModbusBridgeSetBaudrate(uint32_t baudrate)
{
if ((baudrate >= 300) && (baudrate <= 115200))
{
@@ -246,7 +238,7 @@ void SetModbusBridgeBaudrate(uint32_t baudrate)
//
void ModbusBridgeHandle(void)
{
- bool data_ready = tasmotaModbus->ReceiveReady();
+ bool data_ready = modbusBridgeModbus->ReceiveReady();
if (data_ready)
{
uint8_t *buffer;
@@ -258,7 +250,7 @@ void ModbusBridgeHandle(void)
return;
}
memset(buffer, 0, 9 + modbusBridge.byteCount);
- uint32_t error = tasmotaModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
+ uint32_t error = modbusBridgeModbus->ReceiveBuffer(buffer, 0, modbusBridge.byteCount);
#ifdef USE_MODBUS_BRIDGE_TCP
for (uint32_t i = 0; i < nitems(modbusBridgeTCP.client_tcp); i++)
@@ -283,7 +275,7 @@ void ModbusBridgeHandle(void)
nrOfBytes += 1;
client.write(header, 9);
}
- else if (buffer[1] <= 2)
+ else if (buffer[1] <= 2)
{
header[4] = modbusBridge.byteCount >> 8;
header[5] = modbusBridge.byteCount + 3;
@@ -293,7 +285,7 @@ void ModbusBridgeHandle(void)
client.write(buffer + 3, modbusBridge.byteCount); // Don't send CRC
nrOfBytes += modbusBridge.byteCount;
}
- else if (buffer[1] <= 4)
+ else if (buffer[1] <= 4)
{
header[4] = modbusBridge.byteCount >> 8;
header[5] = modbusBridge.byteCount + 3;
@@ -367,10 +359,10 @@ void ModbusBridgeHandle(void)
if (modbusBridge.type == ModbusBridgeType::mb_raw)
{
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"RAW\":["));
- for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
+ for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
{
ResponseAppend_P(PSTR("%d"), buffer[i]);
- if (i < tasmotaModbus->ReceiveCount() - 1)
+ if (i < modbusBridgeModbus->ReceiveCount() - 1)
ResponseAppend_P(PSTR(","));
}
ResponseAppend_P(PSTR("]}"));
@@ -380,10 +372,10 @@ void ModbusBridgeHandle(void)
else if (modbusBridge.type == ModbusBridgeType::mb_hex)
{
Response_P(PSTR("{\"" D_JSON_MODBUS_RECEIVED "\":{\"HEX\":["));
- for (uint8_t i = 0; i < tasmotaModbus->ReceiveCount(); i++)
+ for (uint8_t i = 0; i < modbusBridgeModbus->ReceiveCount(); i++)
{
ResponseAppend_P(PSTR("0x%02X"), buffer[i]);
- if (i < tasmotaModbus->ReceiveCount() - 1)
+ if (i < modbusBridgeModbus->ReceiveCount() - 1)
ResponseAppend_P(PSTR(","));
}
ResponseAppend_P(PSTR("]}"));
@@ -405,7 +397,7 @@ void ModbusBridgeHandle(void)
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
dataOffset = 4;
}
- ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
+ ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d,"), modbusBridge.count);
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_VALUES "\":["));
@@ -539,7 +531,7 @@ void ModbusBridgeHandle(void)
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_DEVICE_ADDRESS "\":%d,"), buffer[0]);
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_FUNCTION_CODE "\":%d,"), buffer[1]);
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_START_ADDRESS "\":%d,"), (buffer[2] << 8) + buffer[3]);
- ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), tasmotaModbus->ReceiveCount());
+ ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_LENGTH "\":%d,"), modbusBridgeModbus->ReceiveCount());
ResponseAppend_P(PSTR("\"" D_JSON_MODBUS_COUNT "\":%d"), (buffer[4] << 8) + buffer[5]);
ResponseAppend_P(PSTR("}"));
ResponseJsonEnd();
@@ -566,7 +558,7 @@ void ModbusBridgeInit(void)
{
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
{
- tasmotaModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
+ modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX));
ModbusBridgeBegin();
#ifdef USE_MODBUS_BRIDGE_TCP
// If TCP bridge is enabled allocate a TCP receive buffer
@@ -591,7 +583,7 @@ void ModbusTCPHandle(void)
bool busy; // did we transfer some data?
int32_t buf_len;
- if (!tasmotaModbus)
+ if (!modbusBridgeModbus)
return;
// check for a new client connection
@@ -665,8 +657,8 @@ void ModbusTCPHandle(void)
if (mbfunctioncode <= 2)
{
count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
- modbusBridge.byteCount = ((count - 1) >> 3) + 1;
- modbusBridge.dataCount = ((count - 1) >> 4) + 1;
+ modbusBridge.byteCount = ((count - 1) >> 3) + 1;
+ modbusBridge.dataCount = ((count - 1) >> 4) + 1;
}
else if (mbfunctioncode <= 4)
{
@@ -676,7 +668,7 @@ void ModbusTCPHandle(void)
}
else
{
- // For functioncode 15 & 16 ignore bytecount, tasmotaModbus does calculate this
+ // For functioncode 15 & 16 ignore bytecount, modbusBridgeModbus does calculate this
uint8_t dataStartByte = mbfunctioncode <= 6 ? 10 : 13;
uint16_t byteCount = (buf_len - dataStartByte);
modbusBridge.byteCount = 2;
@@ -688,10 +680,10 @@ void ModbusTCPHandle(void)
ModbusBridgeAllocError(PSTR("write"));
return;
}
-
+
if ((mbfunctioncode == 15) || (mbfunctioncode == 16)) count = (uint16_t)((((uint16_t)modbusBridgeTCP.tcp_buf[10]) << 8) | ((uint16_t)modbusBridgeTCP.tcp_buf[11]));
else count = 1;
-
+
for (uint16_t dataPointer = 0; dataPointer < byteCount; dataPointer++)
{
if (dataPointer % 2 == 0)
@@ -699,7 +691,7 @@ void ModbusTCPHandle(void)
writeData[dataPointer / 2] = (uint16_t)(((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]) << 8);
}
else
- {
+ {
writeData[dataPointer / 2] |= ((uint16_t)modbusBridgeTCP.tcp_buf[dataStartByte + dataPointer]);
}
}
@@ -708,7 +700,7 @@ void ModbusTCPHandle(void)
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MBS: MBRTCP to Modbus TransactionId:%d, deviceAddress:%d, functionCode:%d, startAddress:%d, count:%d, recvCount:%d, recvBytes:%d"),
modbusBridgeTCP.tcp_transaction_id, mbdeviceaddress, mbfunctioncode, mbstartaddress, count, modbusBridge.dataCount, modbusBridge.byteCount);
- tasmotaModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
+ modbusBridgeModbus->Send(mbdeviceaddress, mbfunctioncode, mbstartaddress, count, writeData);
free(writeData);
}
@@ -908,7 +900,7 @@ void CmndModbusBridgeSend(void)
writeData[jsonDataArrayPointer / 2] = (int8_t)jsonDataArray[jsonDataArrayPointer / 2].getInt(0) << 8;
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
break;
-
+
case ModbusBridgeType::mb_hex:
case ModbusBridgeType::mb_raw:
case ModbusBridgeType::mb_uint8:
@@ -918,31 +910,31 @@ void CmndModbusBridgeSend(void)
writeData[jsonDataArrayPointer / 2] = (uint8_t)jsonDataArray[jsonDataArrayPointer].getUInt(0) << 8;
if (modbusBridge.dataCount != writeDataSize / 2) errorcode = ModbusBridgeError::wrongcount;
break;
-
+
case ModbusBridgeType::mb_int16:
- writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
+ writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
: (int16_t)jsonDataArray[jsonDataArrayPointer].getInt(0);
break;
-
+
case ModbusBridgeType::mb_uint16:
- writeData[jsonDataArrayPointer] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
+ writeData[jsonDataArrayPointer] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
: (int16_t)jsonDataArray[jsonDataArrayPointer].getUInt(0);
break;
-
+
case ModbusBridgeType::mb_int32:
- writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
+ writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0))
: (int16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16);
- writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
+ writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getInt(0) >> 16)
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getInt(0));
break;
-
+
case ModbusBridgeType::mb_uint32:
- writeData[(jsonDataArrayPointer * 2)] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
+ writeData[(jsonDataArrayPointer * 2)] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0))
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16);
- writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? swap_endian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
+ writeData[(jsonDataArrayPointer * 2) + 1] = bitMode ? ModbusBridgeSwapEndian16(jsonDataArray[jsonDataArrayPointer].getUInt(0) >> 16)
: (uint16_t)(jsonDataArray[jsonDataArrayPointer].getUInt(0));
break;
-
+
case ModbusBridgeType::mb_float:
// TODO
default:
@@ -971,20 +963,20 @@ void CmndModbusBridgeSend(void)
if ((modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleCoil) || (modbusBridge.functionCode == ModbusBridgeFunctionCode::mb_writeSingleRegister))
modbusBridge.dataCount = 1;
- uint8_t error = tasmotaModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
+ uint8_t error = modbusBridgeModbus->Send(modbusBridge.deviceAddress, (uint8_t)modbusBridge.functionCode, modbusBridge.startAddress, modbusBridge.dataCount, writeData);
free(writeData);
-
+
if (error)
{
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR Driver send error %u"), error);
return;
- }
+ }
ResponseCmndDone();
}
void CmndModbusBridgeSetBaudrate(void)
{
- SetModbusBridgeBaudrate(XdrvMailbox.payload);
+ ModbusBridgeSetBaudrate(XdrvMailbox.payload);
ResponseCmndNumber(Settings->modbus_sbaudrate * 300);
}
@@ -1000,7 +992,7 @@ void CmndModbusBridgeSetConfig(void)
{ // Use 0..23 as serial config option
if ((XdrvMailbox.payload >= TS_SERIAL_5N1) && (XdrvMailbox.payload <= TS_SERIAL_8O2))
{
- SetModbusBridgeConfig(XdrvMailbox.payload);
+ ModbusBridgeSetConfig(XdrvMailbox.payload);
}
}
else if ((XdrvMailbox.payload >= 5) && (XdrvMailbox.payload <= 8))
@@ -1008,7 +1000,7 @@ void CmndModbusBridgeSetConfig(void)
int8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
if (serial_config >= 0)
{
- SetModbusBridgeConfig(serial_config);
+ ModbusBridgeSetConfig(serial_config);
}
}
}
@@ -1023,7 +1015,7 @@ void CmndModbusBridgeSetConfig(void)
void CmndModbusTCPStart(void)
{
- if (!tasmotaModbus)
+ if (!modbusBridgeModbus)
{
return;
}
@@ -1076,7 +1068,7 @@ void CmndModbusTCPConnect(void)
{
int32_t tcp_port = XdrvMailbox.payload;
- if (!tasmotaModbus)
+ if (!modbusBridgeModbus)
{
return;
}
@@ -1135,7 +1127,7 @@ bool Xdrv63(uint8_t function)
{
ModbusBridgeInit();
}
- else if (tasmotaModbus)
+ else if (modbusBridgeModbus)
{
switch (function)
{
From 050f2e7e61f9544e4996735e6b006a34dc20f2d1 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Sun, 6 Nov 2022 12:32:02 +0100
Subject: [PATCH 133/319] Fix ModbusBridge buffer overflow (#16979)
---
CHANGELOG.md | 1 +
tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52a1b30b0..5a3da0ee0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file.
### Fixed
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
- Serial initialization for baudrate and config (#16970)
+- ModbusBridge buffer overflow (#16979)
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 0e39e97a6..31b1c7a19 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -258,7 +258,7 @@ void ModbusBridgeHandle(void)
WiFiClient &client = modbusBridgeTCP.client_tcp[i];
if (client)
{
- uint8_t header[8];
+ uint8_t header[9];
uint8_t nrOfBytes = 8;
header[0] = modbusBridgeTCP.tcp_transaction_id >> 8;
header[1] = modbusBridgeTCP.tcp_transaction_id;
From 0e32763a4eddaac4738a69cba4f936bd08bd58e0 Mon Sep 17 00:00:00 2001
From: Cossid
Date: Sun, 6 Nov 2022 09:14:03 -0600
Subject: [PATCH 134/319] BP1658CJ - Add support for BP1658CJ RGBCW led driver
control as used in Orein OS0100411267 Bulb
---
.../include/tasmota_configurations_ESP32.h | 1 +
tasmota/include/tasmota_template.h | 7 +
tasmota/language/af_AF.h | 2 +
tasmota/language/bg_BG.h | 2 +
tasmota/language/cs_CZ.h | 2 +
tasmota/language/de_DE.h | 2 +
tasmota/language/el_GR.h | 2 +
tasmota/language/en_GB.h | 2 +
tasmota/language/es_ES.h | 2 +
tasmota/language/fr_FR.h | 2 +
tasmota/language/fy_NL.h | 2 +
tasmota/language/he_HE.h | 2 +
tasmota/language/hu_HU.h | 2 +
tasmota/language/it_IT.h | 2 +
tasmota/language/ko_KO.h | 2 +
tasmota/language/nl_NL.h | 2 +
tasmota/language/pl_PL.h | 2 +
tasmota/language/pt_BR.h | 2 +
tasmota/language/pt_PT.h | 2 +
tasmota/language/ro_RO.h | 2 +
tasmota/language/ru_RU.h | 2 +
tasmota/language/sk_SK.h | 2 +
tasmota/language/sv_SE.h | 2 +
tasmota/language/tr_TR.h | 2 +
tasmota/language/uk_UA.h | 2 +
tasmota/language/vi_VN.h | 2 +
tasmota/language/zh_CN.h | 2 +
tasmota/language/zh_TW.h | 2 +
tasmota/my_user_config.h | 1 +
.../tasmota_xlgt_light/xlgt_10_bp1658cj.ino | 180 ++++++++++++++++++
30 files changed, 241 insertions(+)
create mode 100644 tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index b252a2275..661440aea 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -723,6 +723,7 @@
#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
//#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code)
//#define USE_THERMOSTAT // Add support for Thermostat
+#define USE_BP1658CJ // Add support for BP1658CJ 5 channel led controller as used in Orein OS0100411267 Bulb
#define USE_ETHERNET // Add support for ethernet (+20k code)
#define USE_DISPLAY_TM1621_SONOFF // Add support for TM1621 display driver used by Sonoff POWR3xxD and THR3xxD
diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h
index 831115456..e778914ed 100644
--- a/tasmota/include/tasmota_template.h
+++ b/tasmota/include/tasmota_template.h
@@ -199,6 +199,7 @@ enum UserSelectablePins {
GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device
GPIO_ADE7953_CS, // ADE7953 SPI Chip Select
GPIO_DALI_RX, GPIO_DALI_TX, // Dali
+ GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ
GPIO_SENSOR_END };
// Error as warning to rethink GPIO usage with max 2045
@@ -445,6 +446,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|"
D_SENSOR_ADE7953_CS "|"
D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|"
+ D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|"
;
const char kSensorNamesFixed[] PROGMEM =
@@ -459,6 +461,7 @@ const char kSensorNamesFixed[] PROGMEM =
#define MAX_SM2135_DAT 10
#define MAX_SM2335_DAT 16
#define MAX_DSB 4
+#define MAX_BP1658CJ_DAT 16
const uint16_t kGpioNiceList[] PROGMEM = {
GPIO_NONE, // Not used
@@ -715,6 +718,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK
AGPIO(GPIO_SM2335_DAT) + MAX_SM2335_DAT, // SM2335 DATA
#endif // USE_SM2335
+#ifdef USE_BP1658CJ
+ AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK
+ AGPIO(GPIO_BP1658CJ_DAT) + MAX_BP1658CJ_DAT, // BP1658CJ DATA
+#endif // USE_BP1658CJ
#ifdef USE_BP5758D
AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK
AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA
diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h
index 53f836a14..30093df20 100644
--- a/tasmota/language/af_AF.h
+++ b/tasmota/language/af_AF.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "Diep slaap"
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 784a15f90..dc1fc3d93 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index eb3d4d797..082a1120f 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index d4ba67d4a..4c0db3230 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index a7e79adf7..faaf0bac8 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index 392abdb0e..12e6cd29f 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index 62043d5c5..104ceb164 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 3a26c486f..e24243a8f 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 DAT"
#define D_SENSOR_SM2335_CLK "SM2335 CLK"
#define D_SENSOR_SM2335_DAT "SM2335 DAT"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "Hibernation"
diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h
index 4e2bb00a1..fbbf72aa7 100644
--- a/tasmota/language/fy_NL.h
+++ b/tasmota/language/fy_NL.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index afde4734d..b94395a19 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index 1d753de1b..1a87c6ba1 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index 05dc90c7e..a335c9d16 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -798,6 +798,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 - DATI"
#define D_SENSOR_SM2335_CLK "SM2335 - CLK"
#define D_SENSOR_SM2335_DAT "SM2335 - DATI"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ - CLK"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ - DATI"
#define D_SENSOR_BP5758D_CLK "BP5758D - CLK"
#define D_SENSOR_BP5758D_DAT "BP5758D - DATI"
#define D_SENSOR_DEEPSLEEP "Sleep profondo"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 7fd6d1864..8b3419e98 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index d0f96fe48..4b1b33995 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index a4237e480..d0c98a130 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "Głęboko uśpiony"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index ed31fc1f9..1a429027c 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index e1bde2d58..0b3cd1411 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index b9db344a1..6ceff55a7 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 5e38b74f9..2cf65b605 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 2565fd648..8dec871f6 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index 6c85c366f..ee8eb9167 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index a32bd177a..c0dc1bc30 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index b786a6700..3205c06f6 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index c054ed967..1552aa798 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 63d885088..d34849db2 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index 30db4a4f1..22f72da25 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index b4bc564ef..aacbc1b64 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -562,6 +562,7 @@
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
#define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code)
#define USE_SM2335 // Add support for SM2335 RGBCW led control as used in SwitchBot Color Bulb (+0k7 code)
+#define USE_BP1658CJ // Add support for BP1658CJ RGBCW led control as used in Orein OS0100411267 Bulb
#define USE_BP5758D // Add support for BP5758D RGBCW led control as used in some Tuya lightbulbs (+0k8 code)
#define USE_SONOFF_L1 // Add support for Sonoff L1 led control
#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code)
diff --git a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
new file mode 100644
index 000000000..840022e23
--- /dev/null
+++ b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
@@ -0,0 +1,180 @@
+/*
+ xlgt_10_bp1658cj.ino - bp1658cj five channel led support for Tasmota
+
+ Copyright (C) 2022 Theo Arends and Cossid
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#define US_BP1658CJ
+#ifdef USE_LIGHT
+#ifdef USE_BP1658CJ
+/*********************************************************************************************\
+ * BP1658CJ RGBCW Led bulbs like the Orein OS0100411267 Bulb
+ *
+ * Orein OS0100411267 Bulb
+ *
+ *
+ * FIXME
+ * {"NAME":"Orein OS0100411267 Bulb","GPIO":[0,0,0,0,9129,9088,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1}
+\*********************************************************************************************/
+
+#define XLGT_10 10
+
+// 10 = identification | 00 = Standby | 0000 = start at OUT1/5
+#define BP1658CJ_ADDR_STANDBY 0x80 // 10000000 0x80
+// 10 = identification | 01 = 3 channels (RGB) | 0000 = start at OUT1/5
+//#define BP1658CJ_ADDR_START_3CH 0x90 // 10010000 0xC8
+// 10 = identification | 10 = 2 channels (CW) | 0000 = start at OUT1/5
+//#define BP1658CJ_ADDR_START_2CH 0xA0 // 10100000 0xA0
+// 10 = identification | 11 = 5 channels (RGB+CW) | 0000 = start at OUT1/5
+#define BP1658CJ_ADDR_START_5CH 0xB0 // 10110000 0xB0
+
+// Current values
+// 0x0 // 0000 RGB 0mA | CW 0mA
+// 0x1 // 0001 RGB 10mA | CW 5mA
+// 0x2 // 0010 RGB 20mA | CW 10mA
+// 0x3 // 0011 RGB 30mA | CW 15mA
+// 0x4 // 0100 RGB 40mA | CW 20mA
+// 0x5 // 0101 RGB 50mA | CW 25mA
+// 0x6 // 0110 RGB 60mA | CW 30mA
+// 0x7 // 0111 RGB 70mA | CW 35mA
+// 0x8 // 1000 RGB 80mA | CW 40mA
+// 0x9 // 1001 RGB 900mA | CW 45mA
+// 0xA // 1010 RGB 100mA | CW 50mA
+// 0xB // 1011 RGB 110mA | CW 55mA
+// 0xC // 1100 RGB 120mA | CW 60mA
+// 0xD // 1101 RGB 130mA | CW 65mA
+// 0xE // 1110 RGB 140mA | CW 70mA
+// 0xF // 1111 RGB 150mA | CW 75mA
+
+struct BP1658CJ {
+ uint8_t clk = 0;
+ uint8_t data = 0;
+ uint8_t current;
+} Bp1658cj;
+
+/*********************************************************************************************\
+ * BP1658CJ code - inspired by Bp5758d/SM2335
+\*********************************************************************************************/
+const uint8_t BP1658CJ_DELAY = 2;
+
+void BP1658CJInit(void) {
+ pinMode(Bp1658cj.data, OUTPUT);
+ pinMode(Bp1658cj.clk, OUTPUT);
+ BP1658CJStop();
+}
+
+void BP1658CJWrite(uint8_t value) {
+ for (int bit_idx = 7; bit_idx >= 0; bit_idx--) {
+ bool bit = bitRead(value, bit_idx);
+ digitalWrite(Bp1658cj.data, bit);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ }
+ // Wait for ACK
+ pinMode(Bp1658cj.data, INPUT);
+ digitalWrite(Bp1658cj.clk, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ pinMode(Bp1658cj.data, OUTPUT);
+}
+
+void BP1658CJStart(uint8_t addr) {
+ digitalWrite(Bp1658cj.data, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.clk, LOW);
+ delayMicroseconds(BP1658CJ_DELAY);
+ BP1658CJWrite(addr);
+}
+
+void BP1658CJStop(void) {
+ digitalWrite(Bp1658cj.clk, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+ digitalWrite(Bp1658cj.data, HIGH);
+ delayMicroseconds(BP1658CJ_DELAY);
+}
+
+/********************************************************************************************/
+
+bool BP1658CJSetChannels(void) {
+ uint16_t *cur_col_10 = (uint16_t*)XdrvMailbox.command;
+
+ // If we receive 0 for all channels, we'll assume that the lightbulb is off, and activate BP1658CJ's standby mode.
+ if (cur_col_10[0] == 0 && cur_col_10[1] == 0 && cur_col_10[2] == 0 && cur_col_10[3] == 0 && cur_col_10[4] == 0) {
+ BP1658CJStart(BP1658CJ_ADDR_STANDBY);
+ // Clear all remaining data. This clears out Current, Red, Green, Blue, Cold White, Warm White.
+ for (int i = 0; i < 11; i++) {
+ BP1658CJWrite(0);
+ }
+ BP1658CJStop();
+ return true;
+ }
+
+ // Write the header activating all 5 channels
+ BP1658CJStart(BP1658CJ_ADDR_START_5CH);
+ // Set the current defined in ModuleSelected.
+ BP1658CJWrite(Bp1658cj.current);
+ // Set RGB and CW grayscale.
+ for (int i = 0; i < 5; i++) {
+ BP1658CJWrite((uint8_t)(cur_col_10[i] & 0x1F));
+ BP1658CJWrite((uint8_t)(cur_col_10[i] >> 5));
+ }
+ BP1658CJStop();
+ return true;
+}
+
+void BP1658CJModuleSelected(void)
+{
+ if (PinUsed(GPIO_BP1658CJ_CLK) && PinUsed(GPIO_BP1658CJ_DAT, GPIO_ANY)) {
+ Bp1658cj.clk = Pin(GPIO_BP1658CJ_CLK);
+ Bp1658cj.data = Pin(GPIO_BP1658CJ_DAT, GPIO_ANY);
+ // See #define MAX_BP1658CJ_DAT 16 in tasmota_template.h
+ int currentDat = GetPin(Bp1658cj.data) - AGPIO(GPIO_BP1658CJ_DAT); // 0 .. 15
+ // Split RGB and CW current.
+ Bp1658cj.current = (currentDat << 4) | currentDat;
+
+ BP1658CJInit();
+
+ TasmotaGlobal.light_type = LT_RGBWC;
+ TasmotaGlobal.light_driver = XLGT_10;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("LGT: BP1658CJ Found"));
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xlgt10(uint8_t function)
+{
+ bool result = false;
+
+ switch (function) {
+ case FUNC_SET_CHANNELS:
+ result = BP1658CJSetChannels();
+ break;
+ case FUNC_MODULE_INIT:
+ BP1658CJModuleSelected();
+ break;
+ }
+ return result;
+}
+
+#endif // USE_BP1658CJ
+#endif // USE_LIGHT
From 79928150cbabc5d5b585f1bcbd86763224ee880e Mon Sep 17 00:00:00 2001
From: Cossid
Date: Sun, 6 Nov 2022 09:18:52 -0600
Subject: [PATCH 135/319] BP1658CJ - Remove debugging define.
---
tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino | 1 -
1 file changed, 1 deletion(-)
diff --git a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
index 840022e23..c241e796d 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
@@ -17,7 +17,6 @@
along with this program. If not, see .
*/
-#define US_BP1658CJ
#ifdef USE_LIGHT
#ifdef USE_BP1658CJ
/*********************************************************************************************\
From 1e2e5c308cc118941a94c8acdab34fc2217949f1 Mon Sep 17 00:00:00 2001
From: Cossid
Date: Sun, 6 Nov 2022 09:26:37 -0600
Subject: [PATCH 136/319] BP1658CJ - Add missing language translation for
ca_AD.
---
tasmota/language/ca_AD.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h
index c01ee0d66..153db03f4 100644
--- a/tasmota/language/ca_AD.h
+++ b/tasmota/language/ca_AD.h
@@ -800,6 +800,8 @@
#define D_SENSOR_SM2135_DAT "SM2135 Dat"
#define D_SENSOR_SM2335_CLK "SM2335 Clk"
#define D_SENSOR_SM2335_DAT "SM2335 Dat"
+#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk"
+#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat"
#define D_SENSOR_BP5758D_CLK "BP5758D Clk"
#define D_SENSOR_BP5758D_DAT "BP5758D Dat"
#define D_SENSOR_DEEPSLEEP "DeepSleep"
From 8f920220dba8d78f49d324e632dbf6e295751030 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 6 Nov 2022 17:41:53 +0100
Subject: [PATCH 137/319] Fis default sserialconfig on new installs
---
tasmota/tasmota_support/settings.ino | 1 +
1 file changed, 1 insertion(+)
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index ecfe30063..c31a603bf 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -914,6 +914,7 @@ void SettingsDefaultSet2(void) {
// Serial
Settings->serial_config = TS_SERIAL_8N1;
Settings->baudrate = APP_BAUDRATE / 300;
+ Settings->sserial_config = TS_SERIAL_8N1;
Settings->sbaudrate = SOFT_BAUDRATE / 300;
Settings->serial_delimiter = 0xff;
Settings->seriallog_level = SERIAL_LOG_LEVEL;
From 479b8f4015a4cbfd48d45a768a87a667762011d4 Mon Sep 17 00:00:00 2001
From: Reimer Prochnow
Date: Sun, 6 Nov 2022 18:38:40 +0100
Subject: [PATCH 138/319] fix for #13955
Signed-off-by: Reimer Prochnow
---
tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
index 81f7b3a3e..859d0e5ed 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
@@ -118,11 +118,16 @@ void DeepSleepPrepare(void)
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
}
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep: time %ld, next %ld, slip %ld"),
+ timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
// It may happen that wakeup in just <5 seconds in future
// In this case also add deepsleep to nextwakeup
if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) {
- // ensure nextwakeup is at least in the future
+ // ensure nextwakeup is at least in the future, and add 5%
RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep;
+ RtcSettings.nextwakeup += Settings->deepsleep * 0.05;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep too short: time %ld, next %ld, slip %ld"),
+ timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
}
String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02
From a469b35f021ac2d0d8a8753cb39f22201af5ba00 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 11:06:17 +0100
Subject: [PATCH 139/319] Bump version to v12.2.0.3
---
CHANGELOG.md | 17 ++++++++++++++---
RELEASENOTES.md | 5 ++++-
tasmota/include/tasmota_version.h | 2 +-
tasmota/tasmota_support/support_features.ino | 13 +++++++++----
tools/decode-status.py | 8 ++++----
5 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a3da0ee0..6ed7e1001 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [12.2.0.2]
+## [12.2.0.3]
+### Added
+- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid (#17011)
+
+### Breaking Changed
+
+### Changed
+
+### Fixed
+
+### Removed
+
+## [12.2.0.2] 20221107
### Added
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk (#16938)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
@@ -14,8 +26,6 @@ All notable changes to this project will be documented in this file.
- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
- Berry add ``dyn`` class
-### Breaking Changed
-
### Changed
- Move some persistent data (PowerLow)
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
@@ -25,6 +35,7 @@ All notable changes to this project will be documented in this file.
- Deduplicate code and fix %timer n% rule regression from v12.2.0 (#16914)
- Serial initialization for baudrate and config (#16970)
- ModbusBridge buffer overflow (#16979)
+- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader (#16939)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index e582f6c68..0fc183dd2 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -107,7 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v12.2.0.2
+## Changelog v12.2.0.3
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
@@ -116,6 +116,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
+- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
@@ -134,6 +135,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
+- ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979)
+- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
### Removed
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index 6d24b16b5..c2ac91bfd 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x0C020002; // 12.2.0.2
+const uint32_t VERSION = 0x0C020003; // 12.2.0.3
#endif // _TASMOTA_VERSION_H_
diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino
index 78d972340..9c728ef75 100644
--- a/tasmota/tasmota_support/support_features.ino
+++ b/tasmota/tasmota_support/support_features.ino
@@ -840,10 +840,15 @@ void ResponseAppendFeatures(void)
#if defined(USE_ENERGY_SENSOR) && defined(USE_MODBUS_ENERGY)
feature9 |= 0x00000010; // xnrg_29_modbus.ino
#endif
-// feature9 |= 0x00000020;
-// feature9 |= 0x00000040;
-// feature9 |= 0x00000080;
-
+#if defined(USE_SPI) && defined(USE_SHELLY_PRO)
+ feature9 |= 0x00000020; // xdrv_88_esp32_shelly_pro.ino
+#endif
+#ifdef USE_DALI
+ feature9 |= 0x00000040; // xdrv_89_esp32_dali.ino
+#endif
+#if defined(USE_LIGHT) && defined(USE_BP1658CJ)
+ feature9 |= 0x00000080; // xlgt_10_bp1658cj.ino
+#endif
// feature9 |= 0x00000100;
// feature9 |= 0x00000200;
// feature9 |= 0x00000400;
diff --git a/tools/decode-status.py b/tools/decode-status.py
index d076f11a2..1ae8641e2 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -97,8 +97,8 @@ a_setoption = [[
"(Rotary) Rotary step boundary (default 10)",
"(IR) Base tolerance percentage for matching incoming IR messages (default 25, max 100)",
"(Bistable) Pulse time in milliseconds for two coil bistable latching relays (default 40)",
- "(not used) Tuya MCU power Id",
- "(not used) Energy Tariff1 start hour",
+ "(PowerOn) Add delay of 10 x value milliseconds at power on",
+ "(PowerOn) Add delay of value seconds at power on before activating relays",
"(not used) Energy Tariff2 start hour",
"",
],[
@@ -287,7 +287,7 @@ a_features = [[
"USE_BP5758D","USE_HYT","USE_SM2335","USE_DISPLAY_TM1621_SONOFF"
],[
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
- "USE_MODBUS_ENERGY","","","",
+ "USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
"","","","",
"","","","",
"","","","",
@@ -321,7 +321,7 @@ else:
obj = json.load(fp)
def StartDecode():
- print ("\n*** decode-status.py v12.1.1.4 by Theo Arends and Jacek Ziolkowski ***")
+ print ("\n*** decode-status.py v12.2.0.3 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj))
From 1c47744eeb43c26e31ad171a689d1c2168ea54f0 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 11:56:27 +0100
Subject: [PATCH 140/319] Clean up
---
tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
index 859d0e5ed..27377eeea 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
@@ -118,16 +118,14 @@ void DeepSleepPrepare(void)
RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000);
}
- AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep: time %ld, next %ld, slip %ld"),
- timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DSL: Time %ld, next %ld, slip %ld"), timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip );
// It may happen that wakeup in just <5 seconds in future
// In this case also add deepsleep to nextwakeup
if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) {
// ensure nextwakeup is at least in the future, and add 5%
RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep;
RtcSettings.nextwakeup += Settings->deepsleep * 0.05;
- AddLog(LOG_LEVEL_DEBUG, PSTR("DSPrep too short: time %ld, next %ld, slip %ld"),
- timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DSL: Time too short: time %ld, next %ld, slip %ld"), timeslip, RtcSettings.nextwakeup, RtcSettings.deepsleep_slip);
}
String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02
From 4ebd7a9cd32c9ed29a4baac91108afe986b79643 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 12:46:24 +0100
Subject: [PATCH 141/319] Update ESP32 processor detection
---
tasmota/tasmota_support/support_esp.ino | 91 ++++++++++++++++++++++---
1 file changed, 83 insertions(+), 8 deletions(-)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index b4fb28cf6..9f9e8cfde 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -104,7 +104,14 @@ String GetDeviceHardware(void) {
uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
-
+ /*
+ ESP8266 SoCs
+ - 32-bit MCU & 2.4 GHz Wi-Fi
+ - High-performance 160 MHz single-core CPU
+ - +19.5 dBm output power ensures a good physical range
+ - Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
+ - Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
+ */
if (((efuse1 & (1 << 4)) || (efuse2 & (1 << 16))) && (ESP.getFlashChipRealSize() < 1048577)) { // ESP8285 can only have 1M flash
return F("ESP8285");
}
@@ -768,6 +775,17 @@ typedef struct {
bool single_core = (1 == chip_info.cores);
if (chip_model < 2) { // ESP32
+ /*
+ ESP32 Series
+ - 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth/Bluetooth LE
+ - Two or one CPU core(s) with adjustable clock frequency, ranging from 80 MHz to 240 MHz
+ - +19.5 dBm output power ensures a good physical range
+ - Classic Bluetooth for legacy connections, also supporting L2CAP, SDP, GAP, SMP, AVDTP, AVCTP, A2DP (SNK) and AVRCP (CT)
+ - Support for Bluetooth Low Energy (Bluetooth LE) profiles including L2CAP, GAP, GATT, SMP, and GATT-based profiles like BluFi, SPP-like, etc
+ - Bluetooth Low Energy (Bluetooth LE) connects to smart phones, broadcasting low-energy beacons for easy detection
+ - Sleep current is less than 5 μA, making it suitable for battery-powered and wearable-electronics applications
+ - Peripherals include capacitive touch sensors, Hall sensor, SD card interface, Ethernet, high-speed SPI, UART, I2S and I2C
+ */
#ifdef CONFIG_IDF_TARGET_ESP32
/* esptool:
def get_pkg_version(self):
@@ -807,6 +825,15 @@ typedef struct {
return F("ESP32");
}
else if (2 == chip_model) { // ESP32-S2
+ /*
+ ESP32-S2 Series
+ - 32-bit MCU & 2.4 GHz Wi-Fi
+ - High-performance 240 MHz single-core CPU
+ - Ultra-low-power performance: fine-grained clock gating, dynamic voltage and frequency scaling
+ - Security features: eFuse、flash encryption, secure boot, signature verification, integrated AES, SHA and RSA algorithms
+ - Peripherals include 43 GPIOs, 1 full-speed USB OTG interface, SPI, I2S, UART, I2C, LED PWM, LCD interface, camera interface, ADC, DAC, touch sensor, temperature sensor
+ - Availability of common cloud connectivity agents and common product features shortens the time to market
+ */
#ifdef CONFIG_IDF_TARGET_ESP32S2
/* esptool:
def get_flash_version(self):
@@ -840,13 +867,19 @@ typedef struct {
#endif // CONFIG_IDF_TARGET_ESP32S2
return F("ESP32-S2");
}
- else if (9 == chip_model) { // ESP32-S3
-#ifdef CONFIG_IDF_TARGET_ESP32S3
- // no variants for now
-#endif // CONFIG_IDF_TARGET_ESP32S3
- return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1
+ else if (4 == chip_model) { // ESP32-S3(beta2)
+ return F("ESP32-S3");
}
- else if (5 == chip_model) { // ESP32-C3
+ else if (5 == chip_model) { // ESP32-C3 = ESP8685
+ /*
+ ESP32-C3 Series
+ - 32-bit RISC-V MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
+ - 32-bit RISC-V single-core processor with a four-stage pipeline that operates at up to 160 MHz
+ - State-of-the-art power and RF performance
+ - 400 KB of SRAM and 384 KB of ROM on the chip, and SPI, Dual SPI, Quad SPI, and QPI interfaces that allow connection to flash
+ - Reliable security features ensured by RSA-3072-based secure boot, AES-128-XTS-based flash encryption, the innovative digital signature and the HMAC peripheral, hardware acceleration support for cryptographic algorithms
+ - Rich set of peripheral interfaces and GPIOs, ideal for various scenarios and complex applications
+ */
#ifdef CONFIG_IDF_TARGET_ESP32C3
/* esptool:
def get_pkg_version(self):
@@ -894,7 +927,22 @@ typedef struct {
#endif // CONFIG_IDF_TARGET_ESP32C6
return F("ESP32-C6");
}
- else if (10 == chip_model) { // ESP32-H2
+ else if (9 == chip_model) { // ESP32-S3
+ /*
+ ESP32-S3 Series
+ - 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
+ - Xtensa® 32-bit LX7 dual-core processor that operates at up to 240 MHz
+ - 512 KB of SRAM and 384 KB of ROM on the chip, and SPI, Dual SPI, Quad SPI, Octal SPI, QPI, and OPI interfaces that allow connection to flash and external RAM
+ - Additional support for vector instructions in the MCU, which provides acceleration for neural network computing and signal processing workloads
+ - Peripherals include 45 programmable GPIOs, SPI, I2S, I2C, PWM, RMT, ADC and UART, SD/MMC host and TWAITM
+ - Reliable security features ensured by RSA-based secure boot, AES-XTS-based flash encryption, the innovative digital signature and the HMAC peripheral, “World Controller”
+ */
+#ifdef CONFIG_IDF_TARGET_ESP32S3
+ // no variants for now
+#endif // CONFIG_IDF_TARGET_ESP32S3
+ return F("ESP32-S3"); // Max 240MHz, Dual core, QFN 7*7, ESP32-S3-WROOM-1, ESP32-S3-DevKitC-1
+ }
+ else if (10 == chip_model) { // ESP32-H2(beta1)
#ifdef CONFIG_IDF_TARGET_ESP32H2
/* esptool:
def get_pkg_version(self):
@@ -916,6 +964,33 @@ typedef struct {
#endif // CONFIG_IDF_TARGET_ESP32H2
return F("ESP32-H2");
}
+ else if (12 == chip_model) { // ESP32-C2 = ESP8684
+ /*
+ ESP32-C2 Series
+ - 32-bit RISC-V MCU & 2.4 GHz Wi-Fi & Bluetooth 5 (LE)
+ - 32-bit RISC-V single-core processor that operates at up to 120 MHz
+ - State-of-the-art power and RF performance
+ - 576 KB ROM, 272 KB SRAM (16 KB for cache) on the chip
+ - 14 programmable GPIOs: SPI, UART, I2C, LED PWM controller, General DMA controller (GDMA), SAR ADC, Temperature sensor
+ */
+
+ return F("ESP32-C2");
+ }
+ else if (13 == chip_model) { // ESP32-C6
+ /*
+ ESP32-C6 Series
+ - 32-bit RISC-V MCU & 2.4 GHz Wi-Fi 6 & Bluetooth 5 (LE) & IEEE 802.15.4
+ - 32-bit RISC-V single-core processor that operates at up to 160 MHz
+ - State-of-the-art power and RF performance
+ - 320 KB ROM, 512 KB SRAM, 16 KB Low-power SRAM on the chip, and works with external flash
+ - 30 (QFN40) or 22 (QFN32) programmable GPIOs, with support for SPI, UART, I2C, I2S, RMT, TWAI and PWM
+ */
+
+ return F("ESP32-C6");
+ }
+ else if (14 == chip_model) { // ESP32-H2(beta2)
+ return F("ESP32-H2");
+ }
return F("ESP32");
}
From 7698178b90569a96281e1a2616f7b55b70f11afb Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 15:00:47 +0100
Subject: [PATCH 142/319] Update ESP8285 device detection
---
tasmota/tasmota_support/support_esp.ino | 51 ++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index 9f9e8cfde..9fa5c87cf 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -98,7 +98,7 @@ void *special_calloc(size_t num, size_t size) {
return calloc(num, size);
}
-String GetDeviceHardware(void) {
+String GetDeviceHardwareOld(void) {
// esptool.py get_efuses
uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
@@ -118,6 +118,55 @@ String GetDeviceHardware(void) {
return F("ESP8266EX");
}
+String GetDeviceHardware(void) {
+ /*
+ ESP8266 SoCs
+ - 32-bit MCU & 2.4 GHz Wi-Fi
+ - High-performance 160 MHz single-core CPU
+ - +19.5 dBm output power ensures a good physical range
+ - Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
+ - Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
+ */
+ // esptool.py get_efuses
+ uint32_t efuse0 = *(uint32_t*)(0x3FF00050);
+// uint32_t efuse1 = *(uint32_t*)(0x3FF00054);
+ uint32_t efuse2 = *(uint32_t*)(0x3FF00058);
+ uint32_t efuse3 = *(uint32_t*)(0x3FF0005C);
+
+ bool r0_4 = efuse0 & (1 << 4); // ESP8285
+ bool r2_16 = efuse2 & (1 << 16); // ESP8285
+ if (r0_4 || r2_16) { // ESP8285
+ // 1M 2M 2M 4M
+ // r0_4 1 1 0 0
+ bool r3_25 = efuse3 & (1 << 25); // ESP8285 flash matrix 0 0 1 1
+ bool r3_26 = efuse3 & (1 << 26); // ESP8285 flash matrix 0 1 0 1
+ bool r3_27 = efuse3 & (1 << 27); // ESP8285 flash matrix 0 0 0 0
+ uint32_t pkg_version = 0;
+ if (!r3_27) {
+ if (r0_4 && !r3_25) {
+ pkg_version = (r3_26) ? 2 : 1;
+ }
+ else if (!r0_4 && r3_25) {
+ pkg_version = (r3_26) ? 4 : 2;
+ }
+ }
+ bool max_temp = efuse0 & (1 << 5); // Max flash temperature (0 = 85C, 1 = 105C)
+ switch (pkg_version) {
+ case 1:
+ if (max_temp) { return F("ESP8285H08"); } // 1M flash
+ else { return F("ESP8285N08"); }
+ case 2:
+ if (max_temp) { return F("ESP8285H16"); } // 2M flash
+ else { return F("ESP8285N16"); }
+ case 4:
+ if (max_temp) { return F("ESP8285H32"); } // 4M flash
+ else { return F("ESP8285N32"); }
+ }
+ return F("ESP8285");
+ }
+ return F("ESP8266EX");
+}
+
String GetDeviceHardwareRevision(void) {
// No known revisions for ESP8266/85
return GetDeviceHardware();
From e8f24fdb6c624b78b112c7bdff10b33d094cf34c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 7 Nov 2022 15:02:03 +0100
Subject: [PATCH 143/319] Update ESP8285 processor detection
---
tasmota/tasmota_support/support_esp.ino | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index 9fa5c87cf..a0ce1d228 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -98,26 +98,6 @@ void *special_calloc(size_t num, size_t size) {
return calloc(num, size);
}
-String GetDeviceHardwareOld(void) {
- // esptool.py get_efuses
- uint32_t efuse1 = *(uint32_t*)(0x3FF00050);
- uint32_t efuse2 = *(uint32_t*)(0x3FF00054);
-// uint32_t efuse3 = *(uint32_t*)(0x3FF00058);
-// uint32_t efuse4 = *(uint32_t*)(0x3FF0005C);
- /*
- ESP8266 SoCs
- - 32-bit MCU & 2.4 GHz Wi-Fi
- - High-performance 160 MHz single-core CPU
- - +19.5 dBm output power ensures a good physical range
- - Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
- - Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
- */
- if (((efuse1 & (1 << 4)) || (efuse2 & (1 << 16))) && (ESP.getFlashChipRealSize() < 1048577)) { // ESP8285 can only have 1M flash
- return F("ESP8285");
- }
- return F("ESP8266EX");
-}
-
String GetDeviceHardware(void) {
/*
ESP8266 SoCs
From 5673e11fac48d2fbc1786abfc7970a6c391b2b1c Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Mon, 7 Nov 2022 16:47:43 +0100
Subject: [PATCH 144/319] `DIO` as default for ESP82xx
---
CHANGELOG.md | 1 +
README.md | 3 +--
boards/esp8266_1M.json | 2 +-
boards/esp8266_2M1M.json | 2 +-
boards/esp8266_2M256.json | 2 +-
boards/esp8266_4M2M.json | 2 +-
boards/esp8266_4M3M.json | 2 +-
boards/esp8266_zbbridge.json | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ed7e1001..ccf8be666 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
### Breaking Changed
### Changed
+- Default Flash Mode changed from ``DOUT`` to ``DIO`` for ESP8266/ESP8285
### Fixed
diff --git a/README.md b/README.md
index 48a099409..18b0bb143 100644
--- a/README.md
+++ b/README.md
@@ -62,8 +62,7 @@ Download one of the released binaries from http://ota.tasmota.com/tasmota/releas
## Important User Compilation Information
If you want to compile Tasmota yourself keep in mind the following:
-- For ESP8285 based devices only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device.
-- For ESP8285 based devices Tasmota uses a 1M linker script WITHOUT spiffs **1M (no SPIFFS)** for optimal code space.
+- For ESP8285 based devices Flash Mode **DOUT** and **DIO** are supported. Do not use Flash Mode QIO / QOUT as it might seem to brick your device.
- To make compile time changes to Tasmota use the `user_config_override.h` file. It assures keeping your custom settings when you download and compile a new version. You have to make a copy from the provided `user_config_override_sample.h` file and add your setting overrides.
## Configuration Information
diff --git a/boards/esp8266_1M.json b/boards/esp8266_1M.json
index 6c3327ae7..760b03535 100644
--- a/boards/esp8266_1M.json
+++ b/boards/esp8266_1M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_1M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dout",
+ "flash_mode": "dio",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_2M1M.json b/boards/esp8266_2M1M.json
index 3f34da721..f95bc00ee 100644
--- a/boards/esp8266_2M1M.json
+++ b/boards/esp8266_2M1M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_2M -DESP8266_2M1M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dout",
+ "flash_mode": "dio",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_2M256.json b/boards/esp8266_2M256.json
index 5ef9e86ae..06357e92a 100644
--- a/boards/esp8266_2M256.json
+++ b/boards/esp8266_2M256.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_2M -DESP8266_2M256",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dout",
+ "flash_mode": "dio",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_4M2M.json b/boards/esp8266_4M2M.json
index 9708b2621..69f561e01 100644
--- a/boards/esp8266_4M2M.json
+++ b/boards/esp8266_4M2M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_4M -DESP8266_4M2M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dout",
+ "flash_mode": "dio",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_4M3M.json b/boards/esp8266_4M3M.json
index d1fe7e459..4001b852a 100644
--- a/boards/esp8266_4M3M.json
+++ b/boards/esp8266_4M3M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_4M -DESP8266_4M3M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dout",
+ "flash_mode": "dio",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_zbbridge.json b/boards/esp8266_zbbridge.json
index 726b71de3..b4d76adff 100644
--- a/boards/esp8266_zbbridge.json
+++ b/boards/esp8266_zbbridge.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_2M -DESP8266_2M256",
"f_cpu": "160000000L",
"f_flash": "40000000L",
- "flash_mode": "dout",
+ "flash_mode": "dio",
"mcu": "esp8266",
"variant": "generic"
},
From 6c2cecf29462e8ae559b3f4fa85954d7680cad96 Mon Sep 17 00:00:00 2001
From: pkkrusty <79770016+pkkrusty@users.noreply.github.com>
Date: Mon, 7 Nov 2022 12:03:36 -0800
Subject: [PATCH 145/319] Fixed comment spacing
---
tasmota/my_user_config.h | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index c51a8c9b1..256d9d15d 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -693,12 +693,12 @@
// #define INA3221_MAX_COUNT // change the number of devices to search for (default 4).
// // Both settings together allow to limit searching for INA3221 to only a subset of addresses
-// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
-// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
-// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - found in M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code)
-// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC - found Shelly 3EM (I2C address 0x51) (+0k7 code)
+// #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one
+// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code)
+// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - found in M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code)
+// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC - found Shelly 3EM (I2C address 0x51) (+0k7 code)
-// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code)
+// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
#define USE_DISPLAY_LCD // [DisplayModel 1] [I2cDriver3] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code)
#define USE_DISPLAY_SSD1306 // [DisplayModel 2] [I2cDriver4] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code)
@@ -712,7 +712,7 @@
#define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module
#define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module
#define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code)
-// #define USE_DISPLAY_SEVENSEG_COMMON_ANODE // Enable support for common anode sevenseg displays
+// #define USE_DISPLAY_SEVENSEG_COMMON_ANODE // Enable support for common anode sevenseg displays
// Multiple sevenseg displays are logically arranged vertically with MTX_ADDRESS1 at y=0,
// MTX_ADDRESS2 at y=1, up to MTX_ADDRESS8 at y=7
// Command: DisplayText [yn]8888
@@ -721,21 +721,21 @@
// where n is 0..4 (4 digits and middle :) and m is decimal for bitmap of which segment to turn on.
// Reference: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-led-backpack.pdf
// #define SEVENSEG_ADDRESS1 0x70 // No longer used. Use MTX_ADDRESS1 - MTX_ADDRESS8 instead to specify I2C address of sevenseg displays
-// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
-//. #define USE_DT_VARS // Display variables that are exposed in JSON MQTT strings e.g. in TelePeriod messages.
-// #define MAX_DT_VARS 16 // Defaults to 7
-//. #define USE_GRAPH // Enable line charts with displays
-//. #define NUM_GRAPHS 4 // Max 16
+// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
+//. #define USE_DT_VARS // Display variables that are exposed in JSON MQTT strings e.g. in TelePeriod messages.
+// #define MAX_DT_VARS 16 // Defaults to 7
+//. #define USE_GRAPH // Enable line charts with displays
+//. #define NUM_GRAPHS 4 // Max 16
#endif // USE_I2C
-// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code)
-//. #define USE_DISPLAY_TM1637 // [DisplayModel 15] Enable TM1637 Module
-//. #define USE_DISPLAY_MAX7219 // [DisplayModel 15] Enable MAX7219 Module
+// #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code)
+//. #define USE_DISPLAY_TM1637 // [DisplayModel 15] Enable TM1637 Module
+//. #define USE_DISPLAY_MAX7219 // [DisplayModel 15] Enable MAX7219 Module
// -- Universal Display Driver ---------------------------------
// #define USE_UNIVERSAL_DISPLAY // New universal display driver for both I2C and SPI
- #define MAX_TOUCH_BUTTONS 16 // Virtual touch buttons
+ #define MAX_TOUCH_BUTTONS 16 // Virtual touch buttons
// -- SPI sensors ---------------------------------
//#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
From 83a07895f969cc3a9b959466b035f4596206bd9a Mon Sep 17 00:00:00 2001
From: Barbudor
Date: Mon, 7 Nov 2022 23:27:16 +0100
Subject: [PATCH 146/319] take care of Relay1 is not 1st power
---
.../tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
index d198f2cc5..4013e9540 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
@@ -99,7 +99,10 @@ void DingtianInit(void) {
Dingtian->first = TasmotaGlobal.devices_present;
TasmotaGlobal.devices_present += Dingtian->count;
- AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, Dingtian->first + Dingtian->count);
+ if (TasGlobal.devices_present > POWER_SIZE) {
+ TasGlobal.devices_present = POWER_SIZE;
+ }
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, TasGlobal.devices_present);
}
}
}
@@ -135,9 +138,9 @@ void DingtianLoop()
void DingtianSetPower(void)
{
// store relay status in structure
- Dingtian->outputs = (XdrvMailbox.index >> Dingtian->first) & ~(0xFFFF << Dingtian->count);
+ Dingtian->outputs = (XdrvMailbox.index >> Dingtian->first) & ~(0xFFFFFFFF << Dingtian->count);
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DNGT: outputs=0x%08X"), Dingtian->outputs);
- //DingtianLoop();
+ DingtianLoop();
}
/********************************************************************************************************
@@ -186,8 +189,8 @@ bool Xdrv90(uint8_t function) {
case FUNC_SET_POWER:
DingtianSetPower();
break;
- //case FUNC_EVERY_50_MSECOND:
- case FUNC_EVERY_250_MSECOND:
+ case FUNC_EVERY_50_MSECOND:
+ //case FUNC_EVERY_250_MSECOND:
DingtianLoop();
break;
case FUNC_JSON_APPEND:
@@ -198,7 +201,6 @@ bool Xdrv90(uint8_t function) {
DingtianShow(0);
break;
#endif // USE_WEBSERVER
-
}
}
return result;
From 05b43fb1432804968f1e38df81605ee7a1d81fff Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 8 Nov 2022 15:27:40 +0100
Subject: [PATCH 147/319] Redesign distance sensors HRXL and DYP
Redesign distance sensors HRXL and DYP to use cm instead of mm (#17021)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino | 101 ++++++++-----------
tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino | 50 ++++-----
4 files changed, 64 insertions(+), 89 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ccf8be666..a18085c11 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid (#17011)
### Breaking Changed
+- Redesign distance sensors HRXL and DYP to use cm instead of mm (#17021)
### Changed
- Default Flash Mode changed from ``DOUT`` to ``DIO`` for ESP8266/ESP8285
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 0fc183dd2..6f94c9821 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -123,6 +123,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
### Breaking Changed
+- Redesign distance sensors HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
### Changed
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
diff --git a/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino b/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
index be78b49ec..9d2a60682 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
@@ -25,71 +25,54 @@
* Hardware Serial will be selected if GPIO1 = [HRXL Rx]
\*********************************************************************************************/
-#define XSNS_64 64
-
-#include
+#define XSNS_64 64
#define HRXL_READ_TIMEOUT 400 // us; enough for 6 bytes@9600bps
+#include
TasmotaSerial *HRXLSerial = nullptr;
-uint32_t hrxl_distance_mm = 0; // distance, mm
-bool hrxl_found = false;
+uint32_t hrxl_distance_cm = 0; // distance, cm
/*********************************************************************************************/
-void HRXLInit(void)
-{
- hrxl_found = false;
- if (PinUsed(GPIO_HRXL_RX))
- {
- HRXLSerial = new TasmotaSerial(Pin(GPIO_HRXL_RX), -1, 1);
- if (HRXLSerial->begin(9600))
- {
- if (HRXLSerial->hardwareSerial())
- ClaimSerial();
- hrxl_found = true;
- HRXLSerial->setTimeout(HRXL_READ_TIMEOUT);
- }
+void HRXLInit(void) {
+ if (PinUsed(GPIO_HRXL_RX)) {
+ HRXLSerial = new TasmotaSerial(Pin(GPIO_HRXL_RX), -1, 1);
+ if (HRXLSerial->begin(9600)) {
+ if (HRXLSerial->hardwareSerial()) {
+ ClaimSerial();
+ }
+ HRXLSerial->setTimeout(HRXL_READ_TIMEOUT);
}
+ }
}
-void HRXLEverySecond(void)
-{
- if (!hrxl_found)
- return;
-
- int num_read=0;
- int sum=0;
- while (HRXLSerial->available()>5)
- {
- if (HRXLSerial->read() != 'R')
- continue;
-
- int d = HRXLSerial->parseInt();
- if (d >= 30 && d<=5000)
- {
- sum += d;
- num_read++;
- }
+void HRXLEverySecond(void) {
+ int num_read = 0;
+ int sum = 0;
+ while (HRXLSerial->available() > 5) {
+ if (HRXLSerial->read() != 'R') {
+ continue;
}
- if (num_read>1)
- hrxl_distance_mm = int(sum / num_read);
-
+ int d = HRXLSerial->parseInt();
+ if (d >= 30 && d <= 5000) {
+ sum += d;
+ num_read++;
+ }
+ }
+ if (num_read > 1) {
+ hrxl_distance_cm = int(sum / num_read) / 10; // cm
+ }
}
-
-void HRXLShow(bool json)
-{
+void HRXLShow(bool json) {
char types[5] = "HRXL";
- if (json)
- {
- ResponseAppend_P(PSTR(",\"%s\":{\"" D_DISTANCE "\":%d}"), types, hrxl_distance_mm);
+ if (json) {
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%d}"), types, hrxl_distance_cm);
#ifdef USE_WEBSERVER
- }
- else
- {
- WSContentSend_PD(HTTP_SNS_RANGE, types, hrxl_distance_mm);
+ } else {
+ WSContentSend_PD(HTTP_SNS_DISTANCE_CM, types, hrxl_distance_cm);
#endif // USE_WEBSERVER
}
}
@@ -98,15 +81,12 @@ void HRXLShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns64(uint8_t function)
-{
- if (!PinUsed(GPIO_HRXL_RX)) { return false; }
-
- switch (function)
- {
- case FUNC_INIT:
- HRXLInit();
- break;
+bool Xsns64(uint8_t function) {
+ if (FUNC_INIT == function) {
+ HRXLInit();
+ }
+ else if (HRXLSerial) {
+ switch (function) {
case FUNC_EVERY_SECOND:
HRXLEverySecond();
break;
@@ -118,8 +98,9 @@ bool Xsns64(uint8_t function)
HRXLShow(0);
break;
#endif // USE_WEBSERVER
- }
- return false;
+ }
+ }
+ return false;
}
#endif // USE_HRXL
diff --git a/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino b/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
index 0c4506502..3956e42d8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
@@ -18,7 +18,6 @@
*/
#ifdef USE_DYP
-
/*********************************************************************************************\
* DYP ME007 ultrasonic distance sensor (300...4000mm), serial version
*
@@ -28,13 +27,11 @@
* 300...4000 for measured distance
* 4999 for distance above 4000mm
* 5999 for not connected sensor
- *
\*********************************************************************************************/
-#define XSNS_76 76
+#define XSNS_76 76
#include
-
TasmotaSerial *DYPSerial = nullptr;
#define DYP_CRCERROR -1
@@ -44,27 +41,22 @@ TasmotaSerial *DYPSerial = nullptr;
#define DYP_ABOVEMAX 4999
#define DYP_NOSENSOR 5999
-uint16_t DYPDistance = 0; // distance in milimeters
-bool DYPSensor = false; // sensor available
+uint16_t DYPDistance = 0; // distance in centimeters
/*********************************************************************************************/
void DYPInit(void) {
- DYPSensor = false;
if (PinUsed(GPIO_DYP_RX)) {
DYPSerial = new TasmotaSerial(Pin(GPIO_DYP_RX), -1, 1);
if (DYPSerial->begin(9600)) {
if (DYPSerial->hardwareSerial()) {
ClaimSerial();
}
- DYPSensor = true;
}
}
}
void DYPEverySecond(void) {
- if (!DYPSensor) { return; }
-
// check for serial data
if (DYPSerial->available() < 6) {
DYPDistance = DYP_NOSENSOR;
@@ -95,7 +87,7 @@ void DYPEverySecond(void) {
if (data > DYP_MAX) {
data = DYP_ABOVEMAX;
}
- DYPDistance = data;
+ DYPDistance = data / 10; // cm
} else {
DYPDistance = DYP_CRCERROR;
}
@@ -104,12 +96,12 @@ void DYPEverySecond(void) {
}
void DYPShow(bool json) {
- char types[5] = "DYP";
+ char types[4] = "DYP";
if (json) {
- ResponseAppend_P(PSTR(",\"%s\":{\"" D_DISTANCE "\":%d}"), types, DYPDistance);
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%d}"), types, DYPDistance);
#ifdef USE_WEBSERVER
} else {
- WSContentSend_PD(HTTP_SNS_RANGE, types, DYPDistance);
+ WSContentSend_PD(HTTP_SNS_DISTANCE_CM, types, DYPDistance);
#endif // USE_WEBSERVER
}
}
@@ -119,23 +111,23 @@ void DYPShow(bool json) {
\*********************************************************************************************/
bool Xsns76(uint8_t function) {
- if (!PinUsed(GPIO_DYP_RX)) { return false; }
-
- switch (function) {
- case FUNC_INIT:
- DYPInit();
- break;
- case FUNC_EVERY_SECOND:
- DYPEverySecond();
- break;
- case FUNC_JSON_APPEND:
- DYPShow(1);
- break;
+ if (FUNC_INIT == function) {
+ DYPInit();
+ }
+ else if (DYPSerial) {
+ switch (function) {
+ case FUNC_EVERY_SECOND:
+ DYPEverySecond();
+ break;
+ case FUNC_JSON_APPEND:
+ DYPShow(1);
+ break;
#ifdef USE_WEBSERVER
- case FUNC_WEB_SENSOR:
- DYPShow(0);
- break;
+ case FUNC_WEB_SENSOR:
+ DYPShow(0);
+ break;
#endif // USE_WEBSERVER
+ }
}
return false;
}
From 64ed79debc29246e681cf54794bcbc7e2ee7d94e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 8 Nov 2022 16:16:15 +0100
Subject: [PATCH 148/319] Make distance floats with one decimal (#17021)
---
tasmota/include/i18n.h | 1 +
tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino | 9 +++------
tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino | 9 +++++----
tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino | 9 +++++----
tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino | 14 ++++++--------
5 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 1c46f3df4..5fe199aaa 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -901,6 +901,7 @@ const char HTTP_SNS_RANGE_CHR[] PROGMEM = "{s}%s " D_RANGE "{
const char HTTP_SNS_RANGE[] PROGMEM = "{s}%s " D_RANGE "{m}%d" "{e}";
const char HTTP_SNS_DISTANCE[] PROGMEM = "{s}%s " D_DISTANCE "{m}%d " D_UNIT_MILLIMETER "{e}";
const char HTTP_SNS_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%s " D_UNIT_CENTIMETER "{e}";
+const char HTTP_SNS_F_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}";
const char HTTP_SNS_HALL_EFFECT[] PROGMEM = "{s}%s " D_HALL_EFFECT "{m}%d" "{e}";
const char HTTP_SNS_VOLTAGE[] PROGMEM = "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}";
const char HTTP_SNS_CURRENT[] PROGMEM = "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}";
diff --git a/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino b/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino
index 85c13a97b..df1764430 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino
@@ -190,19 +190,16 @@ void Sr04TReading(void) {
void Sr04Show(bool json) {
if (SR04.valid) { // Check if read failed
- char distance_chr[33];
- dtostrfd(SR04.distance, 3, distance_chr);
-
if(json) {
- ResponseAppend_P(PSTR(",\"SR04\":{\"" D_JSON_DISTANCE "\":%s}"), distance_chr);
+ ResponseAppend_P(PSTR(",\"SR04\":{\"" D_JSON_DISTANCE "\":%1_f}"), &SR04.distance);
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
- DomoticzSensor(DZ_COUNT, distance_chr); // Send distance as Domoticz Counter value
+ DomoticzFloatSensor(DZ_COUNT, SR04.distance); // Send distance as Domoticz Counter value
}
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
- WSContentSend_PD(HTTP_SNS_DISTANCE_CM, "SR04", distance_chr);
+ WSContentSend_PD(HTTP_SNS_F_DISTANCE_CM, "SR04", &SR04.distance);
#endif // USE_WEBSERVER
}
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino b/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
index 9d2a60682..422279cfe 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
@@ -32,7 +32,7 @@
#include
TasmotaSerial *HRXLSerial = nullptr;
-uint32_t hrxl_distance_cm = 0; // distance, cm
+uint32_t hrxl_distance_mm = 0; // distance, mm
/*********************************************************************************************/
@@ -62,17 +62,18 @@ void HRXLEverySecond(void) {
}
}
if (num_read > 1) {
- hrxl_distance_cm = int(sum / num_read) / 10; // cm
+ hrxl_distance_mm = int(sum / num_read); // mm
}
}
void HRXLShow(bool json) {
char types[5] = "HRXL";
+ float distance = (float)hrxl_distance_mm / 10; // cm
if (json) {
- ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%d}"), types, hrxl_distance_cm);
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%1_f}"), types, &distance);
#ifdef USE_WEBSERVER
} else {
- WSContentSend_PD(HTTP_SNS_DISTANCE_CM, types, hrxl_distance_cm);
+ WSContentSend_PD(HTTP_SNS_F_DISTANCE_CM, types, &distance);
#endif // USE_WEBSERVER
}
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino b/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
index 3956e42d8..9c4124fe8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
@@ -41,7 +41,7 @@ TasmotaSerial *DYPSerial = nullptr;
#define DYP_ABOVEMAX 4999
#define DYP_NOSENSOR 5999
-uint16_t DYPDistance = 0; // distance in centimeters
+uint16_t DYPDistance = 0; // distance in millimeters
/*********************************************************************************************/
@@ -87,7 +87,7 @@ void DYPEverySecond(void) {
if (data > DYP_MAX) {
data = DYP_ABOVEMAX;
}
- DYPDistance = data / 10; // cm
+ DYPDistance = data; // mm
} else {
DYPDistance = DYP_CRCERROR;
}
@@ -97,11 +97,12 @@ void DYPEverySecond(void) {
void DYPShow(bool json) {
char types[4] = "DYP";
+ float distance = (float)DYPDistance / 10; // cm
if (json) {
- ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%d}"), types, DYPDistance);
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%1_f}"), types, &distance);
#ifdef USE_WEBSERVER
} else {
- WSContentSend_PD(HTTP_SNS_DISTANCE_CM, types, DYPDistance);
+ WSContentSend_PD(HTTP_SNS_F_DISTANCE_CM, types, &distance);
#endif // USE_WEBSERVER
}
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino b/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino
index 0f31032e0..6b7963f90 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino
@@ -185,24 +185,22 @@ const char HTTP_SNS_SIGNALSTRENGTH[] PROGMEM = "{s}%s " D_SIGNALSTRENGTH "{m}%d{
const char HTTP_SNS_CHIPTEMPERATURE[] PROGMEM = "{s}%s " D_CHIPTEMPERATURE "{m}%d " D_UNIT_DEGREE "%c{e}";
#endif // USE_WEBSERVER
-void TfmpShow(bool json)
-{
+void TfmpShow(bool json) {
char sensor_name[12];
strcpy_P(sensor_name, "TFminiPlus");
- char distance_chr[FLOATSZ];
- dtostrfd(tfminiplus_sensor.distance, 3, distance_chr);
+ float distance = (float)tfminiplus_sensor.distance; // cm
if (json) {
- ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":\"%s\",\"" D_JSON_SIGNALSTRENGTH "\":\"%d\",\"" D_JSON_CHIPTEMPERATURE "\":%d}"),
- sensor_name, distance_chr, tfminiplus_sensor.sigstrength, tfminiplus_sensor.chiptemp);
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":\"%1_f\",\"" D_JSON_SIGNALSTRENGTH "\":\"%d\",\"" D_JSON_CHIPTEMPERATURE "\":%d}"),
+ sensor_name, &distance, tfminiplus_sensor.sigstrength, tfminiplus_sensor.chiptemp);
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
- DomoticzSensor(DZ_COUNT, distance_chr);
+ DomoticzFloatSensor(DZ_COUNT, distance);
}
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
- WSContentSend_P(HTTP_SNS_DISTANCE_CM, sensor_name, distance_chr);
+ WSContentSend_P(HTTP_SNS_F_DISTANCE_CM, sensor_name, &distance);
WSContentSend_P(HTTP_SNS_SIGNALSTRENGTH, sensor_name, tfminiplus_sensor.sigstrength);
WSContentSend_P(HTTP_SNS_CHIPTEMPERATURE, sensor_name, tfminiplus_sensor.chiptemp, TempUnit());
#endif // USE_WEBSERVER
From 381bfbf5bdb0d63c0b6963516ff598ca988a38dd Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 8 Nov 2022 16:59:46 +0100
Subject: [PATCH 149/319] Redesign distance sensors VL53LXX, TOF10120, HRXL and
DYP
Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm (#17021)
---
CHANGELOG.md | 2 +-
RELEASENOTES.md | 2 +-
tasmota/include/i18n.h | 4 +-
.../tasmota_xsns_sensor/xsns_45_vl53l0x.ino | 59 +++++++------------
.../tasmota_xsns_sensor/xsns_77_vl53l1x.ino | 29 ++++-----
.../tasmota_xsns_sensor/xsns_84_tof10120.ino | 10 ++--
6 files changed, 40 insertions(+), 66 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a18085c11..44082a12d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid (#17011)
### Breaking Changed
-- Redesign distance sensors HRXL and DYP to use cm instead of mm (#17021)
+- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm (#17021)
### Changed
- Default Flash Mode changed from ``DOUT`` to ``DIO`` for ESP8266/ESP8285
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 6f94c9821..9f3513302 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -123,7 +123,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
### Breaking Changed
-- Redesign distance sensors HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
+- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
### Changed
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 5fe199aaa..ff4546996 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -886,6 +886,7 @@ const float kSpeedConversionFactor[] = {1, // none
const char HTTP_SNS_F_TEMP[] PROGMEM = "{s}%s " D_TEMPERATURE "{m}%*_f " D_UNIT_DEGREE "%c{e}";
const char HTTP_SNS_F_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%*_f " D_UNIT_VOLT "{e}";
const char HTTP_SNS_F_CURRENT_MA[] PROGMEM = "{s}%s " D_CURRENT "{m}%*_f " D_UNIT_MILLIAMPERE "{e}";
+const char HTTP_SNS_F_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}";
const char HTTP_SNS_HUM[] PROGMEM = "{s}%s " D_HUMIDITY "{m}%s " D_UNIT_PERCENT "{e}";
const char HTTP_SNS_DEW[] PROGMEM = "{s}%s " D_DEWPOINT "{m}%s " D_UNIT_DEGREE "%c{e}";
const char HTTP_SNS_PRESSURE[] PROGMEM = "{s}%s " D_PRESSURE "{m}%s " "%s{e}";
@@ -899,9 +900,6 @@ const char HTTP_SNS_GPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{
const char HTTP_SNS_MOISTURE[] PROGMEM = "{s}%s " D_MOISTURE "{m}%d " D_UNIT_PERCENT "{e}";
const char HTTP_SNS_RANGE_CHR[] PROGMEM = "{s}%s " D_RANGE "{m}%s" "{e}";
const char HTTP_SNS_RANGE[] PROGMEM = "{s}%s " D_RANGE "{m}%d" "{e}";
-const char HTTP_SNS_DISTANCE[] PROGMEM = "{s}%s " D_DISTANCE "{m}%d " D_UNIT_MILLIMETER "{e}";
-const char HTTP_SNS_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%s " D_UNIT_CENTIMETER "{e}";
-const char HTTP_SNS_F_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}";
const char HTTP_SNS_HALL_EFFECT[] PROGMEM = "{s}%s " D_HALL_EFFECT "{m}%d" "{e}";
const char HTTP_SNS_VOLTAGE[] PROGMEM = "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}";
const char HTTP_SNS_CURRENT[] PROGMEM = "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}";
diff --git a/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino b/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino
index 63b10b55c..84eda3ef6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino
@@ -190,53 +190,38 @@ void Vl53l0Every_250MSecond(void) {
void Vl53l0Every_Second(void) {
if (abs(Vl53l0x_data[0].distance - Vl53l0x_data[0].distance_prev) > 8) {
Vl53l0x_data[0].distance_prev = Vl53l0x_data[0].distance;
- DomoticzSensor(DZ_ILLUMINANCE, Vl53l0x_data[0].distance);
+ float distance = (float)Vl53l0x_data[0].distance / 10; // cm
+ DomoticzFloatSensor(DZ_ILLUMINANCE, distance);
}
}
#endif // USE_DOMOTICZ
void Vl53l0Show(boolean json) {
for (uint32_t i = 0; i < VL53LXX_MAX_SENSORS; i++) {
- if (PinUsed(GPIO_VL53LXX_XSHUT1, i) || (!VL53L0X_xshut)) {
- if (json) {
- if (Vl53l0x_data[i].distance == 9999) {
- if (VL53L0X_xshut) {
- ResponseAppend_P(PSTR(",\"VL53L0X_%d\":{\"" D_JSON_DISTANCE "\":null}"), i+1);
- } else {
- ResponseAppend_P(PSTR(",\"VL53L0X\":{\"" D_JSON_DISTANCE "\":null}")); // For backwards compatibility when not using XSHUT GPIOs
- }
- } else {
- if (VL53L0X_xshut) {
- ResponseAppend_P(PSTR(",\"VL53L0X_%d\":{\"" D_JSON_DISTANCE "\":%d}"), i+1, Vl53l0x_data[i].distance);
- } else {
- ResponseAppend_P(PSTR(",\"VL53L0X\":{\"" D_JSON_DISTANCE "\":%d}"), Vl53l0x_data[i].distance); // For backwards compatibility when not using XSHUT GPIOs
- }
- }
-#ifdef USE_WEBSERVER
- } else {
- if (Vl53l0x_data[i].distance == 9999) {
- if (VL53L0X_xshut) {
- WSContentSend_PD("{s}%s_%d " D_DISTANCE "{m}%s {e}", PSTR("VL53L0X"), i+1, PSTR(D_OUT_OF_RANGE));
- } else {
- WSContentSend_PD("{s}%s " D_DISTANCE "{m}%s {e}", PSTR("VL53L0X"), PSTR(D_OUT_OF_RANGE)); // For backwards compatibility when not using XSHUT GPIOs
- }
- } else {
- if (VL53L0X_xshut) {
- WSContentSend_PD("{s}%s_%d " D_DISTANCE "{m}%d " D_UNIT_MILLIMETER "{e}", PSTR("VL53L0X"), i+1, Vl53l0x_data[i].distance);
- } else {
- WSContentSend_PD(HTTP_SNS_DISTANCE, PSTR("VL53L0X"), Vl53l0x_data[i].distance); // For backwards compatibility when not using XSHUT GPIOs
- }
- }
-#endif
- }
+ char types[12] = "VL53L0X";
+ if (VL53L0X_xshut) {
+ snprintf_P(types, sizeof(types), PSTR("VL53L0X%c%d"), IndexSeparator(), i +1);
+ }
+ if (PinUsed(GPIO_VL53LXX_XSHUT1, i) || (!VL53L0X_xshut)) {
+ float distance = (Vl53l0x_data[i].distance == 9999) ? NAN : (float)Vl53l0x_data[i].distance / 10; // cm
+ if (json) {
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%1_f}"), types, &distance);
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_PD(HTTP_SNS_F_DISTANCE_CM, types, &distance);
+#endif
+ }
+ }
+ if (VL53L0X_device[i].timeoutOccurred()) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_I2C "Timeout waiting for %s"), types);
}
- if (VL53L0X_device[i].timeoutOccurred()) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_I2C D_TIMEOUT_WAITING_FOR D_SENSOR " VL53L0X %d"), i+1); }
if (!VL53L0X_xshut) { break; }
}
#ifdef USE_DOMOTICZ
- if ((json) && (0 == TasmotaGlobal.tele_period)){
- DomoticzSensor(DZ_ILLUMINANCE, Vl53l0x_data[0].distance);
- }
+ if (json && (0 == TasmotaGlobal.tele_period)){
+ float distance = (float)Vl53l0x_data[0].distance / 10; // cm
+ DomoticzFloatSensor(DZ_ILLUMINANCE, distance);
+ }
#endif // USE_DOMOTICZ
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
index 810eaa229..d2f188a0f 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
@@ -123,39 +123,30 @@ void Vl53l1Every_250MSecond(void) {
#ifdef USE_DOMOTICZ
void Vl53l1Every_Second(void) {
- char distance[FLOATSZ];
- dtostrfd((float)vl53l1x_data[0].distance / 10, 1, distance);
- DomoticzSensor(DZ_ILLUMINANCE, distance);
+ float distance = (float)vl53l1x_data[0].distance / 10; // cm
+ DomoticzFloatSensor(DZ_ILLUMINANCE, distance);
}
#endif // USE_DOMOTICZ
void Vl53l1Show(bool json) {
uint32_t i, xshut;
for (i = 0, xshut = 1 ; i < VL53LXX_MAX_SENSORS ; i++, xshut <<= 1) {
+ char types[12] = "VL53L1X";
+ if (VL53L0X_xshut) {
+ snprintf_P(types, sizeof(types), PSTR("VL53L1X%c%d"), IndexSeparator(), i +1);
+ }
+ float distance = (float)vl53l1x_data[i].distance / 10; // cm
if (xshut & VL53L1X_detected) {
if (json) {
- if (0 == VL53L1X_xshut) {
- ResponseAppend_P(PSTR(",\"VL53L1X\":{\"" D_JSON_DISTANCE "\":%d}"), vl53l1x_data[i].distance);
- }
- else {
- ResponseAppend_P(PSTR(",\"VL53L1X%c%d\":{\"" D_JSON_DISTANCE "\":%d}"), IndexSeparator(), i+1, vl53l1x_data[i].distance);
- }
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DISTANCE "\":%1_f}"), types, &distance);
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
Vl53l1Every_Second();
}
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
- }
- else {
- if (0 == VL53L1X_xshut) {
- WSContentSend_PD(HTTP_SNS_DISTANCE, PSTR("VL53L1X"), vl53l1x_data[i].distance);
- }
- else {
- char tmpstr[12];
- sprintf(tmpstr, PSTR("VL53L1X%c%d"), IndexSeparator(), i+1);
- WSContentSend_PD(HTTP_SNS_DISTANCE, tmpstr, vl53l1x_data[i].distance);
- }
+ } else {
+ WSContentSend_PD(HTTP_SNS_F_DISTANCE_CM, types, &distance);
#endif
}
} // if detected
diff --git a/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino b/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino
index 233a8cde8..36bd30842 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino
@@ -84,15 +84,15 @@ void Tof10120Every_250MSecond(void) {
#ifdef USE_DOMOTICZ
void Tof10120Every_Second(void) {
- char distance[FLOATSZ];
- dtostrfd((float)tof10120_sensor.distance / 10, 1, distance);
- DomoticzSensor(DZ_ILLUMINANCE, distance);
+ float distance = (float)tof10120_sensor.distance / 10; // cm
+ DomoticzFloatSensor(DZ_ILLUMINANCE, distance);
}
#endif // USE_DOMOTICZ
void Tof10120Show(bool json) {
+ float distance = (float)tof10120_sensor.distance / 10; // cm
if (json) {
- ResponseAppend_P(PSTR(",\"TOF10120\":{\"" D_JSON_DISTANCE "\":%d}"), tof10120_sensor.distance);
+ ResponseAppend_P(PSTR(",\"TOF10120\":{\"" D_JSON_DISTANCE "\":%1_f}"), &distance);
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
Tof10120Every_Second();
@@ -100,7 +100,7 @@ void Tof10120Show(bool json) {
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
- WSContentSend_PD(HTTP_SNS_DISTANCE, PSTR("TOF10120"), tof10120_sensor.distance);
+ WSContentSend_PD(HTTP_SNS_F_DISTANCE_CM, PSTR("TOF10120"), &distance);
#endif
}
}
From 67c4b1be1fa15b77cd31893f83be4b547ed5a068 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 8 Nov 2022 18:08:45 +0100
Subject: [PATCH 150/319] Fix VL53L1X compilation
---
tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
index d2f188a0f..0f30076a5 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
@@ -132,7 +132,7 @@ void Vl53l1Show(bool json) {
uint32_t i, xshut;
for (i = 0, xshut = 1 ; i < VL53LXX_MAX_SENSORS ; i++, xshut <<= 1) {
char types[12] = "VL53L1X";
- if (VL53L0X_xshut) {
+ if (VL53L1X_xshut) {
snprintf_P(types, sizeof(types), PSTR("VL53L1X%c%d"), IndexSeparator(), i +1);
}
float distance = (float)vl53l1x_data[i].distance / 10; // cm
From 64a609eae2a6df1e62c9a0415d340a4b85d3fbc0 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 9 Nov 2022 11:57:34 +0100
Subject: [PATCH 151/319] Revert "`DIO` as default for ESP82xx"
This reverts commit 5673e11fac48d2fbc1786abfc7970a6c391b2b1c.
---
CHANGELOG.md | 1 -
README.md | 3 ++-
boards/esp8266_1M.json | 2 +-
boards/esp8266_2M1M.json | 2 +-
boards/esp8266_2M256.json | 2 +-
boards/esp8266_4M2M.json | 2 +-
boards/esp8266_4M3M.json | 2 +-
boards/esp8266_zbbridge.json | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44082a12d..9edf22ad4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,6 @@ All notable changes to this project will be documented in this file.
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm (#17021)
### Changed
-- Default Flash Mode changed from ``DOUT`` to ``DIO`` for ESP8266/ESP8285
### Fixed
diff --git a/README.md b/README.md
index 18b0bb143..48a099409 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,8 @@ Download one of the released binaries from http://ota.tasmota.com/tasmota/releas
## Important User Compilation Information
If you want to compile Tasmota yourself keep in mind the following:
-- For ESP8285 based devices Flash Mode **DOUT** and **DIO** are supported. Do not use Flash Mode QIO / QOUT as it might seem to brick your device.
+- For ESP8285 based devices only Flash Mode **DOUT** is supported. Do not use Flash Mode DIO / QIO / QOUT as it might seem to brick your device.
+- For ESP8285 based devices Tasmota uses a 1M linker script WITHOUT spiffs **1M (no SPIFFS)** for optimal code space.
- To make compile time changes to Tasmota use the `user_config_override.h` file. It assures keeping your custom settings when you download and compile a new version. You have to make a copy from the provided `user_config_override_sample.h` file and add your setting overrides.
## Configuration Information
diff --git a/boards/esp8266_1M.json b/boards/esp8266_1M.json
index 760b03535..6c3327ae7 100644
--- a/boards/esp8266_1M.json
+++ b/boards/esp8266_1M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_1M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dio",
+ "flash_mode": "dout",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_2M1M.json b/boards/esp8266_2M1M.json
index f95bc00ee..3f34da721 100644
--- a/boards/esp8266_2M1M.json
+++ b/boards/esp8266_2M1M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_2M -DESP8266_2M1M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dio",
+ "flash_mode": "dout",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_2M256.json b/boards/esp8266_2M256.json
index 06357e92a..5ef9e86ae 100644
--- a/boards/esp8266_2M256.json
+++ b/boards/esp8266_2M256.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_2M -DESP8266_2M256",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dio",
+ "flash_mode": "dout",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_4M2M.json b/boards/esp8266_4M2M.json
index 69f561e01..9708b2621 100644
--- a/boards/esp8266_4M2M.json
+++ b/boards/esp8266_4M2M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_4M -DESP8266_4M2M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dio",
+ "flash_mode": "dout",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_4M3M.json b/boards/esp8266_4M3M.json
index 4001b852a..d1fe7e459 100644
--- a/boards/esp8266_4M3M.json
+++ b/boards/esp8266_4M3M.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_4M -DESP8266_4M3M",
"f_cpu": "80000000L",
"f_flash": "40000000L",
- "flash_mode": "dio",
+ "flash_mode": "dout",
"mcu": "esp8266",
"variant": "generic"
},
diff --git a/boards/esp8266_zbbridge.json b/boards/esp8266_zbbridge.json
index b4d76adff..726b71de3 100644
--- a/boards/esp8266_zbbridge.json
+++ b/boards/esp8266_zbbridge.json
@@ -7,7 +7,7 @@
"extra_flags": "-DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_2M -DESP8266_2M256",
"f_cpu": "160000000L",
"f_flash": "40000000L",
- "flash_mode": "dio",
+ "flash_mode": "dout",
"mcu": "esp8266",
"variant": "generic"
},
From dd1586fbfccc7e7cd67cdbb0c11576eb95a0a657 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 9 Nov 2022 12:19:33 +0100
Subject: [PATCH 152/319] Bump version to v12.2.0.4
- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
---
CHANGELOG.md | 19 ++++++++++++++-----
RELEASENOTES.md | 3 +--
tasmota/include/tasmota_version.h | 2 +-
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9edf22ad4..36944cc1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [12.2.0.3]
+## [12.2.0.4]
+### Added
+
+### Breaking Changed
+
+### Changed
+- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
+
+### Fixed
+
+### Removed
+
+## [12.2.0.3] 20221109
### Added
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid (#17011)
@@ -11,10 +23,7 @@ All notable changes to this project will be documented in this file.
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm (#17021)
### Changed
-
-### Fixed
-
-### Removed
+- Default Flash Mode changed from ``DOUT`` to ``DIO`` for ESP8266/ESP8285
## [12.2.0.2] 20221107
### Added
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 9f3513302..dd095cca6 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -107,7 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v12.2.0.3
+## Changelog v12.2.0.4
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
@@ -139,6 +139,5 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979)
- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
-
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index c2ac91bfd..360603d83 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x0C020003; // 12.2.0.3
+const uint32_t VERSION = 0x0C020004; // 12.2.0.4
#endif // _TASMOTA_VERSION_H_
From 41c4af7dfee33610a44c7180a31905970cee0a0e Mon Sep 17 00:00:00 2001
From: barbudor
Date: Wed, 9 Nov 2022 22:01:01 +0100
Subject: [PATCH 153/319] change mqtt DINGTIAN_CHG to STAT
---
tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
index 4013e9540..05a1fb1b3 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
@@ -130,7 +130,7 @@ void DingtianLoop()
}
ResponseAppend_P(PSTR("}}"));
if (first_done) {
- MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR("DINGTIAN_CHG"));
+ MqttPublishPrefixTopicRulesProcess_P(STAT, PSTR("DINGTIAN_CHG"));
}
}
}
From b5ce17112f7beef03d04fcb6f6da9c3dd939eba1 Mon Sep 17 00:00:00 2001
From: Thomas Hargrove
Date: Wed, 9 Nov 2022 15:33:16 -0800
Subject: [PATCH 154/319] Fix for error on first command sent to S8 module
---
.../tasmota_xsns_sensor/xsns_17_senseair.ino | 21 ++++++++++---------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino b/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino
index ea6ba683b..de7d5a89b 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino
@@ -70,7 +70,7 @@ void Senseair250ms(void) // Every 250 mSec
if (data_ready) {
uint8_t error = SenseairModbus->Receive16BitRegister(&value);
if (error) {
- AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "SenseAir response error %d"), error);
+ AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "SenseAir read register %02X gave response error %d"), (uint16_t)start_addresses[senseair_read_state], error);
} else {
switch(senseair_read_state) {
case 0: // 0x1A (26) READ_TYPE_LOW - S8: fe 04 02 01 77 ec 92
@@ -104,15 +104,16 @@ void Senseair250ms(void) // Every 250 mSec
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "SenseAir temp adjustment %d"), value);
break;
}
- }
- senseair_read_state++;
- if (2 == senseair_type) { // S8
- if (3 == senseair_read_state) {
- senseair_read_state = 1;
- }
- } else { // K30, K70
- if (sizeof(start_addresses) == senseair_read_state) {
- senseair_read_state = 1;
+
+ senseair_read_state++;
+ if (2 == senseair_type) { // S8
+ if (3 == senseair_read_state) {
+ senseair_read_state = 1;
+ }
+ } else { // K30, K70
+ if (sizeof(start_addresses) == senseair_read_state) {
+ senseair_read_state = 1;
+ }
}
}
}
From 2ae8faca2a2d6d49efb7c05acfe09512fc5a8a54 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Nov 2022 11:52:47 +0100
Subject: [PATCH 155/319] Tasmota Core 2.0.5.3
---
platformio_tasmota32.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini
index 1e64da35b..e9d36ada9 100644
--- a/platformio_tasmota32.ini
+++ b/platformio_tasmota32.ini
@@ -40,7 +40,7 @@ extra_scripts = pre:pio-tools/add_c_flags.py
${esp_defaults.extra_scripts}
[core32]
-platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.2/platform-espressif32-2.0.5.2.zip
+platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip
platform_packages =
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
From f16c555f2b704a2a4e60103b69863c07daff874f Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Nov 2022 12:49:13 +0100
Subject: [PATCH 156/319] Tasmota core v2.0.5.3
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 36944cc1a..52caf593a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
+- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
### Fixed
From 1146955312bb9da22671b7864ac53c5abcfd7c6e Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Nov 2022 12:52:38 +0100
Subject: [PATCH 157/319] Core 2.0.5.3
---
RELEASENOTES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index dd095cca6..0094082ef 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -126,7 +126,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
### Changed
-- ESP32 Framework (Core) from v2.0.5 to v2.0.5.2
+- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
From e83882b655e4ae99378b84a29073588b1e825742 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 10 Nov 2022 13:54:05 +0100
Subject: [PATCH 158/319] Update changelogs
---
CHANGELOG.md | 3 +++
RELEASENOTES.md | 13 ++++++++-----
tasmota/tasmota_support/support_features.ino | 4 +++-
tools/decode-status.py | 4 ++--
4 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52caf593a..8f5e4b364 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
## [12.2.0.4]
### Added
+- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
+- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
### Breaking Changed
@@ -13,6 +15,7 @@ All notable changes to this project will be documented in this file.
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
### Fixed
+- SenseAir S8 module detection (#17033)
### Removed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 0094082ef..353786be4 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -33,9 +33,9 @@ While fallback or downgrading is common practice it was never supported due to S
This release will be supported from ESP8266/Arduino library Core version **2.7.4.9** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
-This release will be supported from ESP32/Arduino library Core version **2.0.5**.
+This release will be supported from ESP32/Arduino library Core version **2.0.5.3**.
-Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.5 have been removed.
+Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.5.3 have been removed.
## Support of TLS
@@ -77,7 +77,7 @@ Historical binaries can be downloaded from
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
### ESP32, ESP32-C3, ESP32-S2 and ESP32-S3 based
-The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.5**.
+The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.5.3**.
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota32xy.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3/S2/S3 and 4M+ flash.
@@ -110,13 +110,15 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.4
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
-- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
+- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Support for Digital Addressable Lighting Interface (DALI) by Andrei Kazmirtsuk [#16938](https://github.com/arendst/Tasmota/issues/16938)
- Support for NTAG2xx tags read and write on PN532 NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
+- Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971)
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
+- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
@@ -133,11 +135,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
### Fixed
+- Serial bridge default serial configuration from 5N1 to 8N1 regression from v10.1.0.3
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
- ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979)
-- Default serial bridge configuration from 5N1 to 8N1 regression from v10.1.0.3
+- SenseAir S8 module detection [#17033](https://github.com/arendst/Tasmota/issues/17033)
### Removed
- Define ``USE_PN532_DATA_RAW`` from NFC reader [#16939](https://github.com/arendst/Tasmota/issues/16939)
diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino
index 9c728ef75..f61e15e14 100644
--- a/tasmota/tasmota_support/support_features.ino
+++ b/tasmota/tasmota_support/support_features.ino
@@ -849,7 +849,9 @@ void ResponseAppendFeatures(void)
#if defined(USE_LIGHT) && defined(USE_BP1658CJ)
feature9 |= 0x00000080; // xlgt_10_bp1658cj.ino
#endif
-// feature9 |= 0x00000100;
+#ifdef USE_DINGTIAN_RELAY
+ feature9 |= 0x00000100; // xdrv_90_dingtian_relay.ino
+#endif
// feature9 |= 0x00000200;
// feature9 |= 0x00000400;
// feature9 |= 0x00000800;
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 1ae8641e2..8a8324025 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -288,7 +288,7 @@ a_features = [[
],[
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
- "","","","",
+ "USE_DINGTIAN_RELAY","","","",
"","","","",
"","","","",
"","","","",
@@ -321,7 +321,7 @@ else:
obj = json.load(fp)
def StartDecode():
- print ("\n*** decode-status.py v12.2.0.3 by Theo Arends and Jacek Ziolkowski ***")
+ print ("\n*** decode-status.py v12.2.0.4 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj))
From 986a9d10aeedf005773ab5b03808583d0269444a Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 10 Nov 2022 16:02:00 +0100
Subject: [PATCH 159/319] Refactor serial raw data representation
---
tasmota/tasmota_support/support_tasmota.ino | 3 +--
tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino | 5 ++---
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index 00fdd00f9..6741df57c 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1854,8 +1854,7 @@ void SerialInput(void)
} else {
ResponseAppend_P(PSTR("\""));
if (Settings->flag.mqtt_serial_raw) {
- char hex_char[(TasmotaGlobal.serial_in_byte_counter * 2) + 2];
- ResponseAppend_P(ToHex_P((unsigned char*)TasmotaGlobal.serial_in_buffer, TasmotaGlobal.serial_in_byte_counter, hex_char, sizeof(hex_char)));
+ ResponseAppend_P(PSTR("%*_H"), TasmotaGlobal.serial_in_byte_counter, TasmotaGlobal.serial_in_buffer);
} else {
ResponseAppend_P(EscapeJSONString(TasmotaGlobal.serial_in_buffer).c_str());
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index e8c156a5d..8b5617b47 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -158,8 +158,7 @@ void SerialBridgeInput(void) {
} else {
ResponseAppend_P(PSTR("\""));
if (serial_bridge_raw) {
- char hex_char[(serial_bridge_in_byte_counter * 2) + 2];
- ResponseAppend_P(ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)));
+ ResponseAppend_P(PSTR("%*_H"), serial_bridge_in_byte_counter, serial_bridge_buffer);
} else {
ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str());
}
@@ -171,7 +170,7 @@ void SerialBridgeInput(void) {
XdrvRulesProcess(0);
} else {
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
- }
+ }
serial_bridge_in_byte_counter = 0;
}
}
From c5963d6f2738d08e9298250f68e3d8225b9bc6cb Mon Sep 17 00:00:00 2001
From: bovirus <1262554+bovirus@users.noreply.github.com>
Date: Thu, 10 Nov 2022 21:27:42 +0100
Subject: [PATCH 160/319] Update italian language
---
tasmota/language/it_IT.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index e718cbc51..7aecb90f5 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele.
*
- * Updated until v9.4.0.1 - Last update 30.10.2022
+ * Updated until v9.4.0.1 - Last update 10.11.2022
\*********************************************************************/
#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@@ -900,11 +900,11 @@
#define D_GPIO_SHIFT595_RCLK "74x595 - RCLK"
#define D_GPIO_SHIFT595_OE "74x595 - OE"
#define D_GPIO_SHIFT595_SER "74x595 - SER"
-#define D_GPIO_DINGTIAN_CLK "Dingtian CLK"
-#define D_GPIO_DINGTIAN_SDI "Dingtian SDI"
-#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7"
-#define D_GPIO_DINGTIAN_PL "Dingtian PL"
-#define D_GPIO_DINGTIAN_RCK "Dingtian RCK"
+#define D_GPIO_DINGTIAN_CLK "Dingtian - CLK"
+#define D_GPIO_DINGTIAN_SDI "Dingtian - SDI"
+#define D_GPIO_DINGTIAN_Q7 "Dingtian - Q7"
+#define D_GPIO_DINGTIAN_PL "Dingtian - PL"
+#define D_GPIO_DINGTIAN_RCK "Dingtian - RCK"
#define D_SENSOR_CM11_TX "CM110x - TX"
#define D_SENSOR_CM11_RX "CM110x - RX"
#define D_SENSOR_FLOWRATEMETER "Portata"
From b7f6a7b00adba896358dd805c19a7e4cce65d530 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 09:30:31 +0100
Subject: [PATCH 161/319] Clean up logging functions
---
lib/default/Ext-printf/src/ext_printf.cpp | 21 +++++++++++++++++++++
tasmota/tasmota.ino | 2 +-
tasmota/tasmota_support/support_esp.ino | 14 ++++++--------
tasmota/tasmota_support/support_tasmota.ino | 2 +-
4 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/lib/default/Ext-printf/src/ext_printf.cpp b/lib/default/Ext-printf/src/ext_printf.cpp
index d15f4bcee..17a32701f 100644
--- a/lib/default/Ext-printf/src/ext_printf.cpp
+++ b/lib/default/Ext-printf/src/ext_printf.cpp
@@ -299,6 +299,27 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
break;
+/*
+ case 'V': // 2-byte values, decimals indicates the length, default 2
+ {
+ if (decimals < 0) { decimals = 0; }
+ if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
+ else if (decimals > 0) {
+ uint32_t val_size = decimals*6 + 2;
+ char * val_char = (char*) malloc(val_size);
+ val_char[0] = '\0';
+ for (uint32_t count = 0; count < decimals; count++) {
+ uint32_t value = pgm_read_byte((const uint8_t *)cur_val +1) << 8 | pgm_read_byte((const uint8_t *)cur_val);
+ snprintf_P(val_char, val_size, PSTR("%s%s%d"), val_char, (count)?",":"", value);
+ cur_val += 2;
+ }
+ new_val_str = val_char;
+ allocs[alloc_idx++] = new_val_str;
+ // Serial.printf("> values=%s\n", hex_char);
+ }
+ }
+ break;
+*/
// case 'D':
// decimals = *(int32_t*)cur_val_ptr;
// break;
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index f8cebb836..702b06253 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -549,7 +549,7 @@ void setup(void) {
#endif
#endif // USE_EMULATION
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&TasmotaGlobal, sizeof(TasmotaGlobal));
+// AddLog(LOG_LEVEL_INFO, PSTR("DBG: TasmotaGlobal size %d, data %*_H"), sizeof(TasmotaGlobal), 100, (uint8_t*)&TasmotaGlobal);
if (Settings->param[P_BOOT_LOOP_OFFSET]) { // SetOption36
// Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts)
diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino
index a0ce1d228..30b6129c9 100644
--- a/tasmota/tasmota_support/support_esp.ino
+++ b/tasmota/tasmota_support/support_esp.ino
@@ -116,11 +116,11 @@ String GetDeviceHardware(void) {
bool r0_4 = efuse0 & (1 << 4); // ESP8285
bool r2_16 = efuse2 & (1 << 16); // ESP8285
if (r0_4 || r2_16) { // ESP8285
- // 1M 2M 2M 4M
- // r0_4 1 1 0 0
- bool r3_25 = efuse3 & (1 << 25); // ESP8285 flash matrix 0 0 1 1
- bool r3_26 = efuse3 & (1 << 26); // ESP8285 flash matrix 0 1 0 1
- bool r3_27 = efuse3 & (1 << 27); // ESP8285 flash matrix 0 0 0 0
+ // 1M 2M 2M 4M flash size
+ // r0_4 1 1 0 0
+ bool r3_25 = efuse3 & (1 << 25); // flash matrix 0 0 1 1
+ bool r3_26 = efuse3 & (1 << 26); // flash matrix 0 1 0 1
+ bool r3_27 = efuse3 & (1 << 27); // flash matrix 0 0 0 0
uint32_t pkg_version = 0;
if (!r3_27) {
if (r0_4 && !r3_25) {
@@ -654,11 +654,9 @@ uint8_t* FlashDirectAccess(void) {
uint32_t address = FlashWriteStartSector() * SPI_FLASH_SEC_SIZE;
uint8_t* data = EspFlashMmap(address);
/*
- AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Flash start address 0x%08X, Mmap address 0x%08X"), address, data);
-
uint8_t buf[32];
memcpy(buf, data, sizeof(buf));
- AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&buf, 32);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Flash start address 0x%08X, Mmap address 0x%08X, Data %*_H"), address, data, sizeof(buf), (uint8_t*)&buf);
*/
return data;
}
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index 6741df57c..dbe7ceb5f 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -2072,7 +2072,7 @@ void GpioInit(void)
if (mpin) { SetPin(i, mpin); } // Anything above GPIO_NONE and below GPIO_SENSOR_END
}
-// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.gpio_pin, nitems(TasmotaGlobal.gpio_pin), sizeof(TasmotaGlobal.gpio_pin[0]));
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: TasmotaGlobal.gpio_pin %*_V"), nitems(TasmotaGlobal.gpio_pin), (uint8_t*)TasmotaGlobal.gpio_pin);
if (ResetReasonPowerOn()) {
TasmotaGlobal.power_on_delay = Settings->param[P_POWER_ON_DELAY2]; // SetOption47 - Delay switching relays to reduce power surge at power on
From 6f00b455e70d036ef8ca23a9f87ecae9805a2306 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 09:57:00 +0100
Subject: [PATCH 162/319] Add serial receive poll during sleep
Add serial receive poll during sleep for tuya and serial bridge
---
tasmota/include/tasmota.h | 2 +-
tasmota/tasmota.ino | 22 +++++++------------
tasmota/tasmota_support/settings.ino | 6 ++---
tasmota/tasmota_support/support_tasmota.ino | 19 +++++++++++-----
.../xdrv_01_9_webserver.ino | 21 ++++++------------
.../xdrv_08_serial_bridge.ino | 1 +
.../tasmota_xdrv_driver/xdrv_16_tuyamcu.ino | 1 +
.../xdrv_87_esp32_sonoff_tm1621.ino | 3 +--
8 files changed, 34 insertions(+), 41 deletions(-)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index 99a5f780c..faf2143ae 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -378,7 +378,7 @@ enum LightTypes { LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT
LT_NU8, LT_SERIAL1, LT_SERIAL2, LT_RGB, LT_RGBW, LT_RGBWC, LT_NU14, LT_NU15 }; // Do not insert new fields
enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_I2C_INIT, FUNC_MODULE_INIT, FUNC_PRE_INIT, FUNC_INIT,
- FUNC_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND,
+ FUNC_LOOP, FUNC_SLEEP_LOOP, FUNC_EVERY_50_MSECOND, FUNC_EVERY_100_MSECOND, FUNC_EVERY_200_MSECOND, FUNC_EVERY_250_MSECOND, FUNC_EVERY_SECOND,
FUNC_SAVE_SETTINGS, FUNC_SAVE_AT_MIDNIGHT, FUNC_SAVE_BEFORE_RESTART,
FUNC_AFTER_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_SENSOR, FUNC_WEB_COL_SENSOR, FUNC_COMMAND, FUNC_COMMAND_SENSOR, FUNC_COMMAND_DRIVER,
FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA,
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 702b06253..126a10c51 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -619,8 +619,7 @@ void setup(void) {
}
#endif // USE_BERRY
- XdrvCall(FUNC_PRE_INIT);
- XsnsCall(FUNC_PRE_INIT);
+ XdrvXsnsCall(FUNC_PRE_INIT);
TasmotaGlobal.init_state = INIT_GPIOS;
@@ -638,8 +637,7 @@ void setup(void) {
ArduinoOTAInit();
#endif // USE_ARDUINO_OTA
- XdrvCall(FUNC_INIT);
- XsnsCall(FUNC_INIT);
+ XdrvXsnsCall(FUNC_INIT);
#ifdef USE_SCRIPT
if (bitRead(Settings->rule_enabled, 0)) Run_Scripter(">BS",3,0);
#endif
@@ -684,6 +682,7 @@ void SleepDelay(uint32_t mseconds) {
if (!TasmotaGlobal.backlog_nodelay && mseconds) {
uint32_t wait = millis() + mseconds;
while (!TimeReached(wait) && !Serial.available() && !TasmotaGlobal.skip_sleep) { // We need to service serial buffer ASAP as otherwise we get uart buffer overrun
+ XdrvCall(FUNC_SLEEP_LOOP);
delay(1);
}
} else {
@@ -692,8 +691,7 @@ void SleepDelay(uint32_t mseconds) {
}
void Scheduler(void) {
- XdrvCall(FUNC_LOOP);
- XsnsCall(FUNC_LOOP);
+ XdrvXsnsCall(FUNC_LOOP);
// check LEAmDNS.h
// MDNS.update() needs to be called in main loop
@@ -721,32 +719,28 @@ void Scheduler(void) {
#ifdef ROTARY_V1
RotaryHandler();
#endif // ROTARY_V1
- XdrvCall(FUNC_EVERY_50_MSECOND);
- XsnsCall(FUNC_EVERY_50_MSECOND);
+ XdrvXsnsCall(FUNC_EVERY_50_MSECOND);
}
static uint32_t state_100msecond = 0; // State 100msecond timer
if (TimeReached(state_100msecond)) {
SetNextTimeInterval(state_100msecond, 100);
Every100mSeconds();
- XdrvCall(FUNC_EVERY_100_MSECOND);
- XsnsCall(FUNC_EVERY_100_MSECOND);
+ XdrvXsnsCall(FUNC_EVERY_100_MSECOND);
}
static uint32_t state_250msecond = 0; // State 250msecond timer
if (TimeReached(state_250msecond)) {
SetNextTimeInterval(state_250msecond, 250);
Every250mSeconds();
- XdrvCall(FUNC_EVERY_250_MSECOND);
- XsnsCall(FUNC_EVERY_250_MSECOND);
+ XdrvXsnsCall(FUNC_EVERY_250_MSECOND);
}
static uint32_t state_second = 0; // State second timer
if (TimeReached(state_second)) {
SetNextTimeInterval(state_second, 1000);
PerformEverySecond();
- XdrvCall(FUNC_EVERY_SECOND);
- XsnsCall(FUNC_EVERY_SECOND);
+ XdrvXsnsCall(FUNC_EVERY_SECOND);
}
if (!TasmotaGlobal.serial_local) { SerialInput(); }
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index c31a603bf..9eeb09103 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -367,8 +367,7 @@ void SettingsSaveAll(void) {
} else {
Settings->power = 0;
}
- XsnsCall(FUNC_SAVE_BEFORE_RESTART);
- XdrvCall(FUNC_SAVE_BEFORE_RESTART);
+ XsnsXdrvCall(FUNC_SAVE_BEFORE_RESTART);
SettingsSave(0);
}
@@ -603,8 +602,7 @@ void SettingsSave(uint8_t rotate) {
* stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1)
*/
#ifndef FIRMWARE_MINIMAL
- XsnsCall(FUNC_SAVE_SETTINGS);
- XdrvCall(FUNC_SAVE_SETTINGS);
+ XsnsXdrvCall(FUNC_SAVE_SETTINGS);
UpdateBackwardCompatibility();
if ((GetSettingsCrc32() != settings_crc32) || rotate) {
if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade)
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index dbe7ceb5f..7f8008965 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -221,6 +221,16 @@ void ZeroCrossInit(uint32_t offset) {
/********************************************************************************************/
+void XdrvXsnsCall(uint32_t function) {
+ XdrvCall(function);
+ XsnsCall(function);
+}
+
+void XsnsXdrvCall(uint32_t function) {
+ XsnsCall(function);
+ XdrvCall(function);
+}
+
void SetLatchingRelay(power_t lpower, uint32_t state) {
// TasmotaGlobal.power xx00 - toggle REL1 (Off) and REL3 (Off) - device 1 Off, device 2 Off
// TasmotaGlobal.power xx01 - toggle REL2 (On) and REL3 (Off) - device 1 On, device 2 Off
@@ -276,8 +286,7 @@ void SetDevicePower(power_t rpower, uint32_t source) {
}
XdrvMailbox.index = rpower;
- XdrvCall(FUNC_SET_POWER); // Signal power state
- XsnsCall(FUNC_SET_POWER); // Signal power state
+ XdrvXsnsCall(FUNC_SET_POWER); // Signal power state
XdrvMailbox.index = rpower;
XdrvMailbox.payload = source;
@@ -889,8 +898,7 @@ void GetSensorValues(void) {
char *start = ResponseData();
int data_start = ResponseLength();
- XsnsCall(FUNC_JSON_APPEND);
- XdrvCall(FUNC_JSON_APPEND);
+ XsnsXdrvCall(FUNC_JSON_APPEND);
if (data_start == ResponseLength()) { return; }
@@ -1137,8 +1145,7 @@ void PerformEverySecond(void)
MqttPublishTeleState();
MqttPublishTeleperiodSensor();
- XsnsCall(FUNC_AFTER_TELEPERIOD);
- XdrvCall(FUNC_AFTER_TELEPERIOD);
+ XsnsXdrvCall(FUNC_AFTER_TELEPERIOD);
} else {
// Global values (Temperature, Humidity and Pressure) update every 10 seconds
if (!(TasmotaGlobal.tele_period % 10)) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
index 1b454348f..32e53c92a 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
@@ -597,8 +597,7 @@ void StartWebserver(int type, IPAddress ipweb)
// Webserver->on(F("/u2"), HTTP_POST, HandleUploadDone, HandleUploadLoop); // this call requires 2 functions so we keep a direct call
Webserver->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop); // this call requires 2 functions so we keep a direct call
#ifndef FIRMWARE_MINIMAL
- XdrvCall(FUNC_WEB_ADD_HANDLER);
- XsnsCall(FUNC_WEB_ADD_HANDLER);
+ XdrvXsnsCall(FUNC_WEB_ADD_HANDLER);
#endif // Not FIRMWARE_MINIMAL
if (!Web.initial_config) {
@@ -1085,8 +1084,7 @@ uint32_t WebUseManagementSubmenu(void) {
if (!management_count) {
XdrvMailbox.index = 1;
- XdrvCall(FUNC_WEB_ADD_CONSOLE_BUTTON);
- XsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON);
+ XdrvXsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON);
XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON);
management_count = XdrvMailbox.index;
}
@@ -1288,8 +1286,7 @@ void HandleRoot(void)
}
#ifndef FIRMWARE_MINIMAL
- XdrvCall(FUNC_WEB_ADD_MAIN_BUTTON);
- XsnsCall(FUNC_WEB_ADD_MAIN_BUTTON);
+ XdrvXsnsCall(FUNC_WEB_ADD_MAIN_BUTTON);
#endif // Not FIRMWARE_MINIMAL
if (HTTP_ADMIN == Web.state) {
@@ -1442,8 +1439,7 @@ bool HandleRootStatusRefresh(void)
}
#endif // USE_ZIGBEE
- XsnsCall(FUNC_WEB_GET_ARG);
- XdrvCall(FUNC_WEB_GET_ARG);
+ XsnsXdrvCall(FUNC_WEB_GET_ARG);
#ifdef USE_WEB_SSE
WSContentBegin(200, CT_STREAM);
@@ -1455,8 +1451,7 @@ bool HandleRootStatusRefresh(void)
if (Settings->web_time_end) {
WSContentSend_P(PSTR("{s}" D_TIMER_TIME "{m}%s{e}"), GetDateAndTime(DT_LOCAL).substring(Settings->web_time_start, Settings->web_time_end).c_str());
}
- XsnsCall(FUNC_WEB_SENSOR);
- XdrvCall(FUNC_WEB_SENSOR);
+ XsnsXdrvCall(FUNC_WEB_SENSOR);
WSContentSend_P(PSTR(""));
@@ -1522,8 +1517,7 @@ void HandleConfiguration(void)
WSContentButton(BUTTON_MODULE);
WSContentButton(BUTTON_WIFI);
- XdrvCall(FUNC_WEB_ADD_BUTTON);
- XsnsCall(FUNC_WEB_ADD_BUTTON);
+ XdrvXsnsCall(FUNC_WEB_ADD_BUTTON);
WSContentButton(BUTTON_LOGGING);
WSContentButton(BUTTON_OTHER);
@@ -3106,8 +3100,7 @@ void HandleManagement(void)
WSContentButton(BUTTON_CONSOLE);
XdrvMailbox.index = 0;
- XdrvCall(FUNC_WEB_ADD_CONSOLE_BUTTON);
- XsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON);
+ XdrvXsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON);
WSContentSend_P(PSTR("")); // 5px padding
XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON);
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index 8b5617b47..3dd8ee554 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -293,6 +293,7 @@ bool Xdrv08(uint8_t function) {
else if (serial_bridge_buffer) {
switch (function) {
case FUNC_LOOP:
+ case FUNC_SLEEP_LOOP:
SerialBridgeInput();
break;
case FUNC_COMMAND:
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
index 102f4374c..5743facb4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
@@ -1566,6 +1566,7 @@ bool Xdrv16(uint8_t function) {
else if (Tuya.active) {
switch (function) {
case FUNC_LOOP:
+ case FUNC_SLEEP_LOOP:
if (TuyaSerial) { TuyaSerialInput(); }
break;
case FUNC_PRE_INIT:
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino
index b0e9fe188..8c31aa1a5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino
@@ -334,8 +334,7 @@ void TM1621Init(void) {
uint32_t TM1621GetSensors(bool refresh) {
if (refresh) {
ResponseClear();
- XsnsCall(FUNC_JSON_APPEND);
- XdrvCall(FUNC_JSON_APPEND);
+ XsnsXdrvCall(FUNC_JSON_APPEND);
ResponseJsonStart(); // Overwrite first comma
ResponseJsonEnd(); // Append }
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("TM1: Sensors %s"), ResponseData());
From c1ea8953cb3f496a5dbf20033a665ad3ad26f136 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 10:44:56 +0100
Subject: [PATCH 163/319] Refactor uint8_t to uint32_t
---
.../xdrv_01_9_webserver.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 4 +-
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_05_irremote.ino | 2 +-
.../xdrv_05_irremote_full.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_06_snfbridge.ino | 5 +-
.../tasmota_xdrv_driver/xdrv_07_domoticz.ino | 2 +-
.../xdrv_08_serial_bridge.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_09_timers.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_10_scripter.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 2 +-
.../{xdrv_99_debug.ino => xdrv_127_debug.ino} | 27 +++++++++--
.../tasmota_xdrv_driver/xdrv_12_discovery.ino | 2 +-
.../xdrv_12_home_assistant.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_13_display.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_14_mp3.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_15_pca9685.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_16_tuyamcu.ino | 4 +-
.../tasmota_xdrv_driver/xdrv_17_rcswitch.ino | 2 +-
.../xdrv_18_armtronix_dimmers.ino | 2 +-
.../xdrv_19_ps16dz_dimmer.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino | 2 +-
.../xdrv_21_wemo_multi.ino | 2 +-
.../xdrv_22_sonoff_ifan.ino | 2 +-
.../xdrv_23_zigbee_A_impl.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_24_buzzer.ino | 2 +-
.../xdrv_25_A4988_Stepper.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_26_ariluxrf.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_27_shutter.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_28_pcf8574.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_29_deepsleep.ino | 2 +-
.../xdrv_30_exs_dimmer.ino | 2 +-
.../xdrv_31_tasmota_client.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_32_hotplug.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_33_nrf24l01.ino | 2 +-
.../xdrv_34_wemos_motor_v1.ino | 2 +-
.../xdrv_35_pwm_dimmer.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_36_keeloq.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino | 2 +-
.../xdrv_39_thermostat.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_40_telegram.ino | 2 +-
.../xdrv_41_tcp_bridge.ino | 2 +-
.../xdrv_42_0_i2s_audio.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_43_mlx90640.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_44_miel_hvac.ino | 2 +-
.../xdrv_45_shelly_dimmer.ino | 4 +-
.../tasmota_xdrv_driver/xdrv_46_ccloader.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_47_ftc532.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_48_timeprop.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_49_pid.ino | 2 +-
.../xdrv_50_filesystem.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_51_bs814a2.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_52_9_berry.ino | 2 +-
.../xdrv_53_projector_ctrl.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino | 2 +-
tasmota/tasmota_xdrv_driver/xdrv_55_touch.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_56_rtc_chips.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino | 2 +-
.../xdrv_58_range_extender.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_59_influxdb.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_60_shift595.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_61_ds3502.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_62_improv.ino | 2 +-
.../xdrv_63_modbus_bridge.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_79_esp32_ble.ino | 2 +-
.../xdrv_81_esp32_webcam.ino | 2 +-
.../xdrv_82_esp32_ethernet.ino | 2 +-
.../xdrv_83_esp32_watch.ino | 2 +-
.../xdrv_85_esp32_ble_eq3_trv.ino | 2 +-
.../xdrv_86_esp32_sonoff_spm.ino | 2 +-
.../xdrv_87_esp32_sonoff_tm1621.ino | 2 +-
.../xdrv_88_esp32_shelly_pro.ino | 2 +-
.../xdrv_89_esp32_dali.ino | 2 +-
.../xdrv_90_dingtian_relay.ino | 2 +-
.../xdrv_98_file_settings_demo.ino | 2 +-
tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino | 2 +-
.../tasmota_xdsp_display/xdsp_02_ssd1306.ino | 3 +-
.../tasmota_xdsp_display/xdsp_03_matrix.ino | 2 +-
.../tasmota_xdsp_display/xdsp_04_ili9341.ino | 2 +-
.../xdsp_05_epaper_29.ino | 2 +-
.../xdsp_06_epaper_42.ino | 2 +-
.../tasmota_xdsp_display/xdsp_07_sh1106.ino | 2 +-
.../tasmota_xdsp_display/xdsp_09_SSD1351.ino | 2 +-
.../tasmota_xdsp_display/xdsp_10_RA8876.ino | 2 +-
.../tasmota_xdsp_display/xdsp_11_sevenseg.ino | 2 +-
.../tasmota_xdsp_display/xdsp_12_ST7789.ino | 2 +-
.../tasmota_xdsp_display/xdsp_14_SSD1331.ino | 2 +-
.../tasmota_xdsp_display/xdsp_15_tm1637.ino | 2 +-
.../xdsp_16_esp32_epaper_47.ino | 2 +-
.../xdsp_17_universal.ino | 2 +-
.../xdsp_18_berry_display.ino | 2 +-
.../xdsp_19_max7219_matrix.ino | 2 +-
tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino | 2 +-
tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino | 2 +-
.../tasmota_xlgt_light/xlgt_03_sm16716.ino | 2 +-
tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino | 6 +--
.../tasmota_xlgt_light/xlgt_05_sonoff_l1.ino | 2 +-
.../xlgt_06_electriq_moodl.ino | 2 +-
.../tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino | 2 +-
.../tasmota_xlgt_light/xlgt_08_bp5758d.ino | 2 +-
tasmota/tasmota_xlgt_light/xlgt_09_sm2335.ino | 2 +-
.../tasmota_xlgt_light/xlgt_10_bp1658cj.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_01_hlw8012.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_02_cse7766.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_03_pzem004t.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_04_mcp39f501.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_05_pzem_ac.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_06_pzem_dc.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_07_ade7953.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_08_sdm120.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_09_dds2382.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_10_sdm630.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_11_ddsu666.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_12_solaxX1.ino | 2 +-
.../xnrg_13_fif_le01mr.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_14_bl09xx.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_15_teleinfo.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_16_iem3000.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_17_ornowe517.ino | 2 +-
tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_19_cse7761.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_21_sdm230.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_22_bl6523.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_23_ade7880.ino | 2 +-
.../tasmota_xnrg_energy/xnrg_29_modbus.ino | 2 +-
tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino | 2 +-
.../tasmota_xsns_sensor/xsns_01_counter.ino | 2 +-
.../tasmota_xsns_sensor/xsns_02_analog.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_04_snfsc.ino | 2 +-
.../tasmota_xsns_sensor/xsns_05_ds18x20.ino | 2 +-
.../xsns_05_esp32_ds18x20.ino | 2 +-
.../tasmota_xsns_sensor/xsns_06_dht_v5.ino | 2 +-
.../tasmota_xsns_sensor/xsns_06_dht_v6.ino | 2 +-
.../tasmota_xsns_sensor/xsns_06_esp32_dht.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_08_htu21.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino | 2 +-
.../tasmota_xsns_sensor/xsns_100_ina3221.ino | 2 +-
.../tasmota_xsns_sensor/xsns_10_bh1750.ino | 2 +-
.../tasmota_xsns_sensor/xsns_11_veml6070.ino | 2 +-
.../xsns_127_esp32_sensors.ino | 2 +-
.../tasmota_xsns_sensor/xsns_12_ads1115.ino | 2 +-
.../tasmota_xsns_sensor/xsns_13_ina219.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_15_mhz19.ino | 2 +-
.../tasmota_xsns_sensor/xsns_16_tsl2561.ino | 2 +-
.../tasmota_xsns_sensor/xsns_17_senseair.ino | 2 +-
.../tasmota_xsns_sensor/xsns_18_pms5003.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_19_mgs.ino | 2 +-
.../tasmota_xsns_sensor/xsns_20_novasds.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino | 2 +-
.../tasmota_xsns_sensor/xsns_24_si1145.ino | 2 +-
.../tasmota_xsns_sensor/xsns_26_lm75ad.ino | 2 +-
.../tasmota_xsns_sensor/xsns_27_apds9960.ino | 2 +-
.../tasmota_xsns_sensor/xsns_28_tm1638.ino | 2 +-
.../tasmota_xsns_sensor/xsns_29_mcp230xx.ino | 2 +-
.../tasmota_xsns_sensor/xsns_30_mpr121.ino | 4 +-
.../tasmota_xsns_sensor/xsns_31_ccs811.ino | 2 +-
.../tasmota_xsns_sensor/xsns_31_ccs811_v2.ino | 2 +-
.../tasmota_xsns_sensor/xsns_32_mpu6050.ino | 2 +-
.../tasmota_xsns_sensor/xsns_33_qmc5883l.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_34_hx711.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_35_tx20.ino | 2 +-
.../tasmota_xsns_sensor/xsns_36_mgc3130.ino | 2 +-
.../tasmota_xsns_sensor/xsns_37_rfsensor.ino | 2 +-
.../tasmota_xsns_sensor/xsns_38_az7798.ino | 2 +-
.../tasmota_xsns_sensor/xsns_39_max31855.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino | 2 +-
.../tasmota_xsns_sensor/xsns_41_max44009.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_43_hre.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_44_sps30.ino | 2 +-
.../tasmota_xsns_sensor/xsns_45_vl53l0x.ino | 2 +-
.../tasmota_xsns_sensor/xsns_46_MLX90614.ino | 2 +-
.../tasmota_xsns_sensor/xsns_47_max31865.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_48_chirp.ino | 2 +-
.../tasmota_xsns_sensor/xsns_50_paj7620.ino | 2 +-
.../tasmota_xsns_sensor/xsns_51_rdm6300.ino | 2 +-
.../xsns_52_esp32_ibeacon_ble.ino | 2 +-
.../tasmota_xsns_sensor/xsns_52_ibeacon.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_53_sml.ino | 2 +-
.../tasmota_xsns_sensor/xsns_54_ina226.ino | 2 +-
.../xsns_55_hih_series.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino | 2 +-
.../tasmota_xsns_sensor/xsns_57_tsl2591.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_58_dht12.ino | 2 +-
.../tasmota_xsns_sensor/xsns_59_ds1624.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_60_GPS.ino | 2 +-
.../tasmota_xsns_sensor/xsns_61_MI_NRF24.ino | 2 +-
.../tasmota_xsns_sensor/xsns_62_MI_HM10.ino | 2 +-
.../tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 2 +-
.../xsns_62_esp32_mi_ble.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino | 2 +-
.../tasmota_xsns_sensor/xsns_65_hdc1080.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino | 2 +-
.../tasmota_xsns_sensor/xsns_67_as3935.ino | 2 +-
.../tasmota_xsns_sensor/xsns_68_windmeter.ino | 2 +-
.../tasmota_xsns_sensor/xsns_69_opentherm.ino | 2 +-
.../tasmota_xsns_sensor/xsns_70_veml6075.ino | 2 +-
.../tasmota_xsns_sensor/xsns_71_veml7700.ino | 2 +-
.../tasmota_xsns_sensor/xsns_72_mcp9808.ino | 2 +-
.../tasmota_xsns_sensor/xsns_73_hp303b.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_74_lmt01.ino | 2 +-
.../xsns_75_prometheus.ino | 8 ++--
tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino | 2 +-
.../tasmota_xsns_sensor/xsns_77_vl53l1x.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_78_xezo.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_79_as608.ino | 2 +-
.../tasmota_xsns_sensor/xsns_80_mfrc522.ino | 2 +-
.../xsns_81_seesaw_soil.ino | 2 +-
.../tasmota_xsns_sensor/xsns_82_wiegand.ino | 2 +-
.../tasmota_xsns_sensor/xsns_83_neopool.ino | 2 +-
.../tasmota_xsns_sensor/xsns_84_tof10120.ino | 2 +-
.../tasmota_xsns_sensor/xsns_85_mpu6886.ino | 2 +-
.../xsns_86_tfminiplus.ino | 2 +-
.../xsns_87_can_sniffer.ino | 2 +-
.../tasmota_xsns_sensor/xsns_87_mcp2515.ino | 2 +-
.../tasmota_xsns_sensor/xsns_88_am2320.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_89_t67xx.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_90_hrg15.ino | 2 +-
.../xsns_91_vindriktning.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino | 2 +-
.../tasmota_xsns_sensor/xsns_93_hm330x.ino | 2 +-
.../tasmota_xsns_sensor/xsns_94_hdc2010.ino | 2 +-
.../tasmota_xsns_sensor/xsns_95_cm110x.ino | 2 +-
.../xsns_96_flowratemeter.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_97_hyt.ino | 2 +-
tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino | 2 +-
.../tasmota_xsns_sensor/xsns_99_luxv30b.ino | 6 +--
.../tasmota_xx2c_global/xdrv_interface.ino | 46 +++++++++----------
.../tasmota_xx2c_global/xdsp_interface.ino | 16 +++----
.../tasmota_xx2c_global/xlgt_interface.ino | 7 ++-
.../tasmota_xx2c_global/xnrg_interface.ino | 7 ++-
.../tasmota_xx2c_global/xsns_interface.ino | 28 +++++------
.../tasmota_xx2c_global/xx2c_interface.ino | 6 +--
241 files changed, 321 insertions(+), 310 deletions(-)
rename tasmota/tasmota_xdrv_driver/{xdrv_99_debug.ino => xdrv_127_debug.ino} (98%)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
index 32e53c92a..83692a06c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
@@ -3689,7 +3689,7 @@ void CmndCors(void)
* Interface
\*********************************************************************************************/
-bool Xdrv01(uint8_t function)
+bool Xdrv01(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
index a4b8b08e2..678d148f1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino
@@ -2003,7 +2003,7 @@ void MqttSaveSettings(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv02(uint8_t function)
+bool Xdrv02(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index cef329705..9807fd5f4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -1384,7 +1384,7 @@ void EnergyShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xdrv03(uint8_t function)
+bool Xdrv03(uint32_t function)
{
bool result = false;
@@ -1420,7 +1420,7 @@ bool Xdrv03(uint8_t function)
return result;
}
-bool Xsns03(uint8_t function)
+bool Xsns03(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index 538da6b09..a3d00b3f7 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -3395,7 +3395,7 @@ void CmndUndocA(void)
* Interface
\*********************************************************************************************/
-bool Xdrv04(uint8_t function)
+bool Xdrv04(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_05_irremote.ino b/tasmota/tasmota_xdrv_driver/xdrv_05_irremote.ino
index ba403f72f..0996484b5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_05_irremote.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_05_irremote.ino
@@ -416,7 +416,7 @@ void IrRemoteCmndResponse(uint32_t error)
* Interface
\*********************************************************************************************/
-bool Xdrv05(uint8_t function)
+bool Xdrv05(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_05_irremote_full.ino b/tasmota/tasmota_xdrv_driver/xdrv_05_irremote_full.ino
index a74270de2..4ffb34a2c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_05_irremote_full.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_05_irremote_full.ino
@@ -852,7 +852,7 @@ void IrInit(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv05(uint8_t function)
+bool Xdrv05(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
index c3aa42bd8..a928d8140 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
@@ -128,6 +128,9 @@ uint8_t rf_erase_flash(void) {
}
err = c2_device_erase();
if (err != C2_SUCCESS) {
+
+// AddLog(LOG_LEVEL_DEBUG, PSTR("RFB: Device erase error %d"), err);
+
if (i < 3) {
c2_reset(); // Reset RF chip and try again
} else {
@@ -535,7 +538,7 @@ void SonoffBridgeWebGetArg(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv06(uint8_t function)
+bool Xdrv06(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_07_domoticz.ino b/tasmota/tasmota_xdrv_driver/xdrv_07_domoticz.ino
index 7687ac644..6fa70cfc4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_07_domoticz.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_07_domoticz.ino
@@ -641,7 +641,7 @@ void DomoticzSaveSettings(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv07(uint8_t function) {
+bool Xdrv07(uint32_t function) {
bool result = false;
if (Settings->flag.mqtt_enabled) { // SetOption3 - Enable MQTT
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index 3dd8ee554..bcc34a4a8 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -284,7 +284,7 @@ void CmndSSerialConfig(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv08(uint8_t function) {
+bool Xdrv08(uint32_t function) {
bool result = false;
if (FUNC_PRE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino b/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
index 8c1fd530e..8575cf685 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_09_timers.ino
@@ -946,7 +946,7 @@ void TimerSaveSettings(void)
* Interface
\*********************************************************************************************/
-bool Xdrv09(uint8_t function)
+bool Xdrv09(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
index 49342df27..6f9003d70 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino
@@ -2441,7 +2441,7 @@ float map_double(float x, float in_min, float in_max, float out_min, float out_m
* Interface
\*********************************************************************************************/
-bool Xdrv10(uint8_t function)
+bool Xdrv10(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
index 66d699bab..6ffbe65fb 100755
--- a/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_10_scripter.ino
@@ -11116,7 +11116,7 @@ void script_add_subpage(uint8_t num) {
-bool Xdrv10(uint8_t function)
+bool Xdrv10(uint32_t function)
{
bool result = false;
glob_script_mem.event_handeled = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
index 33ba550b1..b8573cb3f 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
@@ -1298,7 +1298,7 @@ void CmndKnxCb(void)
* Interface
\*********************************************************************************************/
-bool Xdrv11(uint8_t function)
+bool Xdrv11(uint32_t function)
{
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_99_debug.ino b/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino
similarity index 98%
rename from tasmota/tasmota_xdrv_driver/xdrv_99_debug.ino
rename to tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino
index 61896a610..fe6caaf91 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_99_debug.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino
@@ -1,5 +1,5 @@
/*
- xdrv_99_debug.ino - debug support for Tasmota
+ xdrv_127_debug.ino - debug support for Tasmota
Copyright (C) 2021 Theo Arends
@@ -32,7 +32,7 @@
* Needs file zzzz_debug.ino due to DEFINE processing
\*********************************************************************************************/
-#define XDRV_99 99
+#define XDRV_127 127
#ifndef CPU_LOAD_CHECK
#define CPU_LOAD_CHECK 1 // Seconds between each CPU_LOAD log
@@ -46,6 +46,7 @@
#define D_CMND_CFGDUMP "CfgDump"
#define D_CMND_CFGPEEK "CfgPeek"
#define D_CMND_CFGPOKE "CfgPoke"
+#define D_CMND_SHOWHEAP "ShowHeap"
#define D_CMND_CFGXOR "CfgXor"
#define D_CMND_CPUCHECK "CpuChk"
#define D_CMND_EXCEPTION "Exception"
@@ -62,6 +63,11 @@
const char kDebugCommands[] PROGMEM = "|" // No prefix
D_CMND_MEMDUMP "|" D_CMND_CFGDUMP "|" D_CMND_CFGPEEK "|" D_CMND_CFGPOKE "|"
+#ifdef ESP8266
+#ifdef UMM_INLINE_METRICS
+ D_CMND_SHOWHEAP "|"
+#endif
+#endif
#ifdef USE_WEBSERVER
D_CMND_CFGXOR "|"
#endif
@@ -77,6 +83,11 @@ const char kDebugCommands[] PROGMEM = "|" // No prefix
void (* const DebugCommand[])(void) PROGMEM = {
&CmndMemDump, &CmndCfgDump, &CmndCfgPeek, &CmndCfgPoke,
+#ifdef ESP8266
+#ifdef UMM_INLINE_METRICS
+ &CmndShowHeap,
+#endif
+#endif
#ifdef USE_WEBSERVER
&CmndCfgXor,
#endif
@@ -355,7 +366,6 @@ void DebugDump(uint32_t start, uint32_t size) {
}
}
-
void DebugCfgDump(char* parms)
{
uint32_t CFG_COLS = 16;
@@ -522,6 +532,15 @@ void CmndCfgPoke(void)
ResponseCmndDone();
}
+#ifdef ESP8266
+#ifdef UMM_INLINE_METRICS
+void CmndShowHeap(void) {
+ system_show_malloc();
+ ResponseCmndDone();
+}
+#endif
+#endif
+
#ifdef USE_WEBSERVER
void CmndCfgXor(void)
{
@@ -709,7 +728,7 @@ void CmndI2cClock(void)
* Interface
\*********************************************************************************************/
-bool Xdrv99(uint8_t function)
+bool Xdrv127(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_12_discovery.ino b/tasmota/tasmota_xdrv_driver/xdrv_12_discovery.ino
index 25632cd32..a7cbe6c6e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_12_discovery.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_12_discovery.ino
@@ -298,7 +298,7 @@ void CmndTasDiscover(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv12(uint8_t function) {
+bool Xdrv12(uint32_t function) {
bool result = false;
if (Settings->flag.mqtt_enabled) { // SetOption3 - Enable MQTT
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino b/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino
index e9e976acb..531d8463e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_12_home_assistant.ino
@@ -1271,7 +1271,7 @@ void HassLwtSubscribe(bool hasslwt)
* Interface
\*********************************************************************************************/
-bool Xdrv12(uint8_t function)
+bool Xdrv12(uint32_t function)
{
bool result = false;
bool hasslwt = HOME_ASSISTANT_LWT_SUBSCRIBE;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino
index 99033c4e1..f7cb20fc1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino
@@ -2787,7 +2787,7 @@ void AddValue(uint8_t num,float fval) {
* Interface
\*********************************************************************************************/
-bool Xdrv13(uint8_t function)
+bool Xdrv13(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_14_mp3.ino b/tasmota/tasmota_xdrv_driver/xdrv_14_mp3.ino
index 88eff7dec..625f0359c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_14_mp3.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_14_mp3.ino
@@ -395,7 +395,7 @@ if (PinUsed(GPIO_MP3_DFR562_BUSY)) // optional MP3 player busy pi
* Interface
\*********************************************************************************************/
-bool Xdrv14(uint8_t function)
+bool Xdrv14(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_15_pca9685.ino b/tasmota/tasmota_xdrv_driver/xdrv_15_pca9685.ino
index 9f6cee154..8f82432c2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_15_pca9685.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_15_pca9685.ino
@@ -207,7 +207,7 @@ void PCA9685_OutputTelemetry(bool telemetry)
}
}
-bool Xdrv15(uint8_t function)
+bool Xdrv15(uint32_t function)
{
if (!I2cEnabled(XI2C_01)) { return false; }
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
index 5743facb4..35ef17ccc 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
@@ -1535,7 +1535,7 @@ void TuyaAddButton(void) {
#ifdef USE_ENERGY_SENSOR
-bool Xnrg32(uint8_t function)
+bool Xnrg32(uint32_t function)
{
bool result = false;
@@ -1556,7 +1556,7 @@ bool Xnrg32(uint8_t function)
}
#endif // USE_ENERGY_SENSOR
-bool Xdrv16(uint8_t function) {
+bool Xdrv16(uint32_t function) {
bool result = false;
if (FUNC_MODULE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino b/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino
index acf033c85..68077778e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino
@@ -229,7 +229,7 @@ void CmndRfTimeOut(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv17(uint8_t function)
+bool Xdrv17(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_18_armtronix_dimmers.ino b/tasmota/tasmota_xdrv_driver/xdrv_18_armtronix_dimmers.ino
index 185cb98c0..674ee9b3c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_18_armtronix_dimmers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_18_armtronix_dimmers.ino
@@ -164,7 +164,7 @@ void ArmtronixSetWifiLed(void)
* Interface
\*********************************************************************************************/
-bool Xdrv18(uint8_t function)
+bool Xdrv18(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_19_ps16dz_dimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_19_ps16dz_dimmer.ino
index 9c2d0a23e..d23058b39 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_19_ps16dz_dimmer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_19_ps16dz_dimmer.ino
@@ -206,7 +206,7 @@ bool PS16DZModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xdrv19(uint8_t function)
+bool Xdrv19(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino b/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino
index 734b0c0dd..30db910b5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino
@@ -1149,7 +1149,7 @@ void HandleHueApi(String *path)
* Interface
\*********************************************************************************************/
-bool Xdrv20(uint8_t function)
+bool Xdrv20(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
index f0521aeea4..1bcd0b9ab 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
@@ -342,7 +342,7 @@ void HandleUpnpSetupWemo(void)
* Interface
\*********************************************************************************************/
-bool Xdrv21(uint8_t function)
+bool Xdrv21(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
index 145e3e8c5..bf242d0f4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
@@ -427,7 +427,7 @@ void WemoRespondToMSearch(int echo_type) {
* Interface
\*********************************************************************************************/
-bool Xdrv21(uint8_t function)
+bool Xdrv21(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino b/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino
index 992e0a31f..618cda1ab 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino
@@ -244,7 +244,7 @@ void SonoffIfanUpdate(void)
* Interface
\*********************************************************************************************/
-bool Xdrv22(uint8_t function)
+bool Xdrv22(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
index f3ab5af77..4f44a8115 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
@@ -2377,7 +2377,7 @@ void ZigbeeShowMap(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv23(uint8_t function) {
+bool Xdrv23(uint32_t function) {
if (TasmotaGlobal.gpio_optiona.enable_ccloader) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_24_buzzer.ino b/tasmota/tasmota_xdrv_driver/xdrv_24_buzzer.ino
index 3921589f3..81dcc1dc7 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_24_buzzer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_24_buzzer.ino
@@ -229,7 +229,7 @@ void CmndBuzzer(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv24(uint8_t function) {
+bool Xdrv24(uint32_t function) {
bool result = false;
if (Buzzer.active) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_25_A4988_Stepper.ino b/tasmota/tasmota_xdrv_driver/xdrv_25_A4988_Stepper.ino
index 50e9997b1..ca8a2a421 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_25_A4988_Stepper.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_25_A4988_Stepper.ino
@@ -119,7 +119,7 @@ void CmndSetRPM(void) {
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdrv25(uint8_t function)
+bool Xdrv25(uint32_t function)
{
bool result = false;
if (PinUsed(GPIO_A4988_DIR) && PinUsed(GPIO_A4988_STP)) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_26_ariluxrf.ino b/tasmota/tasmota_xdrv_driver/xdrv_26_ariluxrf.ino
index 50441c1c8..8cad4cf56 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_26_ariluxrf.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_26_ariluxrf.ino
@@ -170,7 +170,7 @@ void AriluxRfDisable(void)
* Interface
\*********************************************************************************************/
-bool Xdrv26(uint8_t function)
+bool Xdrv26(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino
index d92d82025..17b2215af 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_27_shutter.ino
@@ -1718,7 +1718,7 @@ void CmndShutterTiltIncDec(void)
* Interface
\*********************************************************************************************/
-bool Xdrv27(uint8_t function)
+bool Xdrv27(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino
index 7954acd62..25e0018fc 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino
@@ -308,7 +308,7 @@ void Pcf8574SaveSettings(void)
* Interface
\*********************************************************************************************/
-bool Xdrv28(uint8_t function)
+bool Xdrv28(uint32_t function)
{
if (!I2cEnabled(XI2C_02)) { return false; }
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
index 27377eeea..a607fa0e9 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
@@ -205,7 +205,7 @@ void CmndDeepsleepTime(void)
* Interface
\*********************************************************************************************/
-bool Xdrv29(uint8_t function)
+bool Xdrv29(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino
index 7b3f4bcd2..3dfdcda73 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino
@@ -585,7 +585,7 @@ void CmndExsState(void)
* Interface
*/
-bool Xdrv30(uint8_t function)
+bool Xdrv30(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
index d47f39b43..04ede81b3 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
@@ -531,7 +531,7 @@ void TasmotaClient_ProcessIn(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv31(uint8_t function) {
+bool Xdrv31(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_32_hotplug.ino b/tasmota/tasmota_xdrv_driver/xdrv_32_hotplug.ino
index 8a055911a..d5dba3b3c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_32_hotplug.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_32_hotplug.ino
@@ -80,7 +80,7 @@ void CmndHotPlugTime(void)
* Interface
\*********************************************************************************************/
-bool Xdrv32(uint8_t function)
+bool Xdrv32(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_33_nrf24l01.ino b/tasmota/tasmota_xdrv_driver/xdrv_33_nrf24l01.ino
index dfe690de2..83381d203 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_33_nrf24l01.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_33_nrf24l01.ino
@@ -80,7 +80,7 @@ void NRF24Detect(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv33(uint8_t function) {
+bool Xdrv33(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_34_wemos_motor_v1.ino b/tasmota/tasmota_xdrv_driver/xdrv_34_wemos_motor_v1.ino
index b38a863e1..4b25b714d 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_34_wemos_motor_v1.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_34_wemos_motor_v1.ino
@@ -268,7 +268,7 @@ void WMotorV2command(uint8_t *data, uint8_t len) // process V2 request
* Interface
\*********************************************************************************************/
-bool Xdrv34(uint8_t function)
+bool Xdrv34(uint32_t function)
{
if (!I2cEnabled(XI2C_44)) { return false; }
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_35_pwm_dimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_35_pwm_dimmer.ino
index 4a8587dc8..5ce566548 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_35_pwm_dimmer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_35_pwm_dimmer.ino
@@ -790,7 +790,7 @@ void CmndPWMDimmerPWMs(void)
* Interface
\*********************************************************************************************/
-bool Xdrv35(uint8_t function)
+bool Xdrv35(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_36_keeloq.ino b/tasmota/tasmota_xdrv_driver/xdrv_36_keeloq.ino
index 1ea0f3bfc..13b700920 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_36_keeloq.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_36_keeloq.ino
@@ -261,7 +261,7 @@ void KeeloqInit()
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdrv36(uint8_t function)
+bool Xdrv36(uint32_t function)
{
if (!PinUsed(GPIO_CC1101_GDO0) || !PinUsed(GPIO_CC1101_GDO2)) { return false; }
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino b/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino
index a153f3351..adc34e0bf 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino
@@ -173,7 +173,7 @@ bool SonoffD1ModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xdrv37(uint8_t function)
+bool Xdrv37(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino b/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino
index 4390bd1d9..acf6181e3 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino
@@ -365,7 +365,7 @@ void CmndPing(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv38(uint8_t function)
+bool Xdrv38(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino b/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino
index 4d341fd4d..ca1f39ec7 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino
@@ -2084,7 +2084,7 @@ void ThermostatShow(uint8_t ctr_output, bool json)
* Interface
\*********************************************************************************************/
-bool Xdrv39(uint8_t function)
+bool Xdrv39(uint32_t function)
{
bool result = false;
uint8_t ctr_output;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_40_telegram.ino b/tasmota/tasmota_xdrv_driver/xdrv_40_telegram.ino
index 56d0d882d..a511cdf2d 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_40_telegram.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_40_telegram.ino
@@ -476,7 +476,7 @@ void CmndTmSend(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv40(uint8_t function)
+bool Xdrv40(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino
index d0b3de1f9..b5c4a0789 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_41_tcp_bridge.ino
@@ -277,7 +277,7 @@ void CmndTCPConnect(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv41(uint8_t function)
+bool Xdrv41(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio.ino
index 26ad5412c..e6031ce31 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio.ino
@@ -679,7 +679,7 @@ void i2s_mp3_loop(void);
void i2s_mp3_init(void);
void MP3ShowStream(void);
-bool Xdrv42(uint8_t function) {
+bool Xdrv42(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_43_mlx90640.ino b/tasmota/tasmota_xdrv_driver/xdrv_43_mlx90640.ino
index 833340c90..d13dd4416 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_43_mlx90640.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_43_mlx90640.ino
@@ -591,7 +591,7 @@ void MLX90640Show(uint8_t json)
* Interface
\*********************************************************************************************/
-bool Xdrv43(uint8_t function)
+bool Xdrv43(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino
index e5f37fbc1..60ea83e5a 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_44_miel_hvac.ino
@@ -1285,7 +1285,7 @@ static void (*const miel_hvac_cmnds[])(void) PROGMEM = {
#endif
};
-bool Xdrv44(uint8_t function) {
+bool Xdrv44(uint32_t function) {
bool result = false;
struct miel_hvac_softc *sc = miel_hvac_sc;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino
index d1f317bfc..6476fa172 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino
@@ -831,7 +831,7 @@ void CmndShdWarmupTime(void)
\*********************************************************************************************/
#ifdef USE_ENERGY_SENSOR
-bool Xnrg31(uint8_t function) {
+bool Xnrg31(uint32_t function) {
bool result = false;
if (Shd.present) {
@@ -852,7 +852,7 @@ bool Xnrg31(uint8_t function) {
* Driver Interface
\*********************************************************************************************/
-bool Xdrv45(uint8_t function) {
+bool Xdrv45(uint32_t function) {
bool result = false;
if (FUNC_MODULE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino b/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
index e8986df36..ab37d271a 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
@@ -671,7 +671,7 @@ void CCLoadershow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xdrv46(uint8_t function) {
+bool Xdrv46(uint32_t function) {
if (!TasmotaGlobal.gpio_optiona.enable_ccloader) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_47_ftc532.ino b/tasmota/tasmota_xdrv_driver/xdrv_47_ftc532.ino
index 2e1e26ac7..220ab6078 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_47_ftc532.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_47_ftc532.ino
@@ -215,7 +215,7 @@ void ftc532_publish(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv47(uint8_t function) {
+bool Xdrv47(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino b/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino
index 934501079..ab11f6c52 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino
@@ -224,7 +224,7 @@ bool TimepropCommand()
#define XDRV_48 48
-bool Xdrv48(byte function) {
+bool Xdrv48(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_49_pid.ino b/tasmota/tasmota_xdrv_driver/xdrv_49_pid.ino
index 581016470..dcc226cd2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_49_pid.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_49_pid.ino
@@ -420,7 +420,7 @@ void PIDRun(void) {
#define XDRV_49 49
-bool Xdrv49(byte function) {
+bool Xdrv49(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino b/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino
index ab66a5bec..db60d2e74 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_50_filesystem.ino
@@ -1109,7 +1109,7 @@ void UfsEditorUpload(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv50(uint8_t function) {
+bool Xdrv50(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_51_bs814a2.ino b/tasmota/tasmota_xdrv_driver/xdrv_51_bs814a2.ino
index aa1abc4bb..5199b3919 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_51_bs814a2.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_51_bs814a2.ino
@@ -166,7 +166,7 @@ void bs814_publish(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv51(uint8_t function) {
+bool Xdrv51(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
index d28e0e41e..7bb20821c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
@@ -715,7 +715,7 @@ void HandleBerryConsole(void)
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdrv52(uint8_t function)
+bool Xdrv52(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_53_projector_ctrl.ino b/tasmota/tasmota_xdrv_driver/xdrv_53_projector_ctrl.ino
index be0af2e5a..dc31523df 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_53_projector_ctrl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_53_projector_ctrl.ino
@@ -439,7 +439,7 @@ projector_ctrl_set_power(struct projector_ctrl_softc_s *sc)
* Interface
\*********************************************************************************************/
-bool Xdrv53(uint8_t function) {
+bool Xdrv53(uint32_t function) {
bool result;
struct projector_ctrl_softc_s *sc;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino
index 3c6ad507a..26fa7bbcb 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino
@@ -433,7 +433,7 @@ void start_lvgl(const char * uconfig) {
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdrv54(uint8_t function)
+bool Xdrv54(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_55_touch.ino b/tasmota/tasmota_xdrv_driver/xdrv_55_touch.ino
index 7ce4b1fed..3a23b965e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_55_touch.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_55_touch.ino
@@ -459,7 +459,7 @@ void TS_RotConvert(int16_t *x, int16_t *y) {
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdrv55(uint8_t function) {
+bool Xdrv55(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino b/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino
index 0de267656..01de30b39 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino
@@ -432,7 +432,7 @@ void CmndRtcNtpServer(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv56(uint8_t function) {
+bool Xdrv56(uint32_t function) {
bool result = false;
#ifdef RTC_NTP_SERVER
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino b/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino
index d309b4d59..5395da2f7 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino
@@ -814,7 +814,7 @@ void CmndMeshInterval(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv57(uint8_t function) {
+bool Xdrv57(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 7fb999063..0b0e382ce 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -344,7 +344,7 @@ void rngxSetupNAPT(void)
* Interface
\*********************************************************************************************/
-bool Xdrv58(uint8_t function)
+bool Xdrv58(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino b/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino
index d98011399..ea95998ea 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_59_influxdb.ino
@@ -561,7 +561,7 @@ void CmndInfluxDbPeriod(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv59(uint8_t function) {
+bool Xdrv59(uint32_t function) {
bool result = false;
if (FUNC_PRE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino
index 4e816fc7e..d18410afb 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_60_shift595.ino
@@ -98,7 +98,7 @@ void CmndShift595Devices(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv60(uint8_t function) {
+bool Xdrv60(uint32_t function) {
bool result = false;
if (FUNC_PRE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_61_ds3502.ino b/tasmota/tasmota_xdrv_driver/xdrv_61_ds3502.ino
index a8d05f6b4..0b158bdef 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_61_ds3502.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_61_ds3502.ino
@@ -73,7 +73,7 @@ void CmndWiper(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv61(uint8_t function) {
+bool Xdrv61(uint32_t function) {
if (!I2cEnabled(XI2C_67)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_62_improv.ino b/tasmota/tasmota_xdrv_driver/xdrv_62_improv.ino
index 6dc0abb68..4b3a15154 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_62_improv.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_62_improv.ino
@@ -340,7 +340,7 @@ void ImprovInit(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv62(uint8_t function) {
+bool Xdrv62(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
index 31b1c7a19..7dfa2a116 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_63_modbus_bridge.ino
@@ -1119,7 +1119,7 @@ void CmndModbusTCPConnect(void)
* Interface
\*********************************************************************************************/
-bool Xdrv63(uint8_t function)
+bool Xdrv63(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino
index 196c53d27..7060671a6 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino
@@ -3583,7 +3583,7 @@ int ExtRestartBLEIfEnabled(){
return 0;
}
-bool Xdrv79(uint8_t function)
+bool Xdrv79(uint32_t function)
{
//if (!Settings->flag5.mi32_enable) { return false; } // SetOption115 - Enable ESP32 BLE BLE
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
index 11e57f2c4..c03031c56 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_81_esp32_webcam.ino
@@ -1422,7 +1422,7 @@ void WcStatsShow(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv81(uint8_t function) {
+bool Xdrv81(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
index 525e878cc..922d44abc 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino
@@ -297,7 +297,7 @@ void CmndEthSetIpConfig(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv82(uint8_t function) {
+bool Xdrv82(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_83_esp32_watch.ino b/tasmota/tasmota_xdrv_driver/xdrv_83_esp32_watch.ino
index 14ce4eb12..e318d2251 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_83_esp32_watch.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_83_esp32_watch.ino
@@ -434,7 +434,7 @@ bool TTGO_button(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv83(uint8_t function) {
+bool Xdrv83(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino b/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino
index 0af5add13..67103ce35 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_85_esp32_ble_eq3_trv.ino
@@ -1745,7 +1745,7 @@ void EQ3DiscoveryOneEQ3(){
* Interface
\*********************************************************************************************/
-bool Xdrv85(uint8_t function)
+bool Xdrv85(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino
index aa0d8ace2..058f83813 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_86_esp32_sonoff_spm.ino
@@ -2631,7 +2631,7 @@ void CmndSSPMPowerOnState(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv86(uint8_t function) {
+bool Xdrv86(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino
index 8c31aa1a5..70926f5ff 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_87_esp32_sonoff_tm1621.ino
@@ -566,7 +566,7 @@ void CmndDspSpeed(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv87(uint8_t function) {
+bool Xdrv87(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
index a822b04c9..9642163ce 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_88_esp32_shelly_pro.ino
@@ -147,7 +147,7 @@ void ShellyProLedLinkWifiOff(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv88(uint8_t function) {
+bool Xdrv88(uint32_t function) {
bool result = false;
if (FUNC_PRE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
index 0a247a2bd..d1fbeee5c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_89_esp32_dali.ino
@@ -556,7 +556,7 @@ bool DaliJsonParse()
* Interface
\*********************************************************************************************/
-bool Xdrv89(uint8_t function)
+bool Xdrv89(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
index 05a1fb1b3..16ae49dda 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino
@@ -179,7 +179,7 @@ void DingtianShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xdrv90(uint8_t function) {
+bool Xdrv90(uint32_t function) {
bool result = false;
if (FUNC_PRE_INIT == function) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino b/tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino
index e4459aeb7..f53fd65e0 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_98_file_settings_demo.ino
@@ -174,7 +174,7 @@ void DrvDemoSettingsSave(void) {
* Interface
\*********************************************************************************************/
-bool Xdrv98(uint8_t function) {
+bool Xdrv98(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino b/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino
index d7ec6ac2a..2dff946f2 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_01_lcd.ino
@@ -197,7 +197,7 @@ void LcdRefresh(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp01(uint8_t function)
+bool Xdsp01(uint32_t function)
{
if (!I2cEnabled(XI2C_03)) { return false; }
diff --git a/tasmota/tasmota_xdsp_display/xdsp_02_ssd1306.ino b/tasmota/tasmota_xdsp_display/xdsp_02_ssd1306.ino
index 0d1fc27e2..5f9657069 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_02_ssd1306.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_02_ssd1306.ino
@@ -167,8 +167,7 @@ void Ssd1306Refresh(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp02(byte function)
-{
+bool Xdsp02(uint32_t function) {
if (!I2cEnabled(XI2C_04)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino b/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino
index 09d8b8587..c314d4982 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_03_matrix.ino
@@ -333,7 +333,7 @@ void MatrixRefresh(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp03(uint8_t function)
+bool Xdsp03(uint32_t function)
{
if (!I2cEnabled(XI2C_05)) { return false; }
diff --git a/tasmota/tasmota_xdsp_display/xdsp_04_ili9341.ino b/tasmota/tasmota_xdsp_display/xdsp_04_ili9341.ino
index 3b6a8de9f..96dae6558 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_04_ili9341.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_04_ili9341.ino
@@ -366,7 +366,7 @@ void ILI9341_Refresh(void) { // Every second
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdsp04(uint8_t function)
+bool Xdsp04(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_05_epaper_29.ino b/tasmota/tasmota_xdsp_display/xdsp_05_epaper_29.ino
index 54a3eac8a..46f8dabe2 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_05_epaper_29.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_05_epaper_29.ino
@@ -178,7 +178,7 @@ void EpdRefresh29(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp05(uint8_t function)
+bool Xdsp05(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_06_epaper_42.ino b/tasmota/tasmota_xdsp_display/xdsp_06_epaper_42.ino
index d0baef8ab..f8f59bd7f 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_06_epaper_42.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_06_epaper_42.ino
@@ -118,7 +118,7 @@ void EpdRefresh42() // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp06(uint8_t function)
+bool Xdsp06(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_07_sh1106.ino b/tasmota/tasmota_xdsp_display/xdsp_07_sh1106.ino
index a8434f820..689e2273c 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_07_sh1106.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_07_sh1106.ino
@@ -165,7 +165,7 @@ void SH1106Refresh(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp07(uint8_t function)
+bool Xdsp07(uint32_t function)
{
if (!I2cEnabled(XI2C_06)) { return false; }
diff --git a/tasmota/tasmota_xdsp_display/xdsp_09_SSD1351.ino b/tasmota/tasmota_xdsp_display/xdsp_09_SSD1351.ino
index 8a30ad2c8..ffb47f425 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_09_SSD1351.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_09_SSD1351.ino
@@ -153,7 +153,7 @@ void SSD1351Refresh(void) { // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp09(uint8_t function) {
+bool Xdsp09(uint32_t function) {
bool result = false;
if (FUNC_DISPLAY_INIT_DRIVER == function) {
diff --git a/tasmota/tasmota_xdsp_display/xdsp_10_RA8876.ino b/tasmota/tasmota_xdsp_display/xdsp_10_RA8876.ino
index 80c5b4f0f..33b4fc438 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_10_RA8876.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_10_RA8876.ino
@@ -297,7 +297,7 @@ Serial.print("Text test took "); Serial.print(elapsedtime); Serial.println(" ms"
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdsp10(uint8_t function)
+bool Xdsp10(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino b/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino
index f2c48adb9..bb8792259 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_11_sevenseg.ino
@@ -422,7 +422,7 @@ void SevensegRefresh(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp11(uint8_t function)
+bool Xdsp11(uint32_t function)
{
if (!I2cEnabled(XI2C_47)) { return false; }
diff --git a/tasmota/tasmota_xdsp_display/xdsp_12_ST7789.ino b/tasmota/tasmota_xdsp_display/xdsp_12_ST7789.ino
index 6553fc6a1..2b3c818ae 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_12_ST7789.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_12_ST7789.ino
@@ -176,7 +176,7 @@ st7789_ctouch_counter++;
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xdsp12(uint8_t function)
+bool Xdsp12(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_14_SSD1331.ino b/tasmota/tasmota_xdsp_display/xdsp_14_SSD1331.ino
index 3d531d229..e455a66ce 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_14_SSD1331.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_14_SSD1331.ino
@@ -169,7 +169,7 @@ void SSD1331Refresh(void) { // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp14(uint8_t function) {
+bool Xdsp14(uint32_t function) {
bool result = false;
if (FUNC_DISPLAY_INIT_DRIVER == function) {
diff --git a/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino b/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino
index 144921527..0deb8d4a8 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_15_tm1637.ino
@@ -1284,7 +1284,7 @@ void TM1637Refresh(void)
* Interface
\*********************************************************************************************/
-bool Xdsp15(uint8_t function)
+bool Xdsp15(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_16_esp32_epaper_47.ino b/tasmota/tasmota_xdsp_display/xdsp_16_esp32_epaper_47.ino
index bc6473efe..15b79955c 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_16_esp32_epaper_47.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_16_esp32_epaper_47.ino
@@ -278,7 +278,7 @@ void EPD47_CheckTouch(void) {
* Interface
\*********************************************************************************************/
-bool Xdsp16(uint8_t function)
+bool Xdsp16(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino b/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino
index 6a1f970da..3a24870d4 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_17_universal.ino
@@ -481,7 +481,7 @@ void UDISP_Refresh(void) // Every second
* Interface
\*********************************************************************************************/
-bool Xdsp17(uint8_t function) {
+bool Xdsp17(uint32_t function) {
bool result = false;
if (FUNC_DISPLAY_INIT_DRIVER == function) {
diff --git a/tasmota/tasmota_xdsp_display/xdsp_18_berry_display.ino b/tasmota/tasmota_xdsp_display/xdsp_18_berry_display.ino
index 11875692e..98ace0f0c 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_18_berry_display.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_18_berry_display.ino
@@ -26,7 +26,7 @@
* Interface
\*********************************************************************************************/
-bool Xdsp18(uint8_t function) {
+bool Xdsp18(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xdsp_display/xdsp_19_max7219_matrix.ino b/tasmota/tasmota_xdsp_display/xdsp_19_max7219_matrix.ino
index 3e1a5c258..fca13278b 100644
--- a/tasmota/tasmota_xdsp_display/xdsp_19_max7219_matrix.ino
+++ b/tasmota/tasmota_xdsp_display/xdsp_19_max7219_matrix.ino
@@ -305,7 +305,7 @@ bool MAX7291Matrix_showTime()
#endif // USE_DISPLAY_MODES1TO5
-bool Xdsp19(uint8_t function)
+bool Xdsp19(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
index 715851e4c..e7a65a5ee 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
@@ -771,7 +771,7 @@ void CmndWidth(void)
* Interface
\*********************************************************************************************/
-bool Xlgt01(uint8_t function)
+bool Xlgt01(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino b/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino
index ef23c3c9c..ec72df8d8 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino
@@ -148,7 +148,7 @@ void My92x1ModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt02(uint8_t function)
+bool Xlgt02(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_03_sm16716.ino b/tasmota/tasmota_xlgt_light/xlgt_03_sm16716.ino
index b1d4207b8..407ed67b9 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_03_sm16716.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_03_sm16716.ino
@@ -170,7 +170,7 @@ void Sm16716ModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt03(uint8_t function)
+bool Xlgt03(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino b/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino
index a9f49c3d1..0c9b86ef0 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_04_sm2135.ino
@@ -70,7 +70,7 @@ enum Sm2135Color { SM2135_WCGRB, // 1 (4064) - Action LSC GRB (20mA) an
SM2135_WCBGR15W, // 6 (4069) - BGR (45mA) and CW (60mA)
SM2135_WCBRG_SETALL, // 7 (4070) - Fitop 10W RGBCCT BRG (15mA) and CW (40mA)
SM2135_RESERVED_8, // 8 (4071) - Reserved - currently fallsback to 2
- SM2135_WCGRB_ALL, // 9 (4072) - GRB (20mA) and CW (15mA) like 1 but reset either RGB or CW
+ SM2135_WCGRB_ALL, // 9 (4072) - Qualitel GRB (20mA) and CW (15mA) like 1 but reset either RGB or CW
SM2135_WCBGR_ALL // 10 (4073) - BGR (20mA) and CW (15mA) like 2 but reset either RGB or CW
};
@@ -227,7 +227,7 @@ void Sm2135ModuleSelected(void)
Sm2135.clk = Pin(GPIO_SM2135_CLK);
Sm2135.data = Pin(GPIO_SM2135_DAT, GPIO_ANY);
- // See #define MAX_SM2135_DAT 7 in tasmota_template.h
+ // See #define MAX_SM2135_DAT 10 in tasmota_template.h
Sm2135.model = GetPin(Sm2135.data) - AGPIO(GPIO_SM2135_DAT); // 0 .. 9
// Legacy support of model selection
@@ -271,7 +271,7 @@ void Sm2135ModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt04(uint8_t function)
+bool Xlgt04(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_05_sonoff_l1.ino b/tasmota/tasmota_xlgt_light/xlgt_05_sonoff_l1.ino
index 080bc9c7a..8e793761f 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_05_sonoff_l1.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_05_sonoff_l1.ino
@@ -399,7 +399,7 @@ void CmndMusicSync(void) {
* Interface
\*********************************************************************************************/
-bool Xlgt05(uint8_t function)
+bool Xlgt05(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_06_electriq_moodl.ino b/tasmota/tasmota_xlgt_light/xlgt_06_electriq_moodl.ino
index f6bef1ff5..da984ab05 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_06_electriq_moodl.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_06_electriq_moodl.ino
@@ -82,7 +82,7 @@ void ElectriqMoodLModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt06(uint8_t function)
+bool Xlgt06(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino b/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino
index d7c9bbfd2..75bbd7102 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_07_lsc_mcsl.ino
@@ -294,7 +294,7 @@ void LscMcWebGetArg(void) {
* Interface
\*********************************************************************************************/
-bool Xlgt07(uint8_t function)
+bool Xlgt07(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino b/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino
index a0499bac8..8bcee5894 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_08_bp5758d.ino
@@ -187,7 +187,7 @@ void Bp5758dModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt08(uint8_t function)
+bool Xlgt08(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_09_sm2335.ino b/tasmota/tasmota_xlgt_light/xlgt_09_sm2335.ino
index eb4c8f035..9d09f2068 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_09_sm2335.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_09_sm2335.ino
@@ -157,7 +157,7 @@ void SM2335ModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt09(uint8_t function)
+bool Xlgt09(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
index c241e796d..d9ec3e194 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_10_bp1658cj.ino
@@ -160,7 +160,7 @@ void BP1658CJModuleSelected(void)
* Interface
\*********************************************************************************************/
-bool Xlgt10(uint8_t function)
+bool Xlgt10(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
index d28347af5..cfbd76d94 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_01_hlw8012.ino
@@ -312,7 +312,7 @@ bool HlwCommand(void) {
* Interface
\*********************************************************************************************/
-bool Xnrg01(uint8_t function) {
+bool Xnrg01(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
index 6717304cf..fd2ccc11e 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_02_cse7766.ino
@@ -279,7 +279,7 @@ bool CseCommand(void) {
* Interface
\*********************************************************************************************/
-bool Xnrg02(uint8_t function) {
+bool Xnrg02(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_03_pzem004t.ino b/tasmota/tasmota_xnrg_energy/xnrg_03_pzem004t.ino
index a9df4cd0b..7e6dc699b 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_03_pzem004t.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_03_pzem004t.ino
@@ -279,7 +279,7 @@ bool PzemCommand(void)
* Interface
\*********************************************************************************************/
-bool Xnrg03(uint8_t function)
+bool Xnrg03(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
index 807176c64..631fe9919 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_04_mcp39f501.ino
@@ -647,7 +647,7 @@ bool McpCommand(void)
* Interface
\*********************************************************************************************/
-bool Xnrg04(uint8_t function)
+bool Xnrg04(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino b/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino
index 21c50a4ff..0648525c9 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_05_pzem_ac.ino
@@ -149,7 +149,7 @@ bool PzemAcCommand(void)
* Interface
\*********************************************************************************************/
-bool Xnrg05(uint8_t function)
+bool Xnrg05(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino b/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino
index 1c6841154..d1336ca08 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_06_pzem_dc.ino
@@ -147,7 +147,7 @@ bool PzemDcCommand(void)
* Interface
\*********************************************************************************************/
-bool Xnrg06(uint8_t function)
+bool Xnrg06(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
index 0cef9b6ab..f30619274 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino
@@ -764,7 +764,7 @@ bool Ade7953Command(void) {
* Interface
\*********************************************************************************************/
-bool Xnrg07(uint8_t function) {
+bool Xnrg07(uint32_t function) {
if (!I2cEnabled(XI2C_07) && (SPI_MOSI_MISO != TasmotaGlobal.spi_enabled)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino b/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino
index 5a54e1083..dbd2462cb 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_08_sdm120.ino
@@ -261,7 +261,7 @@ void Sdm220Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg08(uint8_t function)
+bool Xnrg08(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino b/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino
index 885f966d6..329c58f51 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_09_dds2382.ino
@@ -110,7 +110,7 @@ void Dds2382DrvInit(void)
* Interface
\*********************************************************************************************/
-bool Xnrg09(uint8_t function)
+bool Xnrg09(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino b/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino
index 717ded0e8..dcbd2ea40 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_10_sdm630.ino
@@ -235,7 +235,7 @@ void Sdm630DrvInit(void)
* Interface
\*********************************************************************************************/
-bool Xnrg10(uint8_t function)
+bool Xnrg10(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino b/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino
index cad411916..59b4cb88a 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_11_ddsu666.ino
@@ -152,7 +152,7 @@ void Ddsu666DrvInit(void)
* Interface
\*********************************************************************************************/
-bool Xnrg11(uint8_t function)
+bool Xnrg11(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino
index f454b1c06..c57fdd8d2 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_12_solaxX1.ino
@@ -582,7 +582,7 @@ void solaxX1_Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xnrg12(uint8_t function)
+bool Xnrg12(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino b/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino
index a064a5178..8fa11f7ef 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_13_fif_le01mr.ino
@@ -282,7 +282,7 @@ void FifLEShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg13(uint8_t function)
+bool Xnrg13(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
index 740029725..9287bab21 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_14_bl09xx.ino
@@ -404,7 +404,7 @@ void Bl09XXShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg14(uint8_t function) {
+bool Xnrg14(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
index a17361047..1a739084f 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_15_teleinfo.ino
@@ -1064,7 +1064,7 @@ void TInfoShow(bool json)
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xnrg15(uint8_t function)
+bool Xnrg15(uint32_t function)
{
bool result = false;
switch (function)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino b/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino
index 10e3a5de1..fa25d2048 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_16_iem3000.ino
@@ -203,7 +203,7 @@ void Iem3000DrvInit(void)
* Interface
\*********************************************************************************************/
-bool Xnrg16(uint8_t function)
+bool Xnrg16(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino b/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino
index 53c748ea2..117dab094 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_17_ornowe517.ino
@@ -211,7 +211,7 @@ void We517DrvInit(void)
* Interface
\*********************************************************************************************/
-bool Xnrg17(uint8_t function)
+bool Xnrg17(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino b/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino
index d93732386..61a00ee4f 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_18_sdm72.ino
@@ -207,7 +207,7 @@ void Sdm72Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg18(uint8_t function)
+bool Xnrg18(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
index 5a282bc50..71e675e1b 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_19_cse7761.ino
@@ -668,7 +668,7 @@ bool Cse7761Command(void) {
* Interface
\*********************************************************************************************/
-bool Xnrg19(uint8_t function) {
+bool Xnrg19(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino b/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino
index 1c34c893d..e9607ab11 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_21_sdm230.ino
@@ -267,7 +267,7 @@ void Sdm230Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg21(uint8_t function)
+bool Xnrg21(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
index c87fd2a30..2bdd3eff4 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_22_bl6523.ino
@@ -330,7 +330,7 @@ void Bl6523DrvInit(void)
* Interface
\*********************************************************************************************/
-bool Xnrg22(uint8_t function)
+bool Xnrg22(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino b/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino
index 08e987f0c..181fbd9ed 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino
@@ -755,7 +755,7 @@ void Ade7880Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg23(uint8_t function) {
+bool Xnrg23(uint32_t function) {
if (!I2cEnabled(XI2C_65)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
index 33a3b81bc..6f78aa48a 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
@@ -773,7 +773,7 @@ void EnergyModbusShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xnrg29(uint8_t function) {
+bool Xnrg29(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
index 021003e3a..8a1abd304 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_30_dummy.ino
@@ -159,7 +159,7 @@ void NrgDummyDrvInit(void) {
* Interface
\*********************************************************************************************/
-bool Xnrg30(uint8_t function) {
+bool Xnrg30(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino
index 20c0ecc81..0ebb8663e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino
@@ -395,7 +395,7 @@ void CmndCounterDebounceHigh(void)
* Interface
\*********************************************************************************************/
-bool Xsns01(uint8_t function)
+bool Xsns01(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino b/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino
index 81f562584..8c6464aea 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_02_analog.ino
@@ -841,7 +841,7 @@ void CmndAdcParam(void) {
* Interface
\*********************************************************************************************/
-bool Xsns02(uint8_t function) {
+bool Xsns02(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_04_snfsc.ino b/tasmota/tasmota_xsns_sensor/xsns_04_snfsc.ino
index 545c39e7a..16bc77212 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_04_snfsc.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_04_snfsc.ino
@@ -148,7 +148,7 @@ void SonoffScShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns04(uint8_t function)
+bool Xsns04(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
index 8c5ae975e..74ccc478e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino
@@ -611,7 +611,7 @@ void CmndDSAlias(void) {
* Interface
\*********************************************************************************************/
-bool Xsns05(uint8_t function) {
+bool Xsns05(uint32_t function) {
bool result = false;
if (PinUsed(GPIO_DSB, GPIO_ANY)) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
index 2346cbe96..310f9d5da 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
@@ -325,7 +325,7 @@ void CmndDSAlias(void) {
* Interface
\*********************************************************************************************/
-bool Xsns05(uint8_t function) {
+bool Xsns05(uint32_t function) {
bool result = false;
if (PinUsed(GPIO_DSB, GPIO_ANY)) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino
index 62a7d84ae..bab1efaec 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v5.ino
@@ -296,7 +296,7 @@ void DhtShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns06(uint8_t function) {
+bool Xsns06(uint32_t function) {
bool result = false;
if (dht_active) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino
index a2bf67350..c2160b512 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_06_dht_v6.ino
@@ -371,7 +371,7 @@ void DhtShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns06(uint8_t function) {
+bool Xsns06(uint32_t function) {
bool result = false;
if (dht_active) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino b/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino
index 1472b7b53..eb902577a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_06_esp32_dht.ino
@@ -130,7 +130,7 @@ void DhtShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns06(uint8_t function) {
+bool Xsns06(uint32_t function) {
bool result = false;
if (dht_active) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino b/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino
index 4d571960c..e420eea1b 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_07_sht1x.ino
@@ -184,7 +184,7 @@ void ShtShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns07(uint8_t function) {
+bool Xsns07(uint32_t function) {
if (!I2cEnabled(XI2C_08)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_08_htu21.ino b/tasmota/tasmota_xsns_sensor/xsns_08_htu21.ino
index 0b9c652ae..c9b535ffd 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_08_htu21.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_08_htu21.ino
@@ -255,7 +255,7 @@ void HtuShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns08(uint8_t function)
+bool Xsns08(uint32_t function)
{
if (!I2cEnabled(XI2C_09)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino
index 6846af7ae..503b8ff3e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_09_bmp.ino
@@ -645,7 +645,7 @@ void BMP_EnterSleep(void)
* Interface
\*********************************************************************************************/
-bool Xsns09(uint8_t function)
+bool Xsns09(uint32_t function)
{
if (!I2cEnabled(XI2C_10)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_100_ina3221.ino b/tasmota/tasmota_xsns_sensor/xsns_100_ina3221.ino
index 2b3571946..3ea91a9a2 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_100_ina3221.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_100_ina3221.ino
@@ -418,7 +418,7 @@ void Ina3221Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns100(uint8_t function)
+bool Xsns100(uint32_t function)
{
if (!I2cEnabled(XI2C_72)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_10_bh1750.ino b/tasmota/tasmota_xsns_sensor/xsns_10_bh1750.ino
index c67b0e24e..521defe68 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_10_bh1750.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_10_bh1750.ino
@@ -193,7 +193,7 @@ void Bh1750Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns10(uint8_t function) {
+bool Xsns10(uint32_t function) {
if (!I2cEnabled(XI2C_11)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino b/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino
index cb24554ad..59547b037 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_11_veml6070.ino
@@ -294,7 +294,7 @@ void Veml6070Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns11(uint8_t function)
+bool Xsns11(uint32_t function)
{
if (!I2cEnabled(XI2C_12)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino b/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino
index 6da0baaca..c50d9a82d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_127_esp32_sensors.ino
@@ -126,7 +126,7 @@ void Esp32SensorShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns127(uint8_t function) {
+bool Xsns127(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino b/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino
index 052625249..98397babe 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_12_ads1115.ino
@@ -331,7 +331,7 @@ bool ADS1115_Command(void)
* Interface
\*********************************************************************************************/
-bool Xsns12(uint8_t function)
+bool Xsns12(uint32_t function)
{
if (!I2cEnabled(XI2C_13)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_13_ina219.ino b/tasmota/tasmota_xsns_sensor/xsns_13_ina219.ino
index 50e9a39e5..92a679e92 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_13_ina219.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_13_ina219.ino
@@ -369,7 +369,7 @@ void Ina219Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns13(uint8_t function)
+bool Xsns13(uint32_t function)
{
if (!I2cEnabled(XI2C_14)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino b/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino
index b073020e8..24dd17394 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_14_sht3x.ino
@@ -155,7 +155,7 @@ void Sht3xShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns14(uint8_t function) {
+bool Xsns14(uint32_t function) {
if (!I2cEnabled(XI2C_15)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_15_mhz19.ino b/tasmota/tasmota_xsns_sensor/xsns_15_mhz19.ino
index 67745ddb4..3d89ff470 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_15_mhz19.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_15_mhz19.ino
@@ -362,7 +362,7 @@ void MhzShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns15(uint8_t function)
+bool Xsns15(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_16_tsl2561.ino b/tasmota/tasmota_xsns_sensor/xsns_16_tsl2561.ino
index d0674c522..357522cfb 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_16_tsl2561.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_16_tsl2561.ino
@@ -116,7 +116,7 @@ void Tsl2561Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns16(uint8_t function)
+bool Xsns16(uint32_t function)
{
if (!I2cEnabled(XI2C_16)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino b/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino
index de7d5a89b..a2a20196c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_17_senseair.ino
@@ -173,7 +173,7 @@ void SenseairShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns17(uint8_t function)
+bool Xsns17(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
index d1bdf5599..7a403fdb6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_18_pms5003.ino
@@ -363,7 +363,7 @@ void PmsShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns18(uint8_t function)
+bool Xsns18(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_19_mgs.ino b/tasmota/tasmota_xsns_sensor/xsns_19_mgs.ino
index 5334c5c48..519c48b0a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_19_mgs.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_19_mgs.ino
@@ -89,7 +89,7 @@ void MGSShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns19(uint8_t function)
+bool Xsns19(uint32_t function)
{
if (!I2cEnabled(XI2C_17)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino b/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino
index 71a4b1c77..faa3cd3f9 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_20_novasds.ino
@@ -249,7 +249,7 @@ void NovaSdsShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns20(uint8_t function)
+bool Xsns20(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino b/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino
index a2509da94..7c4217da3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_21_sgp30.ino
@@ -143,7 +143,7 @@ void Sgp30Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns21(uint8_t function)
+bool Xsns21(uint32_t function)
{
if (!I2cEnabled(XI2C_18)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino b/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino
index df1764430..01f5a22a9 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_22_sr04.ino
@@ -209,7 +209,7 @@ void Sr04Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns22(uint8_t function) {
+bool Xsns22(uint32_t function) {
bool result = false;
if (SR04.type) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_24_si1145.ino b/tasmota/tasmota_xsns_sensor/xsns_24_si1145.ino
index 393211a9b..0f4df82e5 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_24_si1145.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_24_si1145.ino
@@ -369,7 +369,7 @@ void Si1145Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns24(uint8_t function)
+bool Xsns24(uint32_t function)
{
if (!I2cEnabled(XI2C_19)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_26_lm75ad.ino b/tasmota/tasmota_xsns_sensor/xsns_26_lm75ad.ino
index 03501b9a1..b8c271180 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_26_lm75ad.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_26_lm75ad.ino
@@ -100,7 +100,7 @@ void LM75ADShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns26(uint8_t function)
+bool Xsns26(uint32_t function)
{
if (!I2cEnabled(XI2C_20)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_27_apds9960.ino b/tasmota/tasmota_xsns_sensor/xsns_27_apds9960.ino
index 6c868a4be..64b6864a6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_27_apds9960.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_27_apds9960.ino
@@ -1992,7 +1992,7 @@ bool APDS9960CommandSensor(void) {
* Interface
\*********************************************************************************************/
-bool Xsns27(uint8_t function) {
+bool Xsns27(uint32_t function) {
if (!I2cEnabled(XI2C_21)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_28_tm1638.ino b/tasmota/tasmota_xsns_sensor/xsns_28_tm1638.ino
index 2c3e32707..8a0cdb8f8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_28_tm1638.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_28_tm1638.ino
@@ -198,7 +198,7 @@ void TmShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns28(uint8_t function)
+bool Xsns28(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_29_mcp230xx.ino b/tasmota/tasmota_xsns_sensor/xsns_29_mcp230xx.ino
index 64d5b1700..f158b79f6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_29_mcp230xx.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_29_mcp230xx.ino
@@ -903,7 +903,7 @@ void MCP230xx_SwitchRelay() {
Interface
\*********************************************************************************************/
-bool Xsns29(uint8_t function)
+bool Xsns29(uint32_t function)
{
if (!I2cEnabled(XI2C_22)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_30_mpr121.ino b/tasmota/tasmota_xsns_sensor/xsns_30_mpr121.ino
index 24a0cbdd7..015b121a6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_30_mpr121.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_30_mpr121.ino
@@ -386,7 +386,7 @@ void Mpr121Show(struct mpr121 *pS, uint8_t function)
}
} // if->running
} // for-loop i
-} // void Mpr121Show(uint8_t function)
+} // void Mpr121Show(uint32_t function)
/*********************************************************************************************\
* Interface
@@ -407,7 +407,7 @@ void Mpr121Show(struct mpr121 *pS, uint8_t function)
* @post None.
*
*/
-bool Xsns30(uint8_t function)
+bool Xsns30(uint32_t function)
{
if (!I2cEnabled(XI2C_23)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_31_ccs811.ino b/tasmota/tasmota_xsns_sensor/xsns_31_ccs811.ino
index c0525a909..4b59c99b1 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_31_ccs811.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_31_ccs811.ino
@@ -105,7 +105,7 @@ void CCS811Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns31(uint8_t function)
+bool Xsns31(uint32_t function)
{
if (!I2cEnabled(XI2C_24)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_31_ccs811_v2.ino b/tasmota/tasmota_xsns_sensor/xsns_31_ccs811_v2.ino
index 735ebdbf9..2f16406f7 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_31_ccs811_v2.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_31_ccs811_v2.ino
@@ -306,7 +306,7 @@ void CCS811Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns31(uint8_t function)
+bool Xsns31(uint32_t function)
{
if (!I2cEnabled(XI2C_24)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_32_mpu6050.ino b/tasmota/tasmota_xsns_sensor/xsns_32_mpu6050.ino
index eaa4018ac..0aa43ea10 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_32_mpu6050.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_32_mpu6050.ino
@@ -248,7 +248,7 @@ void MPU_6050Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns32(uint8_t function)
+bool Xsns32(uint32_t function)
{
if (!I2cEnabled(XI2C_25)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_33_qmc5883l.ino b/tasmota/tasmota_xsns_sensor/xsns_33_qmc5883l.ino
index 7c640a737..f024da374 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_33_qmc5883l.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_33_qmc5883l.ino
@@ -283,7 +283,7 @@ void QMC5883L_Show(uint8_t json) {
* Interface
\*********************************************************************************************/
-bool Xsns33(byte function) {
+bool Xsns33(uint32_t function) {
if (!I2cEnabled(XI2C_71)) { return false; }
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_34_hx711.ino b/tasmota/tasmota_xsns_sensor/xsns_34_hx711.ino
index 8a051949a..a12cce716 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_34_hx711.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_34_hx711.ino
@@ -574,7 +574,7 @@ void HandleHxAction(void) {
* Interface
\*********************************************************************************************/
-bool Xsns34(uint8_t function) {
+bool Xsns34(uint32_t function) {
bool result = false;
if (Hx.type) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_35_tx20.ino b/tasmota/tasmota_xsns_sensor/xsns_35_tx20.ino
index 3e1cfd25b..a128f2fe3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_35_tx20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_35_tx20.ino
@@ -581,7 +581,7 @@ void Tx2xShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns35(uint8_t function)
+bool Xsns35(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_36_mgc3130.ino b/tasmota/tasmota_xsns_sensor/xsns_36_mgc3130.ino
index 73961c753..39e84608a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_36_mgc3130.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_36_mgc3130.ino
@@ -599,7 +599,7 @@ bool MGC3130CommandSensor()
* Interface
\*********************************************************************************************/
-bool Xsns36(uint8_t function)
+bool Xsns36(uint32_t function)
{
if (!I2cEnabled(XI2C_27)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_37_rfsensor.ino b/tasmota/tasmota_xsns_sensor/xsns_37_rfsensor.ino
index 25db41a0c..aa3d8b6d1 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_37_rfsensor.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_37_rfsensor.ino
@@ -649,7 +649,7 @@ void RfSnsShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns37(uint8_t function)
+bool Xsns37(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino b/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino
index 1aed89816..ad6cf6f66 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_38_az7798.ino
@@ -297,7 +297,7 @@ void AzShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns38(uint8_t function)
+bool Xsns38(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_39_max31855.ino b/tasmota/tasmota_xsns_sensor/xsns_39_max31855.ino
index 1b7bca1b3..13b0450b2 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_39_max31855.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_39_max31855.ino
@@ -169,7 +169,7 @@ void MAX31855_Show(bool Json) {
* Interface
\*********************************************************************************************/
-bool Xsns39(uint8_t function)
+bool Xsns39(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
index 4c39f4342..dee669dd5 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_40_pn532.ino
@@ -758,7 +758,7 @@ void PN532_Show(void) {
* Interface
\*********************************************************************************************/
-bool Xsns40(uint8_t function) {
+bool Xsns40(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino b/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino
index 0b1a4fb5a..2d13c6275 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_41_max44009.ino
@@ -139,7 +139,7 @@ void Max4409Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns41(uint8_t function)
+bool Xsns41(uint32_t function)
{
if (!I2cEnabled(XI2C_28)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino b/tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino
index 60057b2b1..f67416bd2 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino
@@ -320,7 +320,7 @@ void Scd30Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns42(byte function) {
+bool Xsns42(uint32_t function) {
if (!I2cEnabled(XI2C_29)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_43_hre.ino b/tasmota/tasmota_xsns_sensor/xsns_43_hre.ino
index 6ceddf43c..a288de135 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_43_hre.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_43_hre.ino
@@ -257,7 +257,7 @@ void hreShow(boolean json)
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-bool Xsns43(byte function)
+bool Xsns43(uint32_t function)
{
// If we don't have pins assigned give up quickly.
if (!PinUsed(GPIO_HRE_CLOCK) || !PinUsed(GPIO_HRE_DATA)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_44_sps30.ino b/tasmota/tasmota_xsns_sensor/xsns_44_sps30.ino
index 1af0a7127..016f7ef9b 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_44_sps30.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_44_sps30.ino
@@ -284,7 +284,7 @@ bool SPS30_cmd(void)
* Interface
\*********************************************************************************************/
-bool Xsns44(byte function)
+bool Xsns44(uint32_t function)
{
if (!I2cEnabled(XI2C_30)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino b/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino
index 84eda3ef6..55882066c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_45_vl53l0x.ino
@@ -229,7 +229,7 @@ void Vl53l0Show(boolean json) {
* Interface
\*********************************************************************************************/
-bool Xsns45(byte function) {
+bool Xsns45(uint32_t function) {
if (!I2cEnabled(XI2C_31)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_46_MLX90614.ino b/tasmota/tasmota_xsns_sensor/xsns_46_MLX90614.ino
index 5cb7f65cf..c93ec08b5 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_46_MLX90614.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_46_MLX90614.ino
@@ -137,7 +137,7 @@ uint8_t MLX90614_crc8(uint8_t *addr, uint8_t len)
* Interface
\*********************************************************************************************/
-bool Xsns46(byte function)
+bool Xsns46(uint32_t function)
{
if (!I2cEnabled(XI2C_32)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino b/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino
index efbd27179..9a8bc0b03 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_47_max31865.ino
@@ -387,7 +387,7 @@ void MAX31865_Show(bool Json) {
* Interface
\*********************************************************************************************/
-bool Xsns47(uint8_t function)
+bool Xsns47(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_48_chirp.ino b/tasmota/tasmota_xsns_sensor/xsns_48_chirp.ino
index b5e3db4e2..1782a59df 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_48_chirp.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_48_chirp.ino
@@ -519,7 +519,7 @@ bool ChirpCmd(void) {
* Interface
\*********************************************************************************************/
-bool Xsns48(uint8_t function)
+bool Xsns48(uint32_t function)
{
if (!I2cEnabled(XI2C_33)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_50_paj7620.ino b/tasmota/tasmota_xsns_sensor/xsns_50_paj7620.ino
index 8a8db26c5..4374476bd 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_50_paj7620.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_50_paj7620.ino
@@ -422,7 +422,7 @@ bool PAJ7620CommandSensor(void)
* Interface
\*********************************************************************************************/
-bool Xsns50(uint8_t function)
+bool Xsns50(uint32_t function)
{
if (!I2cEnabled(XI2C_34)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_51_rdm6300.ino b/tasmota/tasmota_xsns_sensor/xsns_51_rdm6300.ino
index a277e7d65..5a929524d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_51_rdm6300.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_51_rdm6300.ino
@@ -145,7 +145,7 @@ void RDM6300Show(void) {
* Interface
\*********************************************************************************************/
-bool Xsns51(byte function) {
+bool Xsns51(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_52_esp32_ibeacon_ble.ino b/tasmota/tasmota_xsns_sensor/xsns_52_esp32_ibeacon_ble.ino
index e68cd9013..9a96ea794 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_52_esp32_ibeacon_ble.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_52_esp32_ibeacon_ble.ino
@@ -562,7 +562,7 @@ void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *m
* Interface
\*********************************************************************************************/
-bool Xsns52(byte function)
+bool Xsns52(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_52_ibeacon.ino b/tasmota/tasmota_xsns_sensor/xsns_52_ibeacon.ino
index 473d2e05d..411e82e21 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_52_ibeacon.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_52_ibeacon.ino
@@ -969,7 +969,7 @@ void ibeacon_mqtt(const char *mac,const char *rssi,const char *uid,const char *m
* Interface
\*********************************************************************************************/
-bool Xsns52(byte function)
+bool Xsns52(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
index 451044a8e..6f53b8990 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino
@@ -3785,7 +3785,7 @@ void SML_CounterSaveState(void) {
* Interface
\*********************************************************************************************/
-bool Xsns53(byte function) {
+bool Xsns53(uint32_t function) {
bool result = false;
switch (function) {
case FUNC_INIT:
diff --git a/tasmota/tasmota_xsns_sensor/xsns_54_ina226.ino b/tasmota/tasmota_xsns_sensor/xsns_54_ina226.ino
index 4961de5bd..9df7e9b15 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_54_ina226.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_54_ina226.ino
@@ -529,7 +529,7 @@ void Ina226Show(bool json)
* @post None.
*
*/
-bool Xsns54(byte callback_id)
+bool Xsns54(uint32_t callback_id)
{
if (!I2cEnabled(XI2C_35)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_55_hih_series.ino b/tasmota/tasmota_xsns_sensor/xsns_55_hih_series.ino
index 4f6cc0648..df866a5ed 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_55_hih_series.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_55_hih_series.ino
@@ -104,7 +104,7 @@ void Hih6Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns55(uint8_t function)
+bool Xsns55(uint32_t function)
{
if (!I2cEnabled(XI2C_36)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino b/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino
index c400fba1e..0c1918b49 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_56_hpma.ino
@@ -113,7 +113,7 @@ void HpmaShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns56(uint8_t function)
+bool Xsns56(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino
index 1ec7a6838..57d70f992 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_57_tsl2591.ino
@@ -94,7 +94,7 @@ void Tsl2591Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns57(uint8_t function)
+bool Xsns57(uint32_t function)
{
if (!I2cEnabled(XI2C_40)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_58_dht12.ino b/tasmota/tasmota_xsns_sensor/xsns_58_dht12.ino
index 559d9931b..dec917b9c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_58_dht12.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_58_dht12.ino
@@ -98,7 +98,7 @@ void Dht12Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns58(uint8_t function)
+bool Xsns58(uint32_t function)
{
if (!I2cEnabled(XI2C_41)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_59_ds1624.ino b/tasmota/tasmota_xsns_sensor/xsns_59_ds1624.ino
index 6f62b8540..de9f9d1d2 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_59_ds1624.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_59_ds1624.ino
@@ -203,7 +203,7 @@ void DS1624Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns59(uint8_t function)
+bool Xsns59(uint32_t function)
{
if (!I2cEnabled(XI2C_42)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_60_GPS.ino b/tasmota/tasmota_xsns_sensor/xsns_60_GPS.ino
index edf3d9c81..0bf0b5e9e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_60_GPS.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_60_GPS.ino
@@ -878,7 +878,7 @@ bool UBXCmd(void)
* Interface
\*********************************************************************************************/
-bool Xsns60(uint8_t function)
+bool Xsns60(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_61_MI_NRF24.ino b/tasmota/tasmota_xsns_sensor/xsns_61_MI_NRF24.ino
index f5f61e4e3..e6e4b60ec 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_61_MI_NRF24.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_61_MI_NRF24.ino
@@ -1966,7 +1966,7 @@ void MINRFShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns61(uint8_t function)
+bool Xsns61(uint32_t function)
{
bool result = false;
if (NRF24.chipType) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_MI_HM10.ino b/tasmota/tasmota_xsns_sensor/xsns_62_MI_HM10.ino
index 0e5a3bc03..b9334cf96 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_62_MI_HM10.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_62_MI_HM10.ino
@@ -2302,7 +2302,7 @@ void HM10Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns62(uint8_t function)
+bool Xsns62(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
index 145ce7dc4..ead1c2260 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
@@ -2333,7 +2333,7 @@ int ExtStopBLE(){
* Interface
\*********************************************************************************************/
-bool Xsns62(uint8_t function)
+bool Xsns62(uint32_t function)
{
if (!Settings->flag5.mi32_enable) { return false; } // SetOption115 - Enable ESP32 MI32 BLE
diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino
index 0104dd58e..d1a0ebcb6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi_ble.ino
@@ -3530,7 +3530,7 @@ void MI32Show(bool json)
\*********************************************************************************************/
#define WEB_HANDLE_MI32 "mikey"
-bool Xsns62(uint8_t function)
+bool Xsns62(uint32_t function)
{
// if (!Settings->flag5.mi32_enable) { return false; } // SetOption115 - Enable ESP32 MI32 BLE
// return false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino b/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino
index 315930c0b..7a9397f0e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_63_aht1x.ino
@@ -188,7 +188,7 @@ void AHT1XShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns63(uint8_t function)
+bool Xsns63(uint32_t function)
{
if (!I2cEnabled(XI2C_43)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino b/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
index 422279cfe..727778fe1 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_64_hrxl.ino
@@ -82,7 +82,7 @@ void HRXLShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns64(uint8_t function) {
+bool Xsns64(uint32_t function) {
if (FUNC_INIT == function) {
HRXLInit();
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino b/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino
index 96a7be484..3d0f5ef29 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino
@@ -277,7 +277,7 @@ void HdcShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns65(uint8_t function)
+bool Xsns65(uint32_t function)
{
if (!I2cEnabled(XI2C_45)) {
// AddLog(LOG_LEVEL_DEBUG, PSTR("Xsns65: I2C driver not enabled for this device."));
diff --git a/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino b/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino
index 0cbf17276..55b391a3a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino
@@ -124,7 +124,7 @@ void IAQ_Show(uint8_t json)
* Interface
\*********************************************************************************************/
-bool Xsns66(byte function)
+bool Xsns66(uint32_t function)
{
if (!I2cEnabled(XI2C_46)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_67_as3935.ino b/tasmota/tasmota_xsns_sensor/xsns_67_as3935.ino
index 766ae77c3..2ae4d49a9 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_67_as3935.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_67_as3935.ino
@@ -826,7 +826,7 @@ void AH3935Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns67(uint8_t function) {
+bool Xsns67(uint32_t function) {
if (!I2cEnabled(XI2C_48)) { return false; }
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_68_windmeter.ino b/tasmota/tasmota_xsns_sensor/xsns_68_windmeter.ino
index 2768b5eaf..81bd3f2ff 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_68_windmeter.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_68_windmeter.ino
@@ -314,7 +314,7 @@ bool Xsns68Cmnd(void)
* Interface
\*********************************************************************************************/
-bool Xsns68(uint8_t function)
+bool Xsns68(uint32_t function)
{
bool result = false;
if (PinUsed(GPIO_WINDMETER_SPEED)) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_69_opentherm.ino b/tasmota/tasmota_xsns_sensor/xsns_69_opentherm.ino
index e8960de76..d18f51635 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_69_opentherm.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_69_opentherm.ino
@@ -581,7 +581,7 @@ void sns_opentherm_blor_cmd(void)
* Interface
\*********************************************************************************************/
-bool Xsns69(uint8_t function)
+bool Xsns69(uint32_t function)
{
bool result = false;
if (FUNC_INIT == function)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_70_veml6075.ino b/tasmota/tasmota_xsns_sensor/xsns_70_veml6075.ino
index 69fd074f5..e26e72b77 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_70_veml6075.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_70_veml6075.ino
@@ -272,7 +272,7 @@ void VEML6075Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns70(uint8_t function)
+bool Xsns70(uint32_t function)
{
if (!I2cEnabled(XI2C_49)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_71_veml7700.ino b/tasmota/tasmota_xsns_sensor/xsns_71_veml7700.ino
index a4bf12905..e78488dcf 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_71_veml7700.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_71_veml7700.ino
@@ -171,7 +171,7 @@ bool VEML7700Cmd(void) {
* Interface
\*********************************************************************************************/
-bool Xsns71(uint8_t function)
+bool Xsns71(uint32_t function)
{
if (!I2cEnabled(XI2C_50)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_72_mcp9808.ino b/tasmota/tasmota_xsns_sensor/xsns_72_mcp9808.ino
index 95716f9e9..0f864bac4 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_72_mcp9808.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_72_mcp9808.ino
@@ -103,7 +103,7 @@ void MCP9808Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns72(uint8_t function)
+bool Xsns72(uint32_t function)
{
if (!I2cEnabled(XI2C_51)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino b/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino
index 1ee39f0ca..a4310397f 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_73_hp303b.ino
@@ -142,7 +142,7 @@ void HP303B_Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns73(uint8_t function)
+bool Xsns73(uint32_t function)
{
if (!I2cEnabled(XI2C_52)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_74_lmt01.ino b/tasmota/tasmota_xsns_sensor/xsns_74_lmt01.ino
index eade01b2d..edfa00d3b 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_74_lmt01.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_74_lmt01.ino
@@ -108,7 +108,7 @@ void LMT01_Show(bool Json) {
* Interface
\*********************************************************************************************/
-bool Xsns74(uint8_t function)
+bool Xsns74(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino b/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino
index f08c730b0..1914881e3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_75_prometheus.ino
@@ -298,7 +298,7 @@ void HandleMetrics(void) {
JsonParserObject Object3 = value2.getObject();
for (auto key3 : Object3) {
const char *value = key3.getValue().getStr(nullptr);
- if (value != nullptr && (isdigit(value[0]) || (value[0] == '-') || (value[0] == '.'))) {
+ if (value != nullptr && isdigit(value[0])) {
String sensor = FormatMetricName(key2.getStr());
String type = FormatMetricName(key3.getStr());
@@ -311,7 +311,7 @@ void HandleMetrics(void) {
}
} else {
const char *value = value2.getStr(nullptr);
- if (value != nullptr && (isdigit(value[0]) || (value[0] == '-') || (value[0] == '.'))) {
+ if (value != nullptr && isdigit(value[0])) {
String sensor = FormatMetricName(key1.getStr());
String type = FormatMetricName(key2.getStr());
if (strcmp(type.c_str(), "totalstarttime") != 0) { // this metric causes Prometheus of fail
@@ -336,7 +336,7 @@ void HandleMetrics(void) {
const char *value = value1.getStr(nullptr);
String sensor = FormatMetricName(key1.getStr());
- if (value != nullptr && (isdigit(value[0]) || (value[0] == '-') || (value[0] == '.')) && strcmp(sensor.c_str(), "time") != 0) { //remove false 'time' metric
+ if (value != nullptr && isdigit(value[0] && strcmp(sensor.c_str(), "time") != 0)) { //remove false 'time' metric
WritePromMetricStr(PSTR("sensors"), kPromMetricGauge, value,
PSTR("sensor"), sensor.c_str(),
nullptr);
@@ -352,7 +352,7 @@ void HandleMetrics(void) {
* Interface
\*********************************************************************************************/
-bool Xsns75(uint8_t function) {
+bool Xsns75(uint32_t function) {
bool result = false;
switch (function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino b/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
index 9c4124fe8..9aa3ecaa2 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_76_dyp.ino
@@ -111,7 +111,7 @@ void DYPShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns76(uint8_t function) {
+bool Xsns76(uint32_t function) {
if (FUNC_INIT == function) {
DYPInit();
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
index 0f30076a5..b6a88538a 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_77_vl53l1x.ino
@@ -158,7 +158,7 @@ void Vl53l1Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns77(uint8_t function) {
+bool Xsns77(uint32_t function) {
if (!I2cEnabled(XI2C_54)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_78_xezo.ino b/tasmota/tasmota_xsns_sensor/xsns_78_xezo.ino
index 60b3cd8e4..488ba78c2 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_78_xezo.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_78_xezo.ino
@@ -306,7 +306,7 @@ private:
// The main driver is the same for all devices.
// What changes is the implementation of the class itself
-bool Xsns78(uint8_t function)
+bool Xsns78(uint32_t function)
{
if (!I2cEnabled(XI2C_55)) {
return false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_79_as608.ino b/tasmota/tasmota_xsns_sensor/xsns_79_as608.ino
index fba9e8afc..4b8115d1d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_79_as608.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_79_as608.ino
@@ -294,7 +294,7 @@ void CmndFpCount(void) {
* Interface
\*********************************************************************************************/
-bool Xsns79(uint8_t function) {
+bool Xsns79(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino b/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino
index 3ad92f4d9..7cb2daf93 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_80_mfrc522.ino
@@ -160,7 +160,7 @@ bool RC522Command(void) {
* Interface
\*********************************************************************************************/
-bool Xsns80(uint8_t function) {
+bool Xsns80(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_81_seesaw_soil.ino b/tasmota/tasmota_xsns_sensor/xsns_81_seesaw_soil.ino
index 15a8bff66..429c43856 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_81_seesaw_soil.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_81_seesaw_soil.ino
@@ -328,7 +328,7 @@ void seeSoilName(int no, char *name, int len) // generates a sensor name
* Interface
\*********************************************************************************************/
-bool Xsns81(uint8_t function)
+bool Xsns81(uint32_t function)
{
if (!I2cEnabled(XI2C_56)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_82_wiegand.ino b/tasmota/tasmota_xsns_sensor/xsns_82_wiegand.ino
index 9908e7a55..e0247ead3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_82_wiegand.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_82_wiegand.ino
@@ -617,7 +617,7 @@ const char kWiegandCommands[] PROGMEM = "Wie|" // No prefix
* Interface
\*********************************************************************************************/
-bool Xsns82(byte function) {
+bool Xsns82(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
index 6865f38cb..6e40008fd 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_83_neopool.ino
@@ -2559,7 +2559,7 @@ void CmndNeopoolIONRes(void)
* Interface
\*********************************************************************************************/
-bool Xsns83(uint8_t function)
+bool Xsns83(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino b/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino
index 36bd30842..8292f67b7 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_84_tof10120.ino
@@ -109,7 +109,7 @@ void Tof10120Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns84(uint8_t function) {
+bool Xsns84(uint32_t function) {
if (!I2cEnabled(XI2C_57)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino b/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino
index 5b650a198..c80820180 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_85_mpu6886.ino
@@ -103,7 +103,7 @@ void MPU_Every_Second(void) {
* Interface
\*********************************************************************************************/
-bool Xsns85(uint8_t function) {
+bool Xsns85(uint32_t function) {
if (!I2cEnabled(XI2C_58)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino b/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino
index 6b7963f90..ea32fcb22 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_86_tfminiplus.ino
@@ -211,7 +211,7 @@ void TfmpShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns86(byte callback_id)
+bool Xsns86(uint32_t callback_id)
{
bool result = false;
if (FUNC_INIT == callback_id)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_87_can_sniffer.ino b/tasmota/tasmota_xsns_sensor/xsns_87_can_sniffer.ino
index 6d4f733be..db4c62c3e 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_87_can_sniffer.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_87_can_sniffer.ino
@@ -191,7 +191,7 @@ void MCP2515_Read() {
* Interface
\*********************************************************************************************/
-bool Xsns87(uint8_t function) {
+bool Xsns87(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_87_mcp2515.ino b/tasmota/tasmota_xsns_sensor/xsns_87_mcp2515.ino
index ceb3cce07..3fe523ad4 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_87_mcp2515.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_87_mcp2515.ino
@@ -407,7 +407,7 @@ void MCP2515_Show(bool Json) {
* Interface
\*********************************************************************************************/
-bool Xsns87(uint8_t function)
+bool Xsns87(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_88_am2320.ino b/tasmota/tasmota_xsns_sensor/xsns_88_am2320.ino
index cb177987b..2d07d2061 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_88_am2320.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_88_am2320.ino
@@ -166,7 +166,7 @@ void Am2320Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns88(uint8_t function)
+bool Xsns88(uint32_t function)
{
if (!I2cEnabled(XI2C_60)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_89_t67xx.ino b/tasmota/tasmota_xsns_sensor/xsns_89_t67xx.ino
index 8b018f88c..34f4787a3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_89_t67xx.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_89_t67xx.ino
@@ -297,7 +297,7 @@ T67XX t67xx;
* Interface
\*********************************************************************************************/
-bool Xsns89(uint8_t function)
+bool Xsns89(uint32_t function)
{
uint16_t ppm = 0;
if (!I2cEnabled(XI2C_61))
diff --git a/tasmota/tasmota_xsns_sensor/xsns_90_hrg15.ino b/tasmota/tasmota_xsns_sensor/xsns_90_hrg15.ino
index 0743d8902..0f062c6ed 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_90_hrg15.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_90_hrg15.ino
@@ -218,7 +218,7 @@ bool Rg15Command(void) {
* Interface
\*********************************************************************************************/
-bool Xsns90(uint8_t function) {
+bool Xsns90(uint32_t function) {
bool result = false;
if (FUNC_INIT == function) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino b/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
index 8e88bb596..3248ea7f6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
@@ -165,7 +165,7 @@ void VindriktningShow(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns91(uint8_t function) {
+bool Xsns91(uint32_t function) {
bool result = false;
if (Vindriktning.type) {
diff --git a/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino b/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino
index 252914d31..9689585d3 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_92_scd40.ino
@@ -459,7 +459,7 @@ void Scd40Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns92(byte function)
+bool Xsns92(uint32_t function)
{
if (!I2cEnabled(XI2C_62)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_93_hm330x.ino b/tasmota/tasmota_xsns_sensor/xsns_93_hm330x.ino
index a64141507..e18ae6de8 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_93_hm330x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_93_hm330x.ino
@@ -322,7 +322,7 @@ void HM330XShow(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns93(byte function)
+bool Xsns93(uint32_t function)
{
if (!I2cEnabled(XI2C_63)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_94_hdc2010.ino b/tasmota/tasmota_xsns_sensor/xsns_94_hdc2010.ino
index 8717b6d90..197bed50b 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_94_hdc2010.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_94_hdc2010.ino
@@ -175,7 +175,7 @@ void Hdc2010SetMeasurementConfig() {
* Interface
\*********************************************************************************************/
-bool Xsns94(uint8_t function)
+bool Xsns94(uint32_t function)
{
if (!I2cEnabled(XI2C_64)) {
return false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino b/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino
index 17c090c10..931b83c4c 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_95_cm110x.ino
@@ -432,7 +432,7 @@ void CM11Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns95(uint8_t function)
+bool Xsns95(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino b/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
index 16a635e9e..e1c5fb6dd 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_96_flowratemeter.ino
@@ -347,7 +347,7 @@ bool FlowRateMeterCommand(void) {
* Interface
\*********************************************************************************************/
-bool Xsns96(uint8_t function)
+bool Xsns96(uint32_t function)
{
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_97_hyt.ino b/tasmota/tasmota_xsns_sensor/xsns_97_hyt.ino
index c8b84320e..8bdcbe782 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_97_hyt.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_97_hyt.ino
@@ -98,7 +98,7 @@ void HYT_Show(bool json) {
* Interface
\*********************************************************************************************/
-bool Xsns97(uint8_t function) {
+bool Xsns97(uint32_t function) {
if (!I2cEnabled(XI2C_68)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino b/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino
index 093136626..b25555bba 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_98_sgp40.ino
@@ -139,7 +139,7 @@ void Sgp40Show(bool json)
* Interface
\*********************************************************************************************/
-bool Xsns98(uint8_t function)
+bool Xsns98(uint32_t function)
{
if (!I2cEnabled(XI2C_69)) { return false; }
diff --git a/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino b/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino
index 3c3cd89e9..d299e485d 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_99_luxv30b.ino
@@ -121,7 +121,7 @@ class LuxV30b {
void Detect();
bool Found();
void Read();
- void Show(uint8_t function);
+ void Show(uint32_t function);
private:
float Lux();
bool _found;
@@ -164,7 +164,7 @@ float LuxV30b::Lux() {
return ((float)_lux * 1.4) / 1000;
}
-void LuxV30b::Show(uint8_t function) {
+void LuxV30b::Show(uint32_t function) {
// if (0 < Lux()) {
if (_lux) {
char lux[FLOATSZ];
@@ -190,7 +190,7 @@ LuxV30b Luxv30b;
* Interface
\*********************************************************************************************/
-bool Xsns99(uint8_t function) {
+bool Xsns99(uint32_t function) {
if (!I2cEnabled(XI2C_70)) { return false; }
bool result = false;
diff --git a/tasmota/tasmota_xx2c_global/xdrv_interface.ino b/tasmota/tasmota_xx2c_global/xdrv_interface.ino
index dcf763935..247e7adb2 100644
--- a/tasmota/tasmota_xx2c_global/xdrv_interface.ino
+++ b/tasmota/tasmota_xx2c_global/xdrv_interface.ino
@@ -18,9 +18,9 @@
*/
#ifdef XFUNC_PTR_IN_ROM
-bool (* const xdrv_func_ptr[])(uint8_t) PROGMEM = { // Driver Function Pointers
+bool (* const xdrv_func_ptr[])(uint32_t) PROGMEM = { // Driver Function Pointers
#else
-bool (* const xdrv_func_ptr[])(uint8_t) = { // Driver Function Pointers
+bool (* const xdrv_func_ptr[])(uint32_t) = { // Driver Function Pointers
#endif
#ifdef XDRV_01
@@ -1063,8 +1063,7 @@ const uint8_t kXdrvList[] = {
/*********************************************************************************************/
-void XsnsDriverState(void)
-{
+void XsnsDriverState(void) {
ResponseAppend_P(PSTR(",\"Drivers\":\"")); // Use string for future enable/disable signal
for (uint32_t i = 0; i < sizeof(kXdrvList); i++) {
#ifdef XFUNC_PTR_IN_ROM
@@ -1099,8 +1098,7 @@ bool XdrvRulesProcess(bool teleperiod) {
}
#ifdef USE_DEBUG_DRIVER
-void ShowFreeMem(const char *where)
-{
+void ShowFreeMem(const char *where) {
char stemp[30];
snprintf_P(stemp, sizeof(stemp), where);
XdrvMailbox.data = stemp;
@@ -1112,8 +1110,7 @@ void ShowFreeMem(const char *where)
* Function call to single xdrv
\*********************************************************************************************/
-bool XdrvCallDriver(uint32_t driver, uint8_t Function)
-{
+bool XdrvCallDriver(uint32_t driver, uint32_t function) {
for (uint32_t x = 0; x < xdrv_present; x++) {
#ifdef XFUNC_PTR_IN_ROM
uint32_t listed = pgm_read_byte(kXdrvList + x);
@@ -1121,7 +1118,7 @@ bool XdrvCallDriver(uint32_t driver, uint8_t Function)
uint32_t listed = kXdrvList[x];
#endif
if (driver == listed) {
- return xdrv_func_ptr[x](Function);
+ return xdrv_func_ptr[x](function);
}
}
return false;
@@ -1131,11 +1128,10 @@ bool XdrvCallDriver(uint32_t driver, uint8_t Function)
* Function call to all xdrv
\*********************************************************************************************/
-bool XdrvCall(uint8_t Function)
-{
+bool XdrvCall(uint32_t function) {
bool result = false;
-// DEBUG_TRACE_LOG(PSTR("DRV: %d"), Function);
+// DEBUG_TRACE_LOG(PSTR("DRV: %d"), function);
uint32_t profile_driver_start = millis();
@@ -1143,7 +1139,7 @@ bool XdrvCall(uint8_t Function)
uint32_t profile_function_start = millis();
- result = xdrv_func_ptr[x](Function);
+ result = xdrv_func_ptr[x](function);
#ifdef USE_PROFILE_FUNCTION
#ifdef XFUNC_PTR_IN_ROM
@@ -1151,25 +1147,25 @@ bool XdrvCall(uint8_t Function)
#else
uint32_t index = kXdrvList[x];
#endif
- PROFILE_FUNCTION("drv", index, Function, profile_function_start);
+ PROFILE_FUNCTION("drv", index, function, profile_function_start);
#endif // USE_PROFILE_FUNCTION
- if (result && ((FUNC_COMMAND == Function) ||
- (FUNC_COMMAND_DRIVER == Function) ||
- (FUNC_MQTT_DATA == Function) ||
- (FUNC_RULES_PROCESS == Function) ||
- (FUNC_BUTTON_PRESSED == Function) ||
- (FUNC_SERIAL == Function) ||
- (FUNC_MODULE_INIT == Function) ||
- (FUNC_SET_CHANNELS == Function) ||
- (FUNC_PIN_STATE == Function) ||
- (FUNC_SET_DEVICE_POWER == Function)
+ if (result && ((FUNC_COMMAND == function) ||
+ (FUNC_COMMAND_DRIVER == function) ||
+ (FUNC_MQTT_DATA == function) ||
+ (FUNC_RULES_PROCESS == function) ||
+ (FUNC_BUTTON_PRESSED == function) ||
+ (FUNC_SERIAL == function) ||
+ (FUNC_MODULE_INIT == function) ||
+ (FUNC_SET_CHANNELS == function) ||
+ (FUNC_PIN_STATE == function) ||
+ (FUNC_SET_DEVICE_POWER == function)
)) {
break;
}
}
- PROFILE_DRIVER("drv", Function, profile_driver_start);
+ PROFILE_DRIVER("drv", function, profile_driver_start);
return result;
}
diff --git a/tasmota/tasmota_xx2c_global/xdsp_interface.ino b/tasmota/tasmota_xx2c_global/xdsp_interface.ino
index d404e169e..06808ca18 100644
--- a/tasmota/tasmota_xx2c_global/xdsp_interface.ino
+++ b/tasmota/tasmota_xx2c_global/xdsp_interface.ino
@@ -20,9 +20,9 @@
#ifdef USE_DISPLAY
#ifdef XFUNC_PTR_IN_ROM
-bool (* const xdsp_func_ptr[])(uint8_t) PROGMEM = { // Display Function Pointers
+bool (* const xdsp_func_ptr[])(uint32_t) PROGMEM = { // Display Function Pointers
#else
-bool (* const xdsp_func_ptr[])(uint8_t) = { // Display Function Pointers
+bool (* const xdsp_func_ptr[])(uint32_t) = { // Display Function Pointers
#endif
#ifdef XDSP_01
@@ -177,21 +177,19 @@ const uint8_t xdsp_present = sizeof(xdsp_func_ptr) / sizeof(xdsp_func_ptr[0]);
* FUNC_DISPLAY_DRAW_STRING
\*********************************************************************************************/
-uint8_t XdspPresent(void)
-{
+uint8_t XdspPresent(void) {
return xdsp_present;
}
-bool XdspCall(uint8_t Function)
-{
+bool XdspCall(uint32_t function) {
bool result = false;
- DEBUG_TRACE_LOG(PSTR("DSP: %d"), Function);
+ DEBUG_TRACE_LOG(PSTR("DSP: %d"), function);
for (uint32_t x = 0; x < xdsp_present; x++) {
- result = xdsp_func_ptr[x](Function);
+ result = xdsp_func_ptr[x](function);
- if (result && (FUNC_DISPLAY_MODEL == Function)) {
+ if (result && (FUNC_DISPLAY_MODEL == function)) {
break;
}
}
diff --git a/tasmota/tasmota_xx2c_global/xlgt_interface.ino b/tasmota/tasmota_xx2c_global/xlgt_interface.ino
index 4ef1928f8..f96cda4df 100644
--- a/tasmota/tasmota_xx2c_global/xlgt_interface.ino
+++ b/tasmota/tasmota_xx2c_global/xlgt_interface.ino
@@ -20,9 +20,9 @@
#ifdef USE_LIGHT
#ifdef XFUNC_PTR_IN_ROM
-bool (* const xlgt_func_ptr[])(uint8_t) PROGMEM = { // Light driver Function Pointers
+bool (* const xlgt_func_ptr[])(uint32_t) PROGMEM = { // Light driver Function Pointers
#else
-bool (* const xlgt_func_ptr[])(uint8_t) = { // Light driver Function Pointers
+bool (* const xlgt_func_ptr[])(uint32_t) = { // Light driver Function Pointers
#endif
#ifdef XLGT_01
@@ -94,8 +94,7 @@ const uint8_t xlgt_present = sizeof(xlgt_func_ptr) / sizeof(xlgt_func_ptr[0]);
uint8_t xlgt_active = 0;
-bool XlgtCall(uint8_t function)
-{
+bool XlgtCall(uint32_t function) {
DEBUG_TRACE_LOG(PSTR("LGT: %d"), function);
if (FUNC_MODULE_INIT == function) {
diff --git a/tasmota/tasmota_xx2c_global/xnrg_interface.ino b/tasmota/tasmota_xx2c_global/xnrg_interface.ino
index de019675c..60c45a5d1 100644
--- a/tasmota/tasmota_xx2c_global/xnrg_interface.ino
+++ b/tasmota/tasmota_xx2c_global/xnrg_interface.ino
@@ -20,9 +20,9 @@
#ifdef USE_ENERGY_SENSOR
#ifdef XFUNC_PTR_IN_ROM
-bool (* const xnrg_func_ptr[])(uint8_t) PROGMEM = { // Energy driver Function Pointers
+bool (* const xnrg_func_ptr[])(uint32_t) PROGMEM = { // Energy driver Function Pointers
#else
-bool (* const xnrg_func_ptr[])(uint8_t) = { // Energy driver Function Pointers
+bool (* const xnrg_func_ptr[])(uint32_t) = { // Energy driver Function Pointers
#endif
#ifdef XNRG_01
@@ -158,8 +158,7 @@ const uint8_t xnrg_present = sizeof(xnrg_func_ptr) / sizeof(xnrg_func_ptr[0]);
uint8_t xnrg_active = 0;
-bool XnrgCall(uint8_t function)
-{
+bool XnrgCall(uint32_t function) {
DEBUG_TRACE_LOG(PSTR("NRG: %d"), function);
if (FUNC_PRE_INIT == function) {
diff --git a/tasmota/tasmota_xx2c_global/xsns_interface.ino b/tasmota/tasmota_xx2c_global/xsns_interface.ino
index c4477447a..71f3dceb4 100644
--- a/tasmota/tasmota_xx2c_global/xsns_interface.ino
+++ b/tasmota/tasmota_xx2c_global/xsns_interface.ino
@@ -18,9 +18,9 @@
*/
#ifdef XFUNC_PTR_IN_ROM
-bool (* const xsns_func_ptr[])(uint8_t) PROGMEM = { // Sensor Function Pointers for simple implementation of sensors
+bool (* const xsns_func_ptr[])(uint32_t) PROGMEM = { // Sensor Function Pointers for simple implementation of sensors
#else
-bool (* const xsns_func_ptr[])(uint8_t) = { // Sensor Function Pointers for simple implementation of sensors
+bool (* const xsns_func_ptr[])(uint32_t) = { // Sensor Function Pointers for simple implementation of sensors
#endif
#ifdef XSNS_01
@@ -1094,7 +1094,7 @@ void XsnsSensorState(uint32_t sensor_list) {
* Function call to all xsns
\*********************************************************************************************/
-bool XsnsNextCall(uint8_t Function, uint8_t &xsns_index) {
+bool XsnsNextCall(uint32_t function, uint8_t &xsns_index) {
if (0 == xsns_present) {
xsns_index = 0;
return false;
@@ -1103,28 +1103,28 @@ bool XsnsNextCall(uint8_t Function, uint8_t &xsns_index) {
xsns_index++;
if (xsns_index == xsns_present) { xsns_index = 0; }
uint32_t max_disabled = xsns_present;
- while ((!XsnsEnabled(0, xsns_index) || ((FUNC_WEB_SENSOR == Function) && !XsnsEnabled(1, xsns_index))) && max_disabled--) { // Perform at least one sensor
+ while ((!XsnsEnabled(0, xsns_index) || ((FUNC_WEB_SENSOR == function) && !XsnsEnabled(1, xsns_index))) && max_disabled--) { // Perform at least one sensor
xsns_index++;
if (xsns_index == xsns_present) { xsns_index = 0; }
}
- return xsns_func_ptr[xsns_index](Function);
+ return xsns_func_ptr[xsns_index](function);
}
-bool XsnsCall(uint8_t Function) {
+bool XsnsCall(uint32_t function) {
bool result = false;
-// DEBUG_TRACE_LOG(PSTR("SNS: %d"), Function);
+// DEBUG_TRACE_LOG(PSTR("SNS: %d"), function);
uint32_t profile_driver_start = millis();
for (uint32_t x = 0; x < xsns_present; x++) {
if (XsnsEnabled(0, x)) { // Skip disabled sensor
- if ((FUNC_WEB_SENSOR == Function) && !XsnsEnabled(1, x)) { continue; } // Skip web info for disabled sensors
+ if ((FUNC_WEB_SENSOR == function) && !XsnsEnabled(1, x)) { continue; } // Skip web info for disabled sensors
uint32_t profile_function_start = millis();
- result = xsns_func_ptr[x](Function);
+ result = xsns_func_ptr[x](function);
#ifdef USE_PROFILE_FUNCTION
#ifdef XFUNC_PTR_IN_ROM
@@ -1132,19 +1132,19 @@ bool XsnsCall(uint8_t Function) {
#else
uint32_t index = kXsnsList[x];
#endif
- PROFILE_FUNCTION("sns", index, Function, profile_function_start);
+ PROFILE_FUNCTION("sns", index, function, profile_function_start);
#endif // USE_PROFILE_FUNCTION
- if (result && ((FUNC_COMMAND == Function) ||
- (FUNC_PIN_STATE == Function) ||
- (FUNC_COMMAND_SENSOR == Function)
+ if (result && ((FUNC_COMMAND == function) ||
+ (FUNC_PIN_STATE == function) ||
+ (FUNC_COMMAND_SENSOR == function)
)) {
break;
}
}
}
- PROFILE_DRIVER("sns", Function, profile_driver_start);
+ PROFILE_DRIVER("sns", function, profile_driver_start);
return result;
}
diff --git a/tasmota/tasmota_xx2c_global/xx2c_interface.ino b/tasmota/tasmota_xx2c_global/xx2c_interface.ino
index 5827c259b..33e7041d3 100644
--- a/tasmota/tasmota_xx2c_global/xx2c_interface.ino
+++ b/tasmota/tasmota_xx2c_global/xx2c_interface.ino
@@ -412,13 +412,11 @@ const uint8_t kI2cList[] = {
/*********************************************************************************************/
-bool I2cEnabled(uint32_t i2c_index)
-{
+bool I2cEnabled(uint32_t i2c_index) {
return (TasmotaGlobal.i2c_enabled && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32));
}
-void I2cDriverState(void)
-{
+void I2cDriverState(void) {
ResponseAppend_P(PSTR("\"")); // Use string for enable/disable signal
for (uint32_t i = 0; i < sizeof(kI2cList); i++) {
#ifdef XFUNC_PTR_IN_ROM
From 37318944863b3f04ae065e75dee2935b5c6c0b5f Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 11 Nov 2022 11:15:05 +0100
Subject: [PATCH 164/319] Added ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN``
events
---
API.md | 2 +
CHANGELOG.md | 1 +
tasmota/include/tasmota.h | 3 +-
tasmota/tasmota_support/support.ino | 4 -
tasmota/tasmota_support/support_tasmota.ino | 81 ++++++++++---------
.../tasmota_xdrv_driver/xdrv_03_energy.ino | 6 ++
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 6 ++
tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino | 11 +++
tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino | 6 ++
tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino | 6 ++
.../xdrv_21_wemo_multi.ino | 6 ++
11 files changed, 89 insertions(+), 43 deletions(-)
diff --git a/API.md b/API.md
index b631172ed..2dbc5c555 100644
--- a/API.md
+++ b/API.md
@@ -51,6 +51,8 @@ FUNC_SET_CHANNELS | | 2 | | | 1 |
FUNC_SET_SCHEME | | | | | x |
FUNC_HOTPLUG_SCAN | | | x | | |
FUNC_DEVICE_GROUP_ITEM | | x | | | |
+FUNC_NETWORK_UP | | 1 | 2 | 3 | 4 | Wifi or ETH network just went up (received even if webserver is not enabled)
+FUNC_NETWORK_DOWN | | 1 | 2 | 3 | 4 | Wifi or ETH network just went down (received even if webserver is not enabled)
The numbers represent the sequence of execution
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f5e4b364..0364f465a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
+- Added ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
### Breaking Changed
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index faf2143ae..cc53ee79f 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -387,7 +387,8 @@ enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_I2C_INIT, FUNC_
FUNC_RULES_PROCESS, FUNC_TELEPERIOD_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_BUTTON_PRESSED, FUNC_BUTTON_MULTI_PRESSED,
FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_CONSOLE_BUTTON, FUNC_WEB_ADD_MANAGEMENT_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON,
FUNC_WEB_GET_ARG, FUNC_WEB_ADD_HANDLER, FUNC_SET_CHANNELS, FUNC_SET_SCHEME, FUNC_HOTPLUG_SCAN, FUNC_TIME_SYNCED,
- FUNC_DEVICE_GROUP_ITEM };
+ FUNC_DEVICE_GROUP_ITEM,
+ FUNC_NETWORK_UP, FUNC_NETWORK_DOWN };
enum AddressConfigSteps { ADDR_IDLE, ADDR_RECEIVE, ADDR_SEND };
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index 2e1e77dd0..6446a44d8 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -21,10 +21,6 @@ extern "C" {
extern struct rst_info resetInfo;
}
-#ifdef USE_KNX
-bool knx_started = false;
-#endif // USE_KNX
-
/*********************************************************************************************\
* Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
\*********************************************************************************************/
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index 7f8008965..a0263fc7e 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1569,76 +1569,81 @@ void Every250mSeconds(void)
WifiDisable();
}
break;
- case 3: // Every x.75 second
- if (!TasmotaGlobal.global_state.network_down) {
+ case 3:
+ {
+ // is there a network state change since last time, if so send events to modules
+ static bool network_was_down = true; // keep track of the previous state of network
+ bool network_state_changed = (network_was_down != (bool)TasmotaGlobal.global_state.network_down); // network state changed from last tick
+ network_was_down = TasmotaGlobal.global_state.network_down;
+
+ if (!TasmotaGlobal.global_state.network_down) {
#ifdef FIRMWARE_MINIMAL
#ifdef CONFIG_IDF_TARGET_ESP32C3
- if (OtaFactoryRead()) {
- OtaFactoryWrite(false);
- TasmotaGlobal.ota_state_flag = 3;
- }
+ if (OtaFactoryRead()) {
+ OtaFactoryWrite(false);
+ TasmotaGlobal.ota_state_flag = 3;
+ }
#endif
- if (1 == RtcSettings.ota_loader) {
- RtcSettings.ota_loader = 0;
- TasmotaGlobal.ota_state_flag = 3;
- }
+ if (1 == RtcSettings.ota_loader) {
+ RtcSettings.ota_loader = 0;
+ TasmotaGlobal.ota_state_flag = 3;
+ }
#endif // FIRMWARE_MINIMAL
#ifdef USE_DISCOVERY
- StartMdns();
+ StartMdns();
#endif // USE_DISCOVERY
#ifdef USE_WEBSERVER
- if (Settings->webserver) {
+ if (Settings->webserver) {
#ifdef ESP8266
- if (!WifiIsInManagerMode()) { StartWebserver(Settings->webserver, WiFi.localIP()); }
+ if (!WifiIsInManagerMode()) { StartWebserver(Settings->webserver, WiFi.localIP()); }
#endif // ESP8266
#ifdef ESP32
#ifdef USE_ETHERNET
- StartWebserver(Settings->webserver, (EthernetLocalIP()) ? EthernetLocalIP() : WiFi.localIP());
+ StartWebserver(Settings->webserver, (EthernetLocalIP()) ? EthernetLocalIP() : WiFi.localIP());
#else
- StartWebserver(Settings->webserver, WiFi.localIP());
+ StartWebserver(Settings->webserver, WiFi.localIP());
#endif
#endif // ESP32
#ifdef USE_DISCOVERY
#ifdef WEBSERVER_ADVERTISE
- MdnsAddServiceHttp();
+ MdnsAddServiceHttp();
#endif // WEBSERVER_ADVERTISE
#endif // USE_DISCOVERY
- } else {
- StopWebserver();
- }
-#ifdef USE_EMULATION
- if (Settings->flag2.emulation) { UdpConnect(); }
-#endif // USE_EMULATION
+
+ } else {
+ StopWebserver();
+ }
#endif // USE_WEBSERVER
#ifdef USE_DEVICE_GROUPS
- DeviceGroupsStart();
+ DeviceGroupsStart();
#endif // USE_DEVICE_GROUPS
-#ifdef USE_KNX
- if (!knx_started && Settings->flag.knx_enabled) { // CMND_KNX_ENABLED
- KNXStart();
- knx_started = true;
- }
-#endif // USE_KNX
+ // send FUNC_NETWORK_UP to all modules
+ if (network_state_changed) {
+ // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_UP"));
+ XdrvCall(FUNC_NETWORK_UP);
+ XsnsCall(FUNC_NETWORK_UP);
+ }
- MqttCheck();
- } else {
-#ifdef USE_EMULATION
- UdpDisconnect();
-#endif // USE_EMULATION
+ MqttCheck();
+ } else {
#ifdef USE_DEVICE_GROUPS
- DeviceGroupsStop();
+ DeviceGroupsStop();
#endif // USE_DEVICE_GROUPS
-#ifdef USE_KNX
- knx_started = false;
-#endif // USE_KNX
+ // send FUNC_NETWORK_UP to all modules
+ if (network_state_changed) {
+ // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_DOWN"));
+ XdrvCall(FUNC_NETWORK_DOWN);
+ XsnsCall(FUNC_NETWORK_DOWN);
+ }
+ } // Every x.75 second
}
break;
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 9807fd5f4..5795800d1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -1415,6 +1415,12 @@ bool Xdrv03(uint32_t function)
case FUNC_COMMAND:
result = DecodeCommand(kEnergyCommands, EnergyCommand);
break;
+ case FUNC_NETWORK_UP:
+ XnrgCall(FUNC_NETWORK_UP);
+ break;
+ case FUNC_NETWORK_DOWN:
+ XnrgCall(FUNC_NETWORK_DOWN);
+ break;
}
}
return result;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index a3d00b3f7..164e4d708 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -3428,6 +3428,12 @@ bool Xdrv04(uint32_t function)
case FUNC_BUTTON_MULTI_PRESSED:
result = XlgtCall(FUNC_BUTTON_MULTI_PRESSED);
break;
+ case FUNC_NETWORK_UP:
+ XlgtCall(FUNC_NETWORK_UP);
+ break;
+ case FUNC_NETWORK_DOWN:
+ XlgtCall(FUNC_NETWORK_DOWN);
+ break;
#ifdef USE_WEBSERVER
case FUNC_WEB_ADD_MAIN_BUTTON:
XlgtCall(FUNC_WEB_ADD_MAIN_BUTTON);
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
index b8573cb3f..04d1225d3 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_11_knx.ino
@@ -52,6 +52,8 @@ uint8_t Settings->knx_CB_param[MAX_KNX_CB] Type of Output (set relay,
#include // KNX Library
+bool knx_started = false;
+
address_t KNX_physs_addr; // Physical KNX address of this device
address_t KNX_addr; // KNX Address converter variable
@@ -1329,6 +1331,15 @@ bool Xdrv11(uint32_t function)
case FUNC_PRE_INIT:
KNX_INIT();
break;
+ case FUNC_NETWORK_UP:
+ if (!knx_started && Settings->flag.knx_enabled) { // CMND_KNX_ENABLED
+ KNXStart();
+ knx_started = true;
+ }
+ break;
+ case FUNC_NETWORK_DOWN:
+ knx_started = false;
+ break;
// case FUNC_SET_POWER:
// break;
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino b/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino
index 30db910b5..74611fa78 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_20_hue.ino
@@ -1162,6 +1162,12 @@ bool Xdrv20(uint32_t function)
case FUNC_WEB_ADD_HANDLER:
WebServer_on(PSTR("/description.xml"), HandleUpnpSetupHue);
break;
+ case FUNC_NETWORK_UP:
+ UdpConnect();
+ break;
+ case FUNC_NETWORK_DOWN:
+ UdpDisconnect();
+ break;
}
}
return result;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
index 1bcd0b9ab..0d433fbdf 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
@@ -354,6 +354,12 @@ bool Xdrv21(uint32_t function)
WebServer_on(PSTR("/metainfoservice.xml"), HandleUpnpMetaService);
WebServer_on(PSTR("/setup.xml"), HandleUpnpSetupWemo);
break;
+ case FUNC_NETWORK_UP:
+ UdpConnect();
+ break;
+ case FUNC_NETWORK_DOWN:
+ UdpDisconnect();
+ break;
}
}
return result;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
index bf242d0f4..5ceb84ac9 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
@@ -453,6 +453,12 @@ bool Xdrv21(uint32_t function)
numOfWemoSwitch++;
}
break;
+ case FUNC_NETWORK_UP:
+ UdpConnect();
+ break;
+ case FUNC_NETWORK_DOWN:
+ UdpDisconnect();
+ break;
}
}
return result;
From 0628d2f1a5205ca87b8e2f84aa42556a72919d10 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 11 Nov 2022 11:34:32 +0100
Subject: [PATCH 165/319] Use `XdrvXsnsCall`
---
tasmota/tasmota_support/support_tasmota.ino | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index a0263fc7e..f6fd5981f 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1626,8 +1626,7 @@ void Every250mSeconds(void)
// send FUNC_NETWORK_UP to all modules
if (network_state_changed) {
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_UP"));
- XdrvCall(FUNC_NETWORK_UP);
- XsnsCall(FUNC_NETWORK_UP);
+ XdrvXsnsCall(FUNC_NETWORK_UP);
}
MqttCheck();
@@ -1640,8 +1639,7 @@ void Every250mSeconds(void)
// send FUNC_NETWORK_UP to all modules
if (network_state_changed) {
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_DOWN"));
- XdrvCall(FUNC_NETWORK_DOWN);
- XsnsCall(FUNC_NETWORK_DOWN);
+ XdrvXsnsCall(FUNC_NETWORK_DOWN);
}
} // Every x.75 second
}
From 9ef0f2aa09e0ae99c8a13659e8bcd01cb1c29cca Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 11:47:11 +0100
Subject: [PATCH 166/319] Consolidate AddLogBuffer
---
tasmota/tasmota_support/support.ino | 34 +++++--------------
.../xdrv_01_9_webserver.ino | 3 +-
.../tasmota_xdrv_driver/xdrv_06_snfbridge.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_127_debug.ino | 4 +--
.../xdrv_30_exs_dimmer.ino | 9 ++---
.../xdrv_31_tasmota_client.ino | 11 +++---
.../xdrv_45_shelly_dimmer.ino | 14 +++-----
.../tasmota_xdrv_driver/xdrv_46_ccloader.ino | 2 +-
.../xdrv_57_1_tasmesh_support.ino | 5 ++-
.../tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino | 6 ++--
.../xsns_91_vindriktning.ino | 2 +-
11 files changed, 30 insertions(+), 62 deletions(-)
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index 6446a44d8..ae7cb166e 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -383,7 +383,7 @@ char* Unescape(char* buffer, uint32_t* size)
int32_t end_size = *size;
uint8_t che = 0;
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)buffer, *size);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: UnescapeIn %*_H"), *size, (uint8_t*)buffer);
while (start_size > 0) {
uint8_t ch = *read++;
@@ -427,7 +427,7 @@ char* Unescape(char* buffer, uint32_t* size)
}
*size = end_size;
*write++ = 0; // add the end string pointer reference
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)buffer, *size);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: UnescapeOut %*_H"), *size, (uint8_t*)buffer);
return buffer;
}
@@ -1479,7 +1479,7 @@ void GetInternalTemplate(void* ptr, uint32_t module, uint32_t option) {
memcpy_P(&template8, &kModules8285[module_template - TMP_WEMOS], sizeof(template8));
}
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&template8, sizeof(mytmplt8285));
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: GetInternalTemplate %*_H"), sizeof(mytmplt8285), (uint8_t *)&template8);
// template16 = GPIO 0,1,2,3,4,5,9,10,12,13,14,15,16,Adc,Flg
uint16_t template16[(sizeof(mytmplt) / 2)] = { GPIO_NONE };
@@ -1500,8 +1500,7 @@ void GetInternalTemplate(void* ptr, uint32_t module, uint32_t option) {
}
memcpy(ptr, &template16[index], size);
-// AddLog(LOG_LEVEL_DEBUG, PSTR("FNC: GetInternalTemplate option %d"), option);
-// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t *)ptr, size / 2, 2);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("FNC: GetInternalTemplate option %d, %*_V"), option, size / 2, (uint8_t *)ptr);
}
#endif // ESP8266
@@ -1528,7 +1527,7 @@ void TemplateGpios(myio *gp)
}
// 11 85 00 85 85 00 00 00 15 38 85 00 00 81
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&src, sizeof(mycfgio));
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: TemplateGpiosIn %*_H"), sizeof(mycfgio), (uint8_t *)&src);
// Expand template to physical GPIO array, j=phy_GPIO, i=template_GPIO
uint32_t j = 0;
@@ -1550,7 +1549,7 @@ void TemplateGpios(myio *gp)
}
// 11 85 00 85 85 00 00 00 00 00 00 00 15 38 85 00 00 81
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)gp, sizeof(myio));
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: TemplateGpiosOut %*_H"), sizeof(myio), (uint8_t *)gp);
}
gpio_flag ModuleFlag(void)
@@ -1757,16 +1756,14 @@ bool JsonTemplate(char* dataBuf)
}
}
-// AddLog(LOG_LEVEL_DEBUG, PSTR("TPL: Converted"));
-// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)&Settings->user_template, sizeof(Settings->user_template) / 2, 2);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("TPL: Converted %*_V"), sizeof(Settings->user_template) / 2, (uint8_t*)&Settings->user_template);
return true;
}
void TemplateJson(void)
{
-// AddLog(LOG_LEVEL_DEBUG, PSTR("TPL: Show"));
-// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)&Settings->user_template, sizeof(Settings->user_template) / 2, 2);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("TPL: Show %*_V"), sizeof(Settings->user_template) / 2, (uint8_t*)&Settings->user_template);
Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), SettingsText(SET_TEMPLATE_NAME));
for (uint32_t i = 0; i < nitems(Settings->user_template.gp.io); i++) {
@@ -2769,21 +2766,6 @@ void AddLogMissed(const char *sensor, uint32_t misses)
AddLog(LOG_LEVEL_DEBUG, PSTR("SNS: %s missed %d"), sensor, SENSOR_MAX_MISS - misses);
}
-void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32_t size) {
- char log_data[4 + (count * size * 3)];
-
- snprintf_P(log_data, sizeof(log_data), PSTR("DMP:"));
- for (uint32_t i = 0; i < count; i++) {
- if (1 == size) { // uint8_t
- snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, *(buffer));
- } else { // uint16_t
- snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X%02X"), log_data, *(buffer +1), *(buffer));
- }
- buffer += size;
- }
- AddLogData(loglevel, log_data);
-}
-
void AddLogSpi(bool hardware, uint32_t clk, uint32_t mosi, uint32_t miso) {
// Needs optimization
uint32_t enabled = (hardware) ? TasmotaGlobal.spi_enabled : TasmotaGlobal.soft_spi_enabled;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
index 83692a06c..b62176159 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
@@ -2847,8 +2847,7 @@ void HandleUploadLoop(void) {
#ifdef USE_WEB_FW_UPGRADE
else if (BUpload.active) {
// Write a block
-// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Size %d"), upload.currentSize);
-// AddLogBuffer(LOG_LEVEL_DEBUG, upload.buf, 32);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Size %d, Data '%32_H'"), upload.currentSize, upload.buf);
Web.upload_error = BUploadWriteBuffer(upload.buf, upload.currentSize);
if (Web.upload_error != 0) { return; }
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
index a928d8140..ff3a5500b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
@@ -105,7 +105,7 @@ uint32_t rf_search_and_write(uint8_t *data, size_t size) {
if (rec_end == sizeof(buf)) { return 9; } // File too large - Failed to decode RF firmware
rec_size = rec_end - rec_start;
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&buf + rec_start, rec_size);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: %*_H"), rec_size, (uint8_t*)&buf + rec_start);
err = rf_decode_and_write(buf + rec_start, rec_size);
if (err != 0) { return err; }
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino b/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino
index fe6caaf91..5a02108eb 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_127_debug.ino
@@ -659,7 +659,7 @@ void CmndI2cWrite(void)
}
if (index > 1) {
- AddLogBuffer(LOG_LEVEL_INFO, buffer, index);
+ AddLog(LOG_LEVEL_INFO, PSTR("DBG: CmndI2cWrite %*_H"), index, buffer);
Wire.beginTransmission(buffer[0]);
for (uint32_t i = 1; i < index; i++) {
@@ -698,7 +698,7 @@ void CmndI2cRead(void)
buffer[index++] = Wire.read();
}
if (index > 0) {
- AddLogBuffer(LOG_LEVEL_INFO, buffer, index);
+ AddLog(LOG_LEVEL_INFO, PSTR("DBG: CmndI2cRead %*_H"), index, buffer);
}
}
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino
index 3dfdcda73..597f3b9e6 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_30_exs_dimmer.ino
@@ -124,8 +124,7 @@ void ExsSerialSend(const uint8_t data[] = nullptr, uint16_t len = 0)
char rc;
#ifdef EXS_DEBUG
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("EXS: Tx Packet:"));
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t *)data, len);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("EXS: Tx Packet %*_H"), len, (uint8_t *)data);
#endif
while (retries)
@@ -363,8 +362,7 @@ bool ExsModuleSelected(void)
bool ExsSetChannels(void)
{
#ifdef EXS_DEBUG
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("EXS: SetChannels:"));
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t *)XdrvMailbox.data, XdrvMailbox.data_len);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("EXS: SetChannels %*_H"), XdrvMailbox.data_len, (uint8_t *)XdrvMailbox.data);
#endif
Exs.dimm[0] = ((uint8_t *)XdrvMailbox.data)[0];
@@ -456,8 +454,7 @@ void ExsSerialInput(void)
Exs.cmd_status = 0;
#ifdef EXS_DEBUG
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("EXS: CRC: 0x%02x, RX Packet:"), crc);
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t *)Exs.buffer, Exs.byte_counter);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("EXS: CRC 0x%02x, RX Packet %*_H"), crc, Exs.byte_counter, (uint8_t *)Exs.buffer);
#endif
if (Exs.buffer[0] == crc)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
index 04ede81b3..3fb9710f9 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
@@ -238,15 +238,13 @@ uint8_t TasmotaClient_receiveData(char* buffer, int size) {
}
if (255 == index) { index = 0; }
-// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: ReceiveData"));
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)buffer, index);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: ReceiveData %*_H"), index, (uint8_t*)buffer);
return index;
}
uint8_t TasmotaClient_sendBytes(uint8_t* bytes, int count) {
-// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: SendBytes"));
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&bytes, count);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: SendBytes %*_H"), count, (uint8_t*)&bytes);
TasmotaClient_Serial->write(bytes, count);
TasmotaClient_waitForSerialData(2, TASMOTA_CLIENT_TIMEOUT);
@@ -334,7 +332,7 @@ uint32_t TasmotaClient_Flash(uint8_t* data, size_t size) {
memcpy(flash_buffer, data + read, sizeof(flash_buffer));
read = read + sizeof(flash_buffer);
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)flash_buffer, 32);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: Flash %32_H"), (uint8_t*)flash_buffer);
for (uint32_t ca = 0; ca < sizeof(flash_buffer); ca++) {
processed++;
@@ -456,8 +454,7 @@ void TasmotaClient_sendCmnd(uint8_t cmnd, uint8_t param) {
memcpy(&buffer[1], &TClientCommand, sizeof(TClientCommand));
buffer[sizeof(TClientCommand)+1] = CMND_END;
-// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: SendCmnd"));
-// AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)&buffer, sizeof(buffer));
+// AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: SendCmnd %*_H"), sizeof(buffer), (uint8_t*)&buffer);
for (uint32_t ca = 0; ca < sizeof(buffer); ca++) {
TasmotaClient_Serial->write(buffer[ca]);
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino
index 6476fa172..4b157ac6e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_45_shelly_dimmer.ino
@@ -268,8 +268,7 @@ bool ShdSerialSend(const uint8_t data[] = nullptr, uint16_t len = 0)
int retries = 3;
#ifdef SHELLY_DIMMER_DEBUG
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(SHD_LOGNAME "Tx Packet:"));
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)data, len);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(SHD_LOGNAME "Tx Packet %*_H"), len, (uint8_t*)data);
#endif // SHELLY_DIMMER_DEBUG
while (retries--)
@@ -694,8 +693,7 @@ bool ShdSerialInput(void)
// finished
#ifdef SHELLY_DIMMER_DEBUG
Shd.byte_counter++;
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(SHD_LOGNAME "Rx Packet:"));
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Shd.buffer, Shd.byte_counter);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(SHD_LOGNAME "Rx Packet %*_H"), Shd.byte_counter, Shd.buffer);
#endif // SHELLY_DIMMER_DEBUG
Shd.byte_counter = 0;
@@ -707,9 +705,8 @@ bool ShdSerialInput(void)
{
// wrong data
#ifdef SHELLY_DIMMER_DEBUG
- AddLog(LOG_LEVEL_DEBUG, PSTR(SHD_LOGNAME "Byte %i of received data frame is invalid. Rx Packet:"), Shd.byte_counter);
- Shd.byte_counter++;
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Shd.buffer, Shd.byte_counter);
+ AddLog(LOG_LEVEL_DEBUG, PSTR(SHD_LOGNAME "Byte %i of received data frame is invalid. Rx Packet %*_H"),
+ Shd.byte_counter, Shd.byte_counter +1, Shd.buffer);
#endif // SHELLY_DIMMER_DEBUG
Shd.byte_counter = 0;
}
@@ -739,8 +736,7 @@ bool ShdModuleSelected(void) {
bool ShdSetChannels(void)
{
#ifdef SHELLY_DIMMER_DEBUG
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(SHD_LOGNAME "SetChannels:"));
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t *)XdrvMailbox.data, XdrvMailbox.data_len);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(SHD_LOGNAME "SetChannels %*_H"), XdrvMailbox.data_len, (uint8_t *)XdrvMailbox.data);
#endif // SHELLY_DIMMER_DEBUG
uint16_t brightness = ((uint32_t *)XdrvMailbox.data)[0];
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino b/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
index ab37d271a..6b0bf7c75 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
@@ -614,7 +614,7 @@ bool CLLFlashFirmware(uint8_t* data, uint32_t size)
uint32_t block = 0;
unsigned int addr = 0x0000;
AddLog(LOG_LEVEL_INFO,PSTR("CCL: will flash ...."));
- AddLogBuffer(LOG_LEVEL_DEBUG,data,16); // quick check to compare with a hex editor
+ AddLog(LOG_LEVEL_DEBUG,PSTR("CCL: data %16_H"), data); // quick check to compare with a hex editor
while((block*512)chunkSize;
char _tag[16];
-// AddLog(LOG_LEVEL_DEBUG, PSTR("cc: %u, _size: %u"), _counter,_size);
-// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*)_tag,16);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: cc %u, _size %u, _tag %16_H"), _counter,_size,(uint8_t*)_tag);
br_chacha20_run bc = br_chacha20_ct_run;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino b/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino
index 5395da2f7..b6cc16812 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino
@@ -65,8 +65,7 @@ void CB_MESHDataReceived(const uint8_t *MAC, const uint8_t *packet, int len) {
MESHencryptPayload(_recvPacket, 0); //decrypt it and check
if (memcmp(_recvPacket->payload, MESH.broker, 6) == 0) {
MESHaddPeer((uint8_t*)MAC);
-// AddLog(LOG_LEVEL_INFO, PSTR("MSH: Rcvd topic %s"), (char*)_recvPacket->payload + 6);
-// AddLogBuffer(LOG_LEVEL_INFO,(uint8_t *)&MESH.packetToConsume.front().payload,MESH.packetToConsume.front().chunkSize+5);
+// AddLog(LOG_LEVEL_INFO, PSTR("MSH: Rcvd topic %s, payload %*_H"), (char*)_recvPacket->payload + 6, MESH.packetToConsume.front().chunkSize+5, (uint8_t *)&MESH.packetToConsume.front().payload);
for (auto &_peer : MESH.peers) {
if (memcmp(_peer.MAC, _recvPacket->sender, 6) == 0) {
strcpy(_peer.topic, (char*)_recvPacket->payload + 6);
@@ -340,8 +339,7 @@ bool MESHrouteMQTTtoMESH(const char* _topic, char* _data, bool _retained) {
}
MESH.sendPacket.chunkSize += _byteLeftInChunk;
MESH.packetToResend.push(MESH.sendPacket);
-// AddLog(LOG_LEVEL_INFO, PSTR("MSH: chunk:%u, size: %u"),MESH.sendPacket.chunk,MESH.sendPacket.chunkSize);
-// AddLogBuffer(LOG_LEVEL_INFO, (uint8_t*)MESH.sendPacket.payload, MESH.sendPacket.chunkSize);
+// AddLog(LOG_LEVEL_INFO, PSTR("MSH: chunk %u, size %u, payload %*_H"),MESH.sendPacket.chunk,MESH.sendPacket.chunkSize,MESH.sendPacket.chunkSize,(uint8_t*)MESH.sendPacket.payload);
if (MESH.sendPacket.chunk == MESH.sendPacket.chunks) {
// AddLog(LOG_LEVEL_INFO, PSTR("MSH: Too many chunks %u"), MESH.sendPacket.chunk +1);
}
diff --git a/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino b/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
index 3248ea7f6..c6e16c204 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
@@ -64,7 +64,7 @@ bool VindriktningReadData(void) {
VindriktningSerial->readBytes(buffer, VINDRIKTNING_DATASET_SIZE);
VindriktningSerial->flush(); // Make room for another burst
- AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, VINDRIKTNING_DATASET_SIZE);
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("VDN: %*_H"), VINDRIKTNING_DATASET_SIZE, buffer);
uint8_t crc = 0;
for (uint32_t i = 0; i < VINDRIKTNING_DATASET_SIZE; i++) {
From 3d6bc2f8420e9f17ee80632ea7e6f24c3874e445 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 12:10:10 +0100
Subject: [PATCH 167/319] Update API.md
---
API.md | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/API.md b/API.md
index 2dbc5c555..9e5d51a5b 100644
--- a/API.md
+++ b/API.md
@@ -14,20 +14,24 @@ Callback Id | Bool | xdrv | xsns | xnrg | xlgt | Description
----------------------------|------|------|------|------|------|----------------------------------
FUNC_SETTINGS_OVERRIDE | | x | | | | Override start-up settings
FUNC_PIN_STATE | x | 1 | 2 | | | At GPIO configuration
+FUNC_I2C_INIT | | x | | | | Immediatly after I2C init
FUNC_MODULE_INIT | x | 3 | 1 | | 2 | Init module specific parameters
FUNC_PRE_INIT | | 1 | 3 | 2 | | Once GPIO have been established
FUNC_INIT | | 1 | 3 | 2 | | At end of initialisation
FUNC_LOOP | | 1 | 2 | | | In main loop
-FUNC_EVERY_50_MSECOND | | 1 | 2 | | |
-FUNC_EVERY_100_MSECOND | | 1 | 2 | | |
-FUNC_EVERY_200_MSECOND | | | | x | |
-FUNC_EVERY_250_MSECOND | | 1 | 3 | 2 | |
-FUNC_EVERY_SECOND | | 1 | 2 | | |
+FUNC_SLEEP_LOOP | | 1 | 2 | | | In main loop during sleep
+FUNC_EVERY_50_MSECOND | | 1 | 2 | | | In main loop
+FUNC_EVERY_100_MSECOND | | 1 | 2 | | | In main loop
+FUNC_EVERY_200_MSECOND | | | | x | | In main loop
+FUNC_EVERY_250_MSECOND | | 1 | 3 | 2 | | In main loop
+FUNC_EVERY_SECOND | | 1 | 2 | | | In main loop
+FUNC_SAVE_SETTINGS | | 2 | 1 | | | Just before saving settings
FUNC_SAVE_AT_MIDNIGHT | | | x | | | At midnight
FUNC_SAVE_BEFORE_RESTART | | 2 | 1 | | | Just before a planned restart
FUNC_AFTER_TELEPERIOD | | 2 | 1 | | | At end of teleperiod
FUNC_JSON_APPEND | | 2 | 1 | 3 | | Extend teleperiod JSON text
FUNC_WEB_SENSOR | | 2 | 1 | 3 | | Add sensor data to web GUI
+FUNC_WEB_COL_SENSOR | | 2 | 1 | 3 | | Add sensor data to web GUI using columns
FUNC_COMMAND | x | 1 | 2 | 3 | 4 | When a command is not recognized
FUNC_COMMAND_DRIVER | x | x | | | | When command Driver\ is executed
FUNC_COMMAND_SENSOR | x | | x | | | When command Sensor\ is executed
@@ -38,18 +42,25 @@ FUNC_SET_POWER | | 1 | 2 | | | Before setting
FUNC_SET_DEVICE_POWER | x | x | | | | Set relay
FUNC_SHOW_SENSOR | | x | | | | When FUNC_JSON_APPEND completes
FUNC_ANY_KEY | | x | | | |
+FUNC_LED_LINK | | x | | | | SetLedLink (On ESP32 only). XdrvMailbox.index holds state
FUNC_ENERGY_EVERY_SECOND | | | | x | |
FUNC_ENERGY_RESET | | | | x | |
FUNC_RULES_PROCESS | x | x | | | | Process specific rule
+FUNC_TELEPERIOD_RULES_PROCESS | x | x | | | | Process specific rule as teleperiod
FUNC_SERIAL | x | 1 | | 2 | 3 | Process serial data
FUNC_FREE_MEM | | x | | | | Show free memory for debugging
FUNC_BUTTON_PRESSED | x | x | | | | When a button is pressed
+FUNC_BUTTON_MULTI_PRESSED | x | x | | | | When a button is pressed multiple times
FUNC_WEB_ADD_BUTTON | | 1 | 2 | | | Add a Configuration Button to GUI
FUNC_WEB_ADD_MAIN_BUTTON | | 1 | 2 | | | Add a main button to GUI
+FUNC_WEB_ADD_CONSOLE_BUTTON | | 1 | 2 | | | Add a Consoles Button to GUI
+FUNC_WEB_ADD_MANAGEMENT_BUTTON | | x | | | | Add a Management Button to GUI
FUNC_WEB_ADD_HANDLER | | 1 | 2 | | | Add a webserver handler
+FUNC_WEB_GET_ARG | | 2 | 1 | | 3 | Get webserver setting arguments
FUNC_SET_CHANNELS | | 2 | | | 1 |
FUNC_SET_SCHEME | | | | | x |
FUNC_HOTPLUG_SCAN | | | x | | |
+FUNC_TIME_SYNCED | | x | | | | Report time is synced
FUNC_DEVICE_GROUP_ITEM | | x | | | |
FUNC_NETWORK_UP | | 1 | 2 | 3 | 4 | Wifi or ETH network just went up (received even if webserver is not enabled)
FUNC_NETWORK_DOWN | | 1 | 2 | 3 | 4 | Wifi or ETH network just went down (received even if webserver is not enabled)
From 9b64c4eb4c7bb30432fc375f7b124a2141f6e739 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 14:34:58 +0100
Subject: [PATCH 168/319] Refactor some logging
---
tasmota/tasmota_support/support.ino | 8 +++-----
.../tasmota_xdrv_driver/xdrv_06_snfbridge.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino | 5 ++---
.../tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_46_ccloader.ino | 2 +-
.../tasmota_xdrv_driver/xdrv_57_9_tasmesh.ino | 17 +++++++----------
.../xsns_91_vindriktning.ino | 2 +-
7 files changed, 16 insertions(+), 22 deletions(-)
diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino
index ae7cb166e..bb92157b6 100755
--- a/tasmota/tasmota_support/support.ino
+++ b/tasmota/tasmota_support/support.ino
@@ -2750,15 +2750,13 @@ void AddLog(uint32_t loglevel, PGM_P formatP, ...) {
}
}
-void AddLogBuffer(uint32_t loglevel, uint8_t *buffer, uint32_t count)
-{
+void AddLogBuffer(uint32_t loglevel, uint8_t *buffer, uint32_t count) {
char hex_char[(count * 3) + 2];
AddLog(loglevel, PSTR("DMP: %s"), ToHex_P(buffer, count, hex_char, sizeof(hex_char), ' '));
}
-void AddLogSerial(uint32_t loglevel)
-{
- AddLogBuffer(loglevel, (uint8_t*)TasmotaGlobal.serial_in_buffer, TasmotaGlobal.serial_in_byte_counter);
+void AddLogSerial() {
+ AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t*)TasmotaGlobal.serial_in_buffer, TasmotaGlobal.serial_in_byte_counter);
}
void AddLogMissed(const char *sensor, uint32_t misses)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
index ff3a5500b..cf62932b4 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_06_snfbridge.ino
@@ -197,7 +197,7 @@ void SonoffBridgeReceived(void)
char rfkey[8];
char stemp[16];
- AddLogSerial(LOG_LEVEL_DEBUG);
+ AddLogSerial();
if (0xA2 == TasmotaGlobal.serial_in_buffer[0]) { // Learn timeout
SonoffBridgeLearnFailed();
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino b/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino
index 618cda1ab..6cf5da0c5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_22_sonoff_ifan.ino
@@ -174,7 +174,7 @@ bool SonoffIfanSerialInput(void)
// AA 55 01 04 00 01 04 0A - Light
// AA 55 01 06 00 01 01 09 - Buzzer
// AA 55 01 07 00 01 01 0A - Rf long press - forget RF codes
- AddLogSerial(LOG_LEVEL_DEBUG);
+ AddLogSerial();
uint8_t crc = 0;
for (uint32_t i = 2; i < 7; i++) {
crc += TasmotaGlobal.serial_in_buffer[i];
@@ -244,8 +244,7 @@ void SonoffIfanUpdate(void)
* Interface
\*********************************************************************************************/
-bool Xdrv22(uint32_t function)
-{
+bool Xdrv22(uint32_t function) {
bool result = false;
if (IsModuleIfan()) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino b/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino
index adc34e0bf..fde6dc1c9 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_37_sonoff_d1.ino
@@ -99,7 +99,7 @@ bool SonoffD1SerialInput(void)
// aa 55 01 04 00 0a 00 64 ff ff ff ff ff ff ff ff 6b - Power Off (with last dimmer 100%)
// aa 55 01 04 00 0a 01 64 ff ff ff ff ff ff ff ff 6c - Power On (with last dimmer 100%)
- AddLogSerial(LOG_LEVEL_DEBUG);
+ AddLogSerial();
uint8_t crc = 0;
for (uint32_t i = 2; i < SnfD1.receive_len -1; i++) {
crc += TasmotaGlobal.serial_in_buffer[i];
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino b/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
index 6b0bf7c75..ab37d271a 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_46_ccloader.ino
@@ -614,7 +614,7 @@ bool CLLFlashFirmware(uint8_t* data, uint32_t size)
uint32_t block = 0;
unsigned int addr = 0x0000;
AddLog(LOG_LEVEL_INFO,PSTR("CCL: will flash ...."));
- AddLog(LOG_LEVEL_DEBUG,PSTR("CCL: data %16_H"), data); // quick check to compare with a hex editor
+ AddLogBuffer(LOG_LEVEL_DEBUG,data,16); // quick check to compare with a hex editor
while((block*512) 0) {
-// AddLog(LOG_LEVEL_DEBUG, PSTR("_"));
-// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t *)&MESH.packetToConsume.front(), 15);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: _ %15_H"), (uint8_t *)&MESH.packetToConsume.front());
for (auto &_headerBytes : MESH.packetsAlreadyReceived) {
-// AddLog(LOG_LEVEL_DEBUG, PSTR("."));
-// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t *)_headerBytes.raw, 15);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: . %15_H"), (uint8_t *)_headerBytes.raw);
if (memcmp(MESH.packetToConsume.front().sender, _headerBytes.raw, 15) == 0) {
MESH.packetToConsume.pop();
return;
@@ -465,21 +463,20 @@ void MESHevery50MSecond(void) {
mesh_first_header_bytes _bytes;
memcpy(_bytes.raw, &MESH.packetToConsume.front(), 15);
MESH.packetsAlreadyReceived.push_back(_bytes);
-// AddLog(LOG_LEVEL_DEBUG, PSTR("..."));
-// AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t *)_bytes.raw, 15);
+// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: ... %15_H"), (uint8_t *)_bytes.raw);
if (MESH.packetsAlreadyReceived.size() > MESH_MAX_PACKETS) {
MESH.packetsAlreadyReceived.erase(MESH.packetsAlreadyReceived.begin());
// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: Erase received data"));
}
// do something on the node
- // AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t *)&MESH.packetToConsume.front(), 30);
+ // AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: %30_H), (uint8_t *)&MESH.packetToConsume.front());
MESHencryptPayload(&MESH.packetToConsume.front(), 0);
switch (MESH.packetToConsume.front().type) {
// case PACKET_TYPE_REGISTER_NODE:
// AddLog(LOG_LEVEL_INFO, PSTR("MSH: received topic: %s"), (char*)MESH.packetToConsume.front().payload + 6);
- // // AddLogBuffer(LOG_LEVEL_INFO,(uint8_t *)&MESH.packetToConsume.front().payload,MESH.packetToConsume.front().chunkSize+5);
+ // // AddLog(LOG_LEVEL_INFO, PSTR("MSH: %*_H), MESH.packetToConsume.front().chunkSize+5, (uint8_t *)&MESH.packetToConsume.front().payload);
// for(auto &_peer : MESH.peers){
// if(memcmp(_peer.MAC,MESH.packetToConsume.front().sender,6)==0){
// strcpy(_peer.topic,(char*)MESH.packetToConsume.front().payload+6);
@@ -532,7 +529,7 @@ void MESHevery50MSecond(void) {
}
} else {
// AddLog(LOG_LEVEL_INFO, PSTR("MSH: chunk: %u size: %u"), MESH.packetToConsume.front().chunk, MESH.packetToConsume.front().chunkSize);
-// if (MESH.packetToConsume.front().chunk==0) AddLogBuffer(LOG_LEVEL_INFO,(uint8_t *)&MESH.packetToConsume.front().payload,MESH.packetToConsume.front().chunkSize);
+// if (MESH.packetToConsume.front().chunk==0) AddLog(LOG_LEVEL_INFO, PSTR("MSH: %*_H), MESH.packetToConsume.front().chunkSize, (uint8_t *)&MESH.packetToConsume.front().payload);
char * _data = (char*)MESH.packetToConsume.front().payload + strlen((char*)MESH.packetToConsume.front().payload) +1;
// AddLog(LOG_LEVEL_DEBUG, PSTR("MSH: Publish packet"));
MqttPublishPayload((char*)MESH.packetToConsume.front().payload, _data);
@@ -546,7 +543,7 @@ void MESHevery50MSecond(void) {
}
idx++;
}
-// AddLogBuffer(LOG_LEVEL_INFO,(uint8_t *)&MESH.packetToConsume.front().payload,MESH.packetToConsume.front().chunkSize);
+// AddLog(LOG_LEVEL_INFO, PSTR("MSH: %*_H), MESH.packetToConsume.front().chunkSize, (uint8_t *)&MESH.packetToConsume.front().payload);
}
break;
default:
diff --git a/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino b/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
index c6e16c204..3248ea7f6 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_91_vindriktning.ino
@@ -64,7 +64,7 @@ bool VindriktningReadData(void) {
VindriktningSerial->readBytes(buffer, VINDRIKTNING_DATASET_SIZE);
VindriktningSerial->flush(); // Make room for another burst
- AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("VDN: %*_H"), VINDRIKTNING_DATASET_SIZE, buffer);
+ AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, VINDRIKTNING_DATASET_SIZE);
uint8_t crc = 0;
for (uint32_t i = 0; i < VINDRIKTNING_DATASET_SIZE; i++) {
From 50b0a983b2631dd7051f62173ab063dad63f7827 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 11 Nov 2022 16:10:39 +0100
Subject: [PATCH 169/319] Add uart info
---
tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino | 3 +++
tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino | 3 +++
2 files changed, 6 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index bcc34a4a8..09939591c 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -189,6 +189,9 @@ void SerialBridgeInit(void) {
}
SerialBridgeSerial->flush();
SerialBridgePrintf("\r\n");
+#ifdef ESP32
+ AddLog(LOG_LEVEL_DEBUG, PSTR("SBR: Serial UART%d"), SerialBridgeSerial->getUart());
+#endif
}
}
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
index 3fb9710f9..d15900189 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_31_tasmota_client.ino
@@ -399,6 +399,9 @@ void TasmotaClient_Init(void) {
if (TasmotaClient_Serial->hardwareSerial()) {
ClaimSerial();
}
+#ifdef ESP32
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TCL: Serial UART%d"), TasmotaClient_Serial->getUart());
+#endif
if (PinUsed(GPIO_TASMOTACLIENT_RST_INV)) {
SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), AGPIO(GPIO_TASMOTACLIENT_RST));
TClient.inverted = HIGH;
From 25be8709cf53259abb7fceb3ce7daef1ecf8839a Mon Sep 17 00:00:00 2001
From: Thomas Hargrove
Date: Fri, 11 Nov 2022 12:03:28 -0800
Subject: [PATCH 170/319] Shave off the leftmost pixel of the 7 segment font
---
.../src/font24_7seg.c | 1352 ++++++++---------
1 file changed, 676 insertions(+), 676 deletions(-)
diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c b/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c
index 1844fc6cf..645caa9d4 100644
--- a/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c
+++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c
@@ -41,712 +41,712 @@
const uint8_t Font24_Table_7seg [] PROGMEM =
{
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+ // @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @72 '!' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x01,0x00,0x00, // #
- 0x01,0x00,0x00, // #
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @72 '!' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x02,0x00, // #
+0x02,0x00, // #
+0x00,0x00, //
+0x00,0x00, //
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @144 '"' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x0e,0x70,0x00, // ### ###
- 0x0e,0x70,0x00, // ### ###
- 0x0e,0x70,0x00, // ### ###
- 0x04,0x20,0x00, // # #
- 0x04,0x20,0x00, // # #
- 0x04,0x20,0x00, // # #
- 0x04,0x20,0x00, // # #
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @144 '"' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x1C,0xE0, // ### ###
+0x1C,0xE0, // ### ###
+0x1C,0xE0, // ### ###
+0x08,0x40, // # #
+0x08,0x40, // # #
+0x08,0x40, // # #
+0x08,0x40, // # #
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @216 '#' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x06,0x60,0x00, // ## ##
- 0x06,0x60,0x00, // ## ##
- 0x06,0x60,0x00, // ## ##
- 0x06,0x60,0x00, // ## ##
- 0x06,0x60,0x00, // ## ##
- 0x3f,0xf8,0x00, // ###########
- 0x3f,0xf8,0x00, // ###########
- 0x06,0x60,0x00, // ## ##
- 0x0c,0xc0,0x00, // ## ##
- 0x3f,0xf8,0x00, // ###########
- 0x3f,0xf8,0x00, // ###########
- 0x0c,0xc0,0x00, // ## ##
- 0x0c,0xc0,0x00, // ## ##
- 0x0c,0xc0,0x00, // ## ##
- 0x0c,0xc0,0x00, // ## ##
- 0x0c,0xc0,0x00, // ## ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @216 '#' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x0C,0xC0, // ## ##
+0x0C,0xC0, // ## ##
+0x0C,0xC0, // ## ##
+0x0C,0xC0, // ## ##
+0x0C,0xC0, // ## ##
+0x7F,0xF0, // ###########
+0x7F,0xF0, // ###########
+0x0C,0xC0, // ## ##
+0x19,0x80, // ## ##
+0x7F,0xF0, // ###########
+0x7F,0xF0, // ###########
+0x19,0x80, // ## ##
+0x19,0x80, // ## ##
+0x19,0x80, // ## ##
+0x19,0x80, // ## ##
+0x19,0x80, // ## ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @288 '$' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x07,0xb0,0x00, // #### ##
- 0x0f,0xf0,0x00, // ########
- 0x18,0x70,0x00, // ## ###
- 0x18,0x70,0x00, // ## ###
- 0x1c,0x00,0x00, // ###
- 0x0f,0x80,0x00, // #####
- 0x07,0xe0,0x00, // ######
- 0x00,0xf0,0x00, // ####
- 0x18,0x30,0x00, // ## ##
- 0x1c,0x30,0x00, // ### ##
- 0x1c,0x70,0x00, // ### ###
- 0x1f,0xe0,0x00, // ########
- 0x1b,0xc0,0x00, // ## ####
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @288 '$' (16 pixels wide)
+0x00,0x00, //
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x0F,0x60, // #### ##
+0x1F,0xE0, // ########
+0x30,0xE0, // ## ###
+0x30,0xE0, // ## ###
+0x38,0x00, // ###
+0x1F,0x00, // #####
+0x0F,0xC0, // ######
+0x01,0xE0, // ####
+0x30,0x60, // ## ##
+0x38,0x60, // ### ##
+0x38,0xE0, // ### ###
+0x3F,0xC0, // ########
+0x37,0x80, // ## ####
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @360 '%' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x07,0x80,0x00, // ####
- 0x0f,0xc0,0x00, // ######
- 0x1c,0xe0,0x00, // ### ###
- 0x18,0x60,0x00, // ## ##
- 0x18,0x60,0x00, // ## ##
- 0x1c,0xe0,0x00, // ### ###
- 0x0f,0xf8,0x00, // #########
- 0x07,0xe0,0x00, // ######
- 0x1f,0xf0,0x00, // #########
- 0x07,0x38,0x00, // ### ###
- 0x06,0x18,0x00, // ## ##
- 0x06,0x18,0x00, // ## ##
- 0x07,0x38,0x00, // ### ###
- 0x03,0xf0,0x00, // ######
- 0x01,0xe0,0x00, // ####
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @360 '%' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x0F,0x00, // ####
+0x1F,0x80, // ######
+0x39,0xC0, // ### ###
+0x30,0xC0, // ## ##
+0x30,0xC0, // ## ##
+0x39,0xC0, // ### ###
+0x1F,0xF0, // #########
+0x0F,0xC0, // ######
+0x3F,0xE0, // #########
+0x0E,0x70, // ### ###
+0x0C,0x30, // ## ##
+0x0C,0x30, // ## ##
+0x0E,0x70, // ### ###
+0x07,0xE0, // ######
+0x03,0xC0, // ####
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @432 '&' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x03,0xf0,0x00, // ######
- 0x07,0xf0,0x00, // #######
- 0x0c,0x60,0x00, // ## ##
- 0x0c,0x00,0x00, // ##
- 0x0c,0x00,0x00, // ##
- 0x06,0x00,0x00, // ##
- 0x07,0x00,0x00, // ###
- 0x0f,0x9c,0x00, // ##### ###
- 0x1d,0xfc,0x00, // ### #######
- 0x18,0xf0,0x00, // ## ####
- 0x18,0x70,0x00, // ## ###
- 0x0f,0xfc,0x00, // ##########
- 0x07,0xdc,0x00, // ##### ###
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @432 '&' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x07,0xE0, // ######
+0x0F,0xE0, // #######
+0x18,0xC0, // ## ##
+0x18,0x00, // ##
+0x18,0x00, // ##
+0x0C,0x00, // ##
+0x0E,0x00, // ###
+0x1F,0x38, // ##### ###
+0x3B,0xF8, // ### #######
+0x31,0xE0, // ## ####
+0x30,0xE0, // ## ###
+0x1F,0xF8, // ##########
+0x0F,0xB8, // ##### ###
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @504 ''' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x01,0x00,0x00, // #
- 0x01,0x00,0x00, // #
- 0x01,0x00,0x00, // #
- 0x01,0x00,0x00, // #
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @504 ''' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x02,0x00, // #
+0x02,0x00, // #
+0x02,0x00, // #
+0x02,0x00, // #
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @576 '(' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x18,0x00, // ##
- 0x00,0x38,0x00, // ###
- 0x00,0x70,0x00, // ###
- 0x00,0xf0,0x00, // ####
- 0x00,0xe0,0x00, // ###
- 0x00,0xe0,0x00, // ###
- 0x01,0xc0,0x00, // ###
- 0x01,0xc0,0x00, // ###
- 0x01,0xc0,0x00, // ###
- 0x01,0xc0,0x00, // ###
- 0x01,0xc0,0x00, // ###
- 0x01,0xc0,0x00, // ###
- 0x00,0xe0,0x00, // ###
- 0x00,0xe0,0x00, // ###
- 0x00,0x70,0x00, // ###
- 0x00,0x70,0x00, // ###
- 0x00,0x38,0x00, // ###
- 0x00,0x18,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @576 '(' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x30, // ##
+0x00,0x70, // ###
+0x00,0xE0, // ###
+0x01,0xE0, // ####
+0x01,0xC0, // ###
+0x01,0xC0, // ###
+0x03,0x80, // ###
+0x03,0x80, // ###
+0x03,0x80, // ###
+0x03,0x80, // ###
+0x03,0x80, // ###
+0x03,0x80, // ###
+0x01,0xC0, // ###
+0x01,0xC0, // ###
+0x00,0xE0, // ###
+0x00,0xE0, // ###
+0x00,0x70, // ###
+0x00,0x30, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @648 ')' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x18,0x00,0x00, // ##
- 0x1c,0x00,0x00, // ###
- 0x0e,0x00,0x00, // ###
- 0x0e,0x00,0x00, // ###
- 0x07,0x00,0x00, // ###
- 0x07,0x00,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x03,0x80,0x00, // ###
- 0x07,0x00,0x00, // ###
- 0x07,0x00,0x00, // ###
- 0x0f,0x00,0x00, // ####
- 0x0e,0x00,0x00, // ###
- 0x1c,0x00,0x00, // ###
- 0x18,0x00,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @648 ')' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x30,0x00, // ##
+0x38,0x00, // ###
+0x1C,0x00, // ###
+0x1C,0x00, // ###
+0x0E,0x00, // ###
+0x0E,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x07,0x00, // ###
+0x0E,0x00, // ###
+0x0E,0x00, // ###
+0x1E,0x00, // ####
+0x1C,0x00, // ###
+0x38,0x00, // ###
+0x30,0x00, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @720 '*' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x1d,0xb8,0x00, // ### ## ###
- 0x1f,0xf8,0x00, // ##########
- 0x07,0xe0,0x00, // ######
- 0x03,0xc0,0x00, // ####
- 0x03,0xc0,0x00, // ####
- 0x06,0x60,0x00, // ## ##
- 0x06,0x60,0x00, // ## ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @720 '*' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x3B,0x70, // ### ## ###
+0x3F,0xF0, // ##########
+0x0F,0xC0, // ######
+0x07,0x80, // ####
+0x07,0x80, // ####
+0x0C,0xC0, // ## ##
+0x0C,0xC0, // ## ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @792 '+' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x3f,0xfc,0x00, // ############
- 0x3f,0xfc,0x00, // ############
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @792 '+' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x7F,0xF8, // ############
+0x7F,0xF8, // ############
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @864 ',' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0xe0,0x00, // ###
- 0x00,0xc0,0x00, // ##
- 0x01,0xc0,0x00, // ###
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x03,0x00,0x00, // ##
- 0x03,0x00,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @864 ',' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x01,0xC0, // ###
+0x01,0x80, // ##
+0x03,0x80, // ###
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x06,0x00, // ##
+0x06,0x00, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @936 '-' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x1f,0xf8,0x00, // ##########
- 0x1f,0xf8,0x00, // ##########
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @936 '-' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x3F,0xF0, // ##########
+0x3F,0xF0, // ##########
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @1008 '.' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x03,0xc0,0x00, // ####
- 0x03,0xc0,0x00, // ####
- 0x03,0xc0,0x00, // ####
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @1008 ' ' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x07,0x80, // ####
+0x07,0x80, // ####
+0x07,0x80, // ####
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @1080 '/' (17 pixels wide)
- 0x00,0x18,0x00, // ##
- 0x00,0x18,0x00, // ##
- 0x00,0x38,0x00, // ###
- 0x00,0x30,0x00, // ##
- 0x00,0x70,0x00, // ###
- 0x00,0x60,0x00, // ##
- 0x00,0x60,0x00, // ##
- 0x00,0xc0,0x00, // ##
- 0x00,0xc0,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x01,0x80,0x00, // ##
- 0x03,0x00,0x00, // ##
- 0x03,0x00,0x00, // ##
- 0x06,0x00,0x00, // ##
- 0x06,0x00,0x00, // ##
- 0x0e,0x00,0x00, // ###
- 0x0c,0x00,0x00, // ##
- 0x1c,0x00,0x00, // ###
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @1080 '/' (16 pixels wide)
+0x00,0x30, // ##
+0x00,0x30, // ##
+0x00,0x70, // ###
+0x00,0x60, // ##
+0x00,0xE0, // ###
+0x00,0xC0, // ##
+0x00,0xC0, // ##
+0x01,0x80, // ##
+0x01,0x80, // ##
+0x03,0x00, // ##
+0x03,0x00, // ##
+0x06,0x00, // ##
+0x06,0x00, // ##
+0x0C,0x00, // ##
+0x0C,0x00, // ##
+0x1C,0x00, // ###
+0x18,0x00, // ##
+0x38,0x00, // ###
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x00,0x00, //
+0x00,0x00, //
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x00, //
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x00, //
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x18,0x00,0x00, // ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x0f,0xfc,0x00, // ##########
- 0x0f,0xfc,0x00, // ##########
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x30,0x00, // ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x1F,0xF8, // ##########
+0x1F,0xF8, // ##########
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x0f,0xfc,0x00, // ##########
- 0x0f,0xfc,0x00, // ##########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x1F,0xF8, // ##########
+0x1F,0xF8, // ##########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x00, //
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x00, //
- // @0 ' ' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x18,0x03,0x00, // ## ##
- 0x07,0xfc,0x00, // #########
- 0x07,0xfc,0x00, // #########
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x03,0x00, // ##
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
+// @0 ' ' (16 pixels wide)
+0x00,0x00, //
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x30,0x06, // ## ##
+0x0F,0xF8, // #########
+0x0F,0xF8, // #########
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x06, // ##
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
- // @1872 ':' (17 pixels wide)
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0xf0,0x00, // ####
- 0x00,0xf0,0x00, // ####
- 0x00,0xf0,0x00, // ####
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0xf0,0x00, // ####
- 0x00,0xf0,0x00, // ####
- 0x00,0xf0,0x00, // ####
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00, //
- 0x00,0x00,0x00 //
+// @1872 ':' (16 pixels wide)
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x01,0xE0, // ####
+0x01,0xE0, // ####
+0x01,0xE0, // ####
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x01,0xE0, // ####
+0x01,0xE0, // ####
+0x01,0xE0, // ####
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00, //
+0x00,0x00 //
};
sFONT Font24_7seg = {
Font24_Table_7seg,
- 17, /* Width */
+ 16, /* Width */
24, /* Height */
};
From 066b98fe784948d2225c6800168314a6d6bee01d Mon Sep 17 00:00:00 2001
From: Thomas Hargrove
Date: Fri, 11 Nov 2022 12:06:44 -0800
Subject: [PATCH 171/319] re-add tab
---
.../src/font24_7seg.c | 1296 ++++++++---------
1 file changed, 648 insertions(+), 648 deletions(-)
diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c b/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c
index 645caa9d4..a4d740b09 100644
--- a/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c
+++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/font24_7seg.c
@@ -42,706 +42,706 @@
const uint8_t Font24_Table_7seg [] PROGMEM =
{
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @72 '!' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x02,0x00, // #
-0x02,0x00, // #
-0x00,0x00, //
-0x00,0x00, //
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x02,0x00, // #
+ 0x02,0x00, // #
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @144 '"' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x1C,0xE0, // ### ###
-0x1C,0xE0, // ### ###
-0x1C,0xE0, // ### ###
-0x08,0x40, // # #
-0x08,0x40, // # #
-0x08,0x40, // # #
-0x08,0x40, // # #
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x1C,0xE0, // ### ###
+ 0x1C,0xE0, // ### ###
+ 0x1C,0xE0, // ### ###
+ 0x08,0x40, // # #
+ 0x08,0x40, // # #
+ 0x08,0x40, // # #
+ 0x08,0x40, // # #
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @216 '#' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x0C,0xC0, // ## ##
-0x0C,0xC0, // ## ##
-0x0C,0xC0, // ## ##
-0x0C,0xC0, // ## ##
-0x0C,0xC0, // ## ##
-0x7F,0xF0, // ###########
-0x7F,0xF0, // ###########
-0x0C,0xC0, // ## ##
-0x19,0x80, // ## ##
-0x7F,0xF0, // ###########
-0x7F,0xF0, // ###########
-0x19,0x80, // ## ##
-0x19,0x80, // ## ##
-0x19,0x80, // ## ##
-0x19,0x80, // ## ##
-0x19,0x80, // ## ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x0C,0xC0, // ## ##
+ 0x0C,0xC0, // ## ##
+ 0x0C,0xC0, // ## ##
+ 0x0C,0xC0, // ## ##
+ 0x0C,0xC0, // ## ##
+ 0x7F,0xF0, // ###########
+ 0x7F,0xF0, // ###########
+ 0x0C,0xC0, // ## ##
+ 0x19,0x80, // ## ##
+ 0x7F,0xF0, // ###########
+ 0x7F,0xF0, // ###########
+ 0x19,0x80, // ## ##
+ 0x19,0x80, // ## ##
+ 0x19,0x80, // ## ##
+ 0x19,0x80, // ## ##
+ 0x19,0x80, // ## ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @288 '$' (16 pixels wide)
-0x00,0x00, //
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x0F,0x60, // #### ##
-0x1F,0xE0, // ########
-0x30,0xE0, // ## ###
-0x30,0xE0, // ## ###
-0x38,0x00, // ###
-0x1F,0x00, // #####
-0x0F,0xC0, // ######
-0x01,0xE0, // ####
-0x30,0x60, // ## ##
-0x38,0x60, // ### ##
-0x38,0xE0, // ### ###
-0x3F,0xC0, // ########
-0x37,0x80, // ## ####
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x0F,0x60, // #### ##
+ 0x1F,0xE0, // ########
+ 0x30,0xE0, // ## ###
+ 0x30,0xE0, // ## ###
+ 0x38,0x00, // ###
+ 0x1F,0x00, // #####
+ 0x0F,0xC0, // ######
+ 0x01,0xE0, // ####
+ 0x30,0x60, // ## ##
+ 0x38,0x60, // ### ##
+ 0x38,0xE0, // ### ###
+ 0x3F,0xC0, // ########
+ 0x37,0x80, // ## ####
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @360 '%' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x0F,0x00, // ####
-0x1F,0x80, // ######
-0x39,0xC0, // ### ###
-0x30,0xC0, // ## ##
-0x30,0xC0, // ## ##
-0x39,0xC0, // ### ###
-0x1F,0xF0, // #########
-0x0F,0xC0, // ######
-0x3F,0xE0, // #########
-0x0E,0x70, // ### ###
-0x0C,0x30, // ## ##
-0x0C,0x30, // ## ##
-0x0E,0x70, // ### ###
-0x07,0xE0, // ######
-0x03,0xC0, // ####
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0x00, // ####
+ 0x1F,0x80, // ######
+ 0x39,0xC0, // ### ###
+ 0x30,0xC0, // ## ##
+ 0x30,0xC0, // ## ##
+ 0x39,0xC0, // ### ###
+ 0x1F,0xF0, // #########
+ 0x0F,0xC0, // ######
+ 0x3F,0xE0, // #########
+ 0x0E,0x70, // ### ###
+ 0x0C,0x30, // ## ##
+ 0x0C,0x30, // ## ##
+ 0x0E,0x70, // ### ###
+ 0x07,0xE0, // ######
+ 0x03,0xC0, // ####
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @432 '&' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x07,0xE0, // ######
-0x0F,0xE0, // #######
-0x18,0xC0, // ## ##
-0x18,0x00, // ##
-0x18,0x00, // ##
-0x0C,0x00, // ##
-0x0E,0x00, // ###
-0x1F,0x38, // ##### ###
-0x3B,0xF8, // ### #######
-0x31,0xE0, // ## ####
-0x30,0xE0, // ## ###
-0x1F,0xF8, // ##########
-0x0F,0xB8, // ##### ###
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x07,0xE0, // ######
+ 0x0F,0xE0, // #######
+ 0x18,0xC0, // ## ##
+ 0x18,0x00, // ##
+ 0x18,0x00, // ##
+ 0x0C,0x00, // ##
+ 0x0E,0x00, // ###
+ 0x1F,0x38, // ##### ###
+ 0x3B,0xF8, // ### #######
+ 0x31,0xE0, // ## ####
+ 0x30,0xE0, // ## ###
+ 0x1F,0xF8, // ##########
+ 0x0F,0xB8, // ##### ###
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @504 ''' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x02,0x00, // #
-0x02,0x00, // #
-0x02,0x00, // #
-0x02,0x00, // #
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x02,0x00, // #
+ 0x02,0x00, // #
+ 0x02,0x00, // #
+ 0x02,0x00, // #
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @576 '(' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x30, // ##
-0x00,0x70, // ###
-0x00,0xE0, // ###
-0x01,0xE0, // ####
-0x01,0xC0, // ###
-0x01,0xC0, // ###
-0x03,0x80, // ###
-0x03,0x80, // ###
-0x03,0x80, // ###
-0x03,0x80, // ###
-0x03,0x80, // ###
-0x03,0x80, // ###
-0x01,0xC0, // ###
-0x01,0xC0, // ###
-0x00,0xE0, // ###
-0x00,0xE0, // ###
-0x00,0x70, // ###
-0x00,0x30, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x30, // ##
+ 0x00,0x70, // ###
+ 0x00,0xE0, // ###
+ 0x01,0xE0, // ####
+ 0x01,0xC0, // ###
+ 0x01,0xC0, // ###
+ 0x03,0x80, // ###
+ 0x03,0x80, // ###
+ 0x03,0x80, // ###
+ 0x03,0x80, // ###
+ 0x03,0x80, // ###
+ 0x03,0x80, // ###
+ 0x01,0xC0, // ###
+ 0x01,0xC0, // ###
+ 0x00,0xE0, // ###
+ 0x00,0xE0, // ###
+ 0x00,0x70, // ###
+ 0x00,0x30, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @648 ')' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x30,0x00, // ##
-0x38,0x00, // ###
-0x1C,0x00, // ###
-0x1C,0x00, // ###
-0x0E,0x00, // ###
-0x0E,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x07,0x00, // ###
-0x0E,0x00, // ###
-0x0E,0x00, // ###
-0x1E,0x00, // ####
-0x1C,0x00, // ###
-0x38,0x00, // ###
-0x30,0x00, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x30,0x00, // ##
+ 0x38,0x00, // ###
+ 0x1C,0x00, // ###
+ 0x1C,0x00, // ###
+ 0x0E,0x00, // ###
+ 0x0E,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x07,0x00, // ###
+ 0x0E,0x00, // ###
+ 0x0E,0x00, // ###
+ 0x1E,0x00, // ####
+ 0x1C,0x00, // ###
+ 0x38,0x00, // ###
+ 0x30,0x00, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @720 '*' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x3B,0x70, // ### ## ###
-0x3F,0xF0, // ##########
-0x0F,0xC0, // ######
-0x07,0x80, // ####
-0x07,0x80, // ####
-0x0C,0xC0, // ## ##
-0x0C,0xC0, // ## ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x3B,0x70, // ### ## ###
+ 0x3F,0xF0, // ##########
+ 0x0F,0xC0, // ######
+ 0x07,0x80, // ####
+ 0x07,0x80, // ####
+ 0x0C,0xC0, // ## ##
+ 0x0C,0xC0, // ## ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @792 '+' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x7F,0xF8, // ############
-0x7F,0xF8, // ############
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x7F,0xF8, // ############
+ 0x7F,0xF8, // ############
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @864 ',' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x01,0xC0, // ###
-0x01,0x80, // ##
-0x03,0x80, // ###
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x06,0x00, // ##
-0x06,0x00, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x01,0xC0, // ###
+ 0x01,0x80, // ##
+ 0x03,0x80, // ###
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x06,0x00, // ##
+ 0x06,0x00, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @936 '-' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x3F,0xF0, // ##########
-0x3F,0xF0, // ##########
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x3F,0xF0, // ##########
+ 0x3F,0xF0, // ##########
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @1008 ' ' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x07,0x80, // ####
-0x07,0x80, // ####
-0x07,0x80, // ####
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x07,0x80, // ####
+ 0x07,0x80, // ####
+ 0x07,0x80, // ####
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @1080 '/' (16 pixels wide)
-0x00,0x30, // ##
-0x00,0x30, // ##
-0x00,0x70, // ###
-0x00,0x60, // ##
-0x00,0xE0, // ###
-0x00,0xC0, // ##
-0x00,0xC0, // ##
-0x01,0x80, // ##
-0x01,0x80, // ##
-0x03,0x00, // ##
-0x03,0x00, // ##
-0x06,0x00, // ##
-0x06,0x00, // ##
-0x0C,0x00, // ##
-0x0C,0x00, // ##
-0x1C,0x00, // ###
-0x18,0x00, // ##
-0x38,0x00, // ###
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x30, // ##
+ 0x00,0x30, // ##
+ 0x00,0x70, // ###
+ 0x00,0x60, // ##
+ 0x00,0xE0, // ###
+ 0x00,0xC0, // ##
+ 0x00,0xC0, // ##
+ 0x01,0x80, // ##
+ 0x01,0x80, // ##
+ 0x03,0x00, // ##
+ 0x03,0x00, // ##
+ 0x06,0x00, // ##
+ 0x06,0x00, // ##
+ 0x0C,0x00, // ##
+ 0x0C,0x00, // ##
+ 0x1C,0x00, // ###
+ 0x18,0x00, // ##
+ 0x38,0x00, // ###
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x00,0x00, //
-0x00,0x00, //
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x30,0x00, // ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x1F,0xF8, // ##########
-0x1F,0xF8, // ##########
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x30,0x00, // ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x1F,0xF8, // ##########
+ 0x1F,0xF8, // ##########
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x1F,0xF8, // ##########
-0x1F,0xF8, // ##########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x1F,0xF8, // ##########
+ 0x1F,0xF8, // ##########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x00, //
// @0 ' ' (16 pixels wide)
-0x00,0x00, //
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x30,0x06, // ## ##
-0x0F,0xF8, // #########
-0x0F,0xF8, // #########
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x06, // ##
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
+ 0x00,0x00, //
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x30,0x06, // ## ##
+ 0x0F,0xF8, // #########
+ 0x0F,0xF8, // #########
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x06, // ##
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
// @1872 ':' (16 pixels wide)
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x01,0xE0, // ####
-0x01,0xE0, // ####
-0x01,0xE0, // ####
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x01,0xE0, // ####
-0x01,0xE0, // ####
-0x01,0xE0, // ####
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00, //
-0x00,0x00 //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x01,0xE0, // ####
+ 0x01,0xE0, // ####
+ 0x01,0xE0, // ####
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x01,0xE0, // ####
+ 0x01,0xE0, // ####
+ 0x01,0xE0, // ####
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00, //
+ 0x00,0x00 //
};
sFONT Font24_7seg = {
From 47dc00bd99cab1675ee904e78a27c17df3867cd5 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 12 Nov 2022 14:04:47 +0100
Subject: [PATCH 172/319] increase clock
---
boards/esp32.json | 2 +-
boards/esp32_solo1.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/boards/esp32.json b/boards/esp32.json
index 0159ea555..808ba0cd0 100644
--- a/boards/esp32.json
+++ b/boards/esp32.json
@@ -5,7 +5,7 @@
},
"core": "esp32",
"extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M",
- "f_cpu": "80000000L",
+ "f_cpu": "160000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
diff --git a/boards/esp32_solo1.json b/boards/esp32_solo1.json
index 3723e27b2..85b886a55 100644
--- a/boards/esp32_solo1.json
+++ b/boards/esp32_solo1.json
@@ -5,7 +5,7 @@
},
"core": "esp32",
"extra_flags": "-DARDUINO_ESP32_DEV -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DCORE32SOLO1",
- "f_cpu": "80000000L",
+ "f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
From b0dbe32f22b13aabd2310dc4119a730d0501dda2 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 12 Nov 2022 15:03:42 +0100
Subject: [PATCH 173/319] Fix serial bridge tee not wanted resolve
---
tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index 09939591c..b4562561b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -73,7 +73,8 @@ void SerialBridgePrintf(PGM_P formatP, ...) {
va_end(arg);
if (data == nullptr) { return; }
- SerialBridgeSerial->printf(data);
+// SerialBridgeSerial->printf(data); // This resolves "MqttClientMask":"DVES_%06X" into "DVES_000002"
+ SerialBridgeSerial->print(data); // This does not resolve "DVES_%06X"
free(data);
}
#endif // USE_SERIAL_BRIDGE_TEE
From 4e5193fdad079b4af81a17e8708dbf82572acba3 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 12 Nov 2022 15:57:46 +0100
Subject: [PATCH 174/319] Remove SkipSleep() in favour of FUNC_SLEEP_LOOP
---
tasmota/tasmota.ino | 5 ++---
tasmota/tasmota_support/support_tasmota.ino | 17 -----------------
tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 1 +
tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino | 2 --
4 files changed, 3 insertions(+), 22 deletions(-)
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 126a10c51..688deed4a 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -314,7 +314,6 @@ struct TasmotaGlobal_t {
uint8_t latching_relay_pulse; // Latching relay pulse timer
uint8_t active_device; // Active device in ExecuteCommandPower
uint8_t sleep; // Current copy of Settings->sleep
- uint8_t skip_sleep; // Abandon sleep and allow loop
uint8_t leds_present; // Max number of LED supported
uint8_t led_inverted; // LED inverted flag (1 = (0 = On, 1 = Off))
uint8_t led_power; // LED power state
@@ -549,7 +548,7 @@ void setup(void) {
#endif
#endif // USE_EMULATION
-// AddLog(LOG_LEVEL_INFO, PSTR("DBG: TasmotaGlobal size %d, data %*_H"), sizeof(TasmotaGlobal), 100, (uint8_t*)&TasmotaGlobal);
+// AddLog(LOG_LEVEL_INFO, PSTR("DBG: TasmotaGlobal size %d, data %100_H"), sizeof(TasmotaGlobal), (uint8_t*)&TasmotaGlobal);
if (Settings->param[P_BOOT_LOOP_OFFSET]) { // SetOption36
// Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts)
@@ -681,7 +680,7 @@ void BacklogLoop(void) {
void SleepDelay(uint32_t mseconds) {
if (!TasmotaGlobal.backlog_nodelay && mseconds) {
uint32_t wait = millis() + mseconds;
- while (!TimeReached(wait) && !Serial.available() && !TasmotaGlobal.skip_sleep) { // We need to service serial buffer ASAP as otherwise we get uart buffer overrun
+ while (!TimeReached(wait) && !Serial.available()) { // We need to service serial buffer ASAP as otherwise we get uart buffer overrun
XdrvCall(FUNC_SLEEP_LOOP);
delay(1);
}
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index f6fd5981f..803bd0adf 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1027,19 +1027,6 @@ void MqttPublishTeleperiodSensor(void) {
}
}
-void SkipSleep(bool state) {
- if (state) {
- TasmotaGlobal.skip_sleep += 2;
- } else {
- if (TasmotaGlobal.skip_sleep) {
- TasmotaGlobal.skip_sleep--;
- }
- if (TasmotaGlobal.skip_sleep) {
- TasmotaGlobal.skip_sleep--;
- }
- }
-}
-
/*********************************************************************************************\
* State loops
\*********************************************************************************************/
@@ -1202,10 +1189,6 @@ void Every100mSeconds(void)
}
}
- if (TasmotaGlobal.skip_sleep) {
- TasmotaGlobal.skip_sleep--; // Clean up possible residue
- }
-
for (uint32_t i = 0; i < MAX_PULSETIMERS; i++) {
if (TasmotaGlobal.pulse_timer[i] != 0L) { // Timer active?
if (TimeReached(TasmotaGlobal.pulse_timer[i])) { // Timer finished?
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 5795800d1..27b941ac2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -1394,6 +1394,7 @@ bool Xdrv03(uint32_t function)
else if (TasmotaGlobal.energy_driver) {
switch (function) {
case FUNC_LOOP:
+ case FUNC_SLEEP_LOOP:
XnrgCall(FUNC_LOOP);
break;
case FUNC_EVERY_250_MSECOND:
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino b/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino
index 181fbd9ed..37d157d16 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_23_ade7880.ino
@@ -536,7 +536,6 @@ void Ade7880Cycle(void) {
void Ade7880Service0(void) {
// Poll sequence
- SkipSleep(false);
Ade7880Cycle();
Ade7880.watchdog = 0;
Ade7880.irq0_state = 0;
@@ -546,7 +545,6 @@ void IRAM_ATTR Ade7880Isr0(void) {
// Poll sequence
if (!Ade7880.irq0_state) {
Ade7880.irq0_state = 1;
- SkipSleep(true);
}
}
From e5219fb8be9ac55587d6f260aae4f40ed089bf91 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 12 Nov 2022 17:12:15 +0100
Subject: [PATCH 175/319] ues zopfli to gz firmware
---
pio-tools/gzip-firmware.py | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/pio-tools/gzip-firmware.py b/pio-tools/gzip-firmware.py
index 080448a30..26a00abe8 100644
--- a/pio-tools/gzip-firmware.py
+++ b/pio-tools/gzip-firmware.py
@@ -1,11 +1,17 @@
Import("env")
import os
import shutil
-import gzip
import pathlib
-
import tasmotapiolib
+# Upgrade pip
+env.Execute("$PYTHONEXE -m pip install --upgrade pip")
+# Install zopfli gz compressor from the PyPi registry
+env.Execute("$PYTHONEXE -m pip install zopfli")
+
+# Import zoepfli compress
+from zopfli.gzip import compress
+import gzip
def map_gzip(source, target, env):
# create string with location and file names based on variant
@@ -45,8 +51,9 @@ if env["PIOPLATFORM"] != "espressif32":
# write gzip firmware file
with open(bin_file, "rb") as fp:
- with gzip.open(gzip_file, "wb", compresslevel=9) as f:
- shutil.copyfileobj(fp, f)
+ with open(gzip_file, "wb") as f:
+ zopfli_gz = compress(fp.read())
+ f.write(zopfli_gz)
ORG_FIRMWARE_SIZE = bin_file.stat().st_size
GZ_FIRMWARE_SIZE = gzip_file.stat().st_size
From 172ea9a80d1bac870e81380a99ef4fb54a91f0b9 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Sat, 12 Nov 2022 23:15:57 +0100
Subject: [PATCH 176/319] add RgxClients command for range extenders
---
.../xdrv_58_range_extender.ino | 35 +++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 0b0e382ce..c8af4b4d2 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -35,10 +35,14 @@ CONFIG_LWIP_IP_FORWARD option set, and optionally CONFIG_LWIP_IPV4_NAPT.
If you want to support NAPT (removing the need for routes on a core router):
#define USE_WIFI_RANGE_EXTENDER_NAPT
+If you want to list AP clients (MAC and IP) with command RgxClients:
+#define USE_WIFI_RANGE_EXTENDER_CLIENTS
+
An example full static configuration:
#define USE_WIFI_RANGE_EXTENDER
#define USE_WIFI_RANGE_EXTENDER_NAPT
+#define USE_WIFI_RANGE_EXTENDER_CLIENTS
#define WIFI_RGX_STATE 1
#define WIFI_RGX_NAPT 1
#define WIFI_RGX_SSID "rangeextender"
@@ -92,6 +96,10 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
"|"
"NAPT"
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
+#ifdef USE_WIFI_RANGE_EXTENDER_CLIENTS
+ "|"
+ "Clients"
+#endif // USE_WIFI_RANGE_EXTENDER_CLIENTS
"|"
"Address"
"|"
@@ -104,6 +112,9 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
&CmndRgxNAPT,
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
+#ifdef USE_WIFI_RANGE_EXTENDER_CLIENTS
+ &CmndRgxClients,
+#endif // USE_WIFI_RANGE_EXTENDER_CLIENTS
&CmndRgxAddresses,
&CmndRgxAddresses,
};
@@ -161,6 +172,30 @@ void RgxCheckConfig(void)
}
}
+#ifdef USE_WIFI_RANGE_EXTENDER_CLIENTS
+#include "esp_wifi.h"
+
+void CmndRgxClients(void)
+{
+ wifi_sta_list_t wifi_sta_list = {0};
+ tcpip_adapter_sta_list_t adapter_sta_list = {0};
+
+ esp_wifi_ap_get_sta_list(&wifi_sta_list);
+ tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
+
+ Response_P(PSTR("["));
+ const char *sep = "";
+ for (int i=0; i= 0) && (XdrvMailbox.payload <= 1))
From 4c376350a7c4ec6ec76ada5876c27f0cada3f3e3 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Sat, 12 Nov 2022 23:17:15 +0100
Subject: [PATCH 177/319] add RgxClients to tasmota32-rangeextender pio env
---
platformio_tasmota_cenv_sample.ini | 1 +
1 file changed, 1 insertion(+)
diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini
index e086b1094..2eb6bce81 100644
--- a/platformio_tasmota_cenv_sample.ini
+++ b/platformio_tasmota_cenv_sample.ini
@@ -11,6 +11,7 @@ build_flags = ${env:tasmota32_base.build_flags}
-D FIRMWARE_TASMOTA32
-D USE_WIFI_RANGE_EXTENDER
-D USE_WIFI_RANGE_EXTENDER_NAPT
+ -D USE_WIFI_RANGE_EXTENDER_CLIENTS
[env:tasmota32s3-file]
extends = env:tasmota32_base
From 13c27194ec54bc1794c82ac45bcd120234d0d85d Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 13 Nov 2022 12:55:18 +0100
Subject: [PATCH 178/319] TuyaMcu rewrite by btsimonh (#17051)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/tasmota.ino | 3 +-
tasmota/tasmota_support/support_command.ino | 1 +
..._16_tuyamcu.ino => xdrv_16_tuyamcu_v1.ino} | 7 +-
.../xdrv_16_tuyamcu_v2.ino | 2579 +++++++++++++++++
6 files changed, 2589 insertions(+), 3 deletions(-)
rename tasmota/tasmota_xdrv_driver/{xdrv_16_tuyamcu.ino => xdrv_16_tuyamcu_v1.ino} (99%)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0364f465a..c8470d738 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
+- TuyaMcu rewrite by btsimonh (#17051)
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 353786be4..6de9a4302 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -133,6 +133,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
+- TuyaMcu rewrite by btsimonh [#17051](https://github.com/arendst/Tasmota/issues/17051)
### Fixed
- Serial bridge default serial configuration from 5N1 to 8N1 regression from v10.1.0.3
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 688deed4a..4681a56ef 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -331,6 +331,7 @@ struct TasmotaGlobal_t {
uint8_t module_type; // Current copy of Settings->module or user template type
uint8_t emulated_module_type; // Emulated module type as requested by ESP32
uint8_t last_source; // Last command source
+ uint8_t last_command_source; // Last command source
uint8_t shutters_present; // Number of actual define shutters
uint8_t discovery_counter; // Delayed discovery counter
uint8_t power_on_delay; // Delay relay power on to reduce power surge (SetOption47)
@@ -681,7 +682,7 @@ void SleepDelay(uint32_t mseconds) {
if (!TasmotaGlobal.backlog_nodelay && mseconds) {
uint32_t wait = millis() + mseconds;
while (!TimeReached(wait) && !Serial.available()) { // We need to service serial buffer ASAP as otherwise we get uart buffer overrun
- XdrvCall(FUNC_SLEEP_LOOP);
+ XdrvCall(FUNC_SLEEP_LOOP); // Main purpose is reacting ASAP on serial data availability or interrupt handling (ADE7880)
delay(1);
}
} else {
diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino
index 6086572db..aaedcf494 100644
--- a/tasmota/tasmota_support/support_command.ino
+++ b/tasmota/tasmota_support/support_command.ino
@@ -329,6 +329,7 @@ void ExecuteCommand(const char *cmnd, uint32_t source)
// cmnd: "var1=1" = stopic "var1" and svalue "=1"
SHOW_FREE_MEM(PSTR("ExecuteCommand"));
ShowSource(source);
+ TasmotaGlobal.last_command_source = source;
const char *pos = cmnd;
while (*pos && isspace(*pos)) {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino
similarity index 99%
rename from tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
rename to tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino
index 35ef17ccc..6bd5a655e 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v1.ino
@@ -18,7 +18,10 @@
*/
#ifdef USE_LIGHT
-#ifdef USE_TUYA_MCU
+#ifdef USE_TUYA_MCU_V1
+/*********************************************************************************************\
+ * Tuya MCU V1
+\*********************************************************************************************/
#define XDRV_16 16
#define XNRG_32 32 // Needs to be the last XNRG_xx
@@ -551,7 +554,7 @@ void TuyaSendHexString(uint8_t id, char data[]) {
TuyaSendCmd(TUYA_CMD_SET_DP, payload_buffer, payload_len);
}
-void TuyaSendString(uint8_t id, char data[]) {
+void TuyaSendString(uint8_t id, const char data[]) {
uint16_t len = strlen(data);
uint16_t payload_len = 4 + len;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino
new file mode 100644
index 000000000..21df2e281
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino
@@ -0,0 +1,2579 @@
+/*
+ xdrv_16_tuyamcu.ino - Tuya MCU support for Tasmota
+
+ Copyright (C) 2021 Federico Leoni, digiblur, Joel Stein and Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_LIGHT
+#ifdef USE_TUYA_MCU
+/*********************************************************************************************\
+ * Tuya MCU V2
+
+ rework 2022-04-03 SH:
+ the intent of the rework is:
+ 1/ make the protocol parsing more robust.
+ to this end, it now observes a byte timeout on receive, and looks for 55AA rather than just 55 to reset.
+ Parsing has been split from message processing for better readability.
+ 2/ try to observe to 'tuya' state machine as per thier documentation.
+ - at least for startup.
+ ALL sends should originate from the state machine (except manual sends?).
+ ALL sends which need a return (synchronous) wait for an expected command before
+ the next command can be sent. (commands were observed being dropped by the MCU).
+ 3/ sending of DP data is now 'requested', and only sent if the DP value is
+ different to the one the MCU has (fixes an issue with Athom dimmer).
+ (data is stored in DPStore[], and serviced in the state machine)
+
+\*********************************************************************************************/
+
+#define XDRV_16 16
+#define XNRG_32 32 // Needs to be the last XNRG_xx
+
+#ifndef TUYA_DIMMER_ID
+#define TUYA_DIMMER_ID 0
+#endif
+
+#define TUYA_CMD_HEARTBEAT 0x00
+#define TUYA_CMD_QUERY_PRODUCT 0x01
+#define TUYA_CMD_MCU_CONF 0x02
+#define TUYA_CMD_WIFI_STATE 0x03
+#define TUYA_CMD_WIFI_RESET 0x04
+#define TUYA_CMD_WIFI_SELECT 0x05
+#define TUYA_CMD_SET_DP 0x06
+#define TUYA_CMD_STATE 0x07
+#define TUYA_CMD_QUERY_STATE 0x08
+#define TUYA_CMD_INITIATING_UPGRADE 0x0A // not implemented
+#define TUYA_CMD_UPGRADE_PACKAGE 0x0B // not implemented
+
+// MCU sends to request a 0x0c return of GMT
+#define TUYA_CMD_GET_TIME_GMT 0x0C // not implemented
+
+// MCU sends
+#define TUYA_CMD_TEST_WIFI 0x0E // not implemented
+// MCU sends
+#define TUYA_CMD_GET_MEMORY 0x0F // not implemented
+
+// MCU sends to request a 0x1c return of Local Time
+// we send unsolicited??
+#define TUYA_CMD_SET_TIME 0x1C
+
+// MCU Sends, we must respond with 0x22, len1 00 failure, 01 success
+#define TUYA_CMD_STATUS_SYNC 0x22 // not implemented
+#define TUYA_CMD_STATUS_SYNC_RES 0x23 // not implemented
+
+// From MCU. Response should be 0x0b 00/01/02
+// subcmd 03 -> request weather data
+// subcmd 06 -> get map id
+#define TUYA_CMD_REPORT_STATUS_RECORD_TYPE 0x34 // not implemented
+
+// MCU sends 'after 01 bute before 02'. Response should be 0x37, len 2, 00, 00/01/02
+// subcmd 01->file download notification
+#define TUYA_CMD_NEW_FEATURES 0x37 // not implemented
+
+// MCU sends
+#define TUYA_CMD_ENABLE_WEATHER 0x20 // not implemented
+// we send every 30 mins, if enabled, MCU acks with 0x21
+#define TUYA_CMD_SEND_WEATHER 0x21 // not implemented
+
+// MCU sends, response 0x24, len 1, -ve dB or 0
+#define TUYA_CMD_GET_WIFI_STRENGTH 0x24 // not implemented
+
+// MCU sends, response 0x25
+#define TUYA_CMD_DISABLE_HEARTBEAT 0x25 // not implemented
+// MCU sends JSON, response 0x2A, len1 00/01/02/03
+#define TUYA_CMD_SERIAL_PAIRING 0x2A // not implemented
+
+#define TUYA_CMD_VACUUM_MAP_STREAMING 0x28 // not implemented
+#define TUYA_CMD_VACUUM_MAP_STREAMING_MULTIPLE 0x30 // not implemented
+
+// MCU sends, response 0x2D
+#define TUYA_CMD_GET_MAC 0x2D // not implemented
+// MCU sends, response 0x2E
+#define TUYA_CMD_IR_STATUS 0x2E // not implemented
+// MCU sends, response 0x2E
+#define TUYA_CMD_IR_TEST 0x2F // not implemented
+// We send, response 0x33
+// uses subcommands, 01->learning, 02->data, 03->report.
+#define TUYA_CMD_RF 0x33 // not implemented
+
+
+
+#define TUYA_LOW_POWER_CMD_WIFI_STATE 0x02
+#define TUYA_LOW_POWER_CMD_WIFI_RESET 0x03
+#define TUYA_LOW_POWER_CMD_WIFI_CONFIG 0x04
+#define TUYA_LOW_POWER_CMD_STATE 0x05
+
+#define TUYA_TYPE_RAW 0x00
+#define TUYA_TYPE_BOOL 0x01
+#define TUYA_TYPE_VALUE 0x02
+#define TUYA_TYPE_STRING 0x03
+#define TUYA_TYPE_ENUM 0x04
+
+// limit to what we store for DPs of type string
+#define TUYA_MAX_STRING_SIZE 16
+
+#define TUYA_BUFFER_SIZE 256
+
+#define TUYA_BYTE_TIMEOUT_MS 500
+
+#define TUYA_MORE_DEBUG
+
+
+
+#include
+
+
+#define TUYAREAD32FROMPTR(x) (((uint8_t*)x)[0] << 24 | ((uint8_t*)x)[1] << 16 | ((uint8_t*)x)[2] << 8 | ((uint8_t*)x)[3])
+
+
+enum {
+ TUYA_STARTUP_STATE_INIT = 0,
+ TUYA_STARTUP_STATE_WAIT_ACK_INIT, // 1
+
+ TUYA_STARTUP_STATE_PRODUCT, //2
+ TUYA_STARTUP_STATE_WAIT_ACK_PRODUCT, // 3
+
+ TUYA_STARTUP_STATE_WAIT_OPTIONAL_NEW_FEATURES, // 4
+
+ TUYA_STARTUP_STATE_CONF, // 5
+ TUYA_STARTUP_STATE_WAIT_ACK_CONF, //6
+
+ TUYA_STARTUP_STATE_WIFI_STATE, //7
+ TUYA_STARTUP_STATE_WAIT_ACK_WIFI,//8
+
+ TUYA_STARTUP_STATE_QUERY_STATE,//9
+ TUYA_STARTUP_STATE_WAIT_ACK_QUERY,//10
+
+ TUYA_STARTUP_STATE_SEND_CMD,//11
+ TUYA_STARTUP_STATE_WAIT_ACK_CMD,//12
+
+ TUYA_STARTUP_STATE_SEND_HEARTBEAT,//13
+ TUYA_STARTUP_STATE_WAIT_ACK_HEARTBEAT,//14
+
+};
+
+
+TasmotaSerial *TuyaSerial = nullptr;
+
+#define TUYA_MAX_STORED_DPs 10
+typedef struct TUYA_DP_STORE_tag {
+ uint8_t DPid;
+ uint8_t Type;
+ uint8_t rxedValueLen;
+ uint8_t desiredValueLen;
+ // NOTE - THESE MUST BE 32 bit ALIGNED, hence uint32_t
+ // DPValues are changed by every TUYA_CMD_STATE
+ uint32_t rxedValue[(TUYA_MAX_STRING_SIZE+3)/4];
+ // desired DPValues are set, and toSet is set to request
+ uint32_t desiredValue[(TUYA_MAX_STRING_SIZE+3)/4];
+ // set to 1 if desired value changed
+ uint8_t toSet;
+ // flag to indicate we saw it at least once from MCU.
+ uint8_t rxed;
+} TUYA_DP_STORE;
+
+typedef struct TUYA_STRUCT_tag {
+ // variables to handle setting of a DP.
+ // DPIds are filled out by initial TUYA_CMD_QUERY_STATE
+ // or by an easrly set request.
+ TUYA_DP_STORE DPStore[TUYA_MAX_STORED_DPs];
+ uint8_t numRxedDPids;
+
+ // set to indicate the command which is an ack to the last sent command.
+ // e.g. 7 is ack to 6 and 8
+ // if state is TUYA_STARTUP_STATE_WAIT_ACK_CMD
+ uint8_t expectedResponseCmd;
+
+// uint8_t rxedDPids[TUYA_MAX_STORED_DPs];
+// uint8_t rxedDPidType[TUYA_MAX_STORED_DPs];
+ // DPValues are changed by every TUYA_CMD_STATE
+// uint32_t rxedDPvalues[TUYA_MAX_STORED_DPs];
+ // DPValues are changed by every TUYA_CMD_STATE
+// uint32_t desiredDPvalues[TUYA_MAX_STORED_DPs];
+ // set to 1 if desired value changed
+// uint8_t toSet[TUYA_MAX_STORED_DPs];
+ // set to 1 if a DP is to be sent
+ uint8_t requestSend;
+
+ uint16_t Levels[5]; // Array to store the values of TuyaMCU channels
+ uint16_t Snapshot[5]; // Array to store a snapshot of Tasmota actual channel values
+ uint16_t EnumState[4]; // Array to store up to four Enum type 4 values
+ char RGBColor[7]; // Stores RGB Color string in Hex format
+ uint16_t CTMin; // Minimum CT level allowed - When SetOption82 is enabled will default to 200
+ uint16_t CTMax; // Maximum CT level allowed - When SetOption82 is enabled will default to 380
+ int16_t Sensors[14]; // Stores the values of Sensors connected to the Tuya Device
+ bool ModeSet; // Controls 0 - Single Tone light, 1 - RGB Light
+ bool SensorsValid[14]; // Bool used for nullify the sensor value until a real value is received from the MCU
+ bool SuspendTopic; // Used to reduce the load at init time or when polling the configuraton on demand
+ bool ignore_dim; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction
+ uint32_t ignore_topic_timeout; // Suppress the /STAT topic (if enabled) to avoid data overflow until the configuration is over
+ uint8_t cmd_status; // Current status of serial-read
+ uint8_t cmd_checksum; // Checksum of tuya command
+ uint8_t data_len; // Data lenght of command
+ uint8_t wifi_state; // Keep MCU wifi-status in sync with WifiState()
+ uint8_t heartbeat_timer; // 10 second heartbeat timer for tuya module
+
+ // flasg which trigger sends of certain messages
+ uint8_t send_heartbeat; // trigger heartbeat when we can next send.
+ uint8_t send_time; // trigger time send when we can in running mode.
+
+#ifdef USE_ENERGY_SENSOR
+ uint32_t lastPowerCheckTime; // Time when last power was checked
+#endif // USE_ENERGY_SENSOR
+ unsigned char buffer[TUYA_BUFFER_SIZE]; // Serial receive buffer
+ int byte_counter; // Index in serial receive buffer
+ uint32_t ignore_dimmer_cmd_timeout; // Time until which received dimmer commands should be ignored
+ bool low_power_mode; // Normal or Low power mode protocol
+ bool send_success_next_second; // Second command success in low power mode
+ bool active;
+
+ int timeout; // command timeout in ms
+ // every time we get a long press, add 10000. If we get to 20000, then go to wifimanager mode, if enabled
+ // decremented by 1000 each second.
+ int wifiTimer;
+
+ char inStateMachine;
+ char startup_state;
+ char timeout_state; // state to go to if timeout.
+
+ unsigned char lastByte;
+ unsigned int lastByteTime; // time of last byte receipt.
+
+ unsigned int errorcnt; // increment every time something goes awry
+ unsigned int lasterrorcnt; // used to choose when to log errorcnt
+
+ int dimDelay_ms[2]; // SIGNED the delay after a dim result after which we are allowed to send a dim value
+ int defaultDimDelay_ms; // the delay after a dim result after which we are allowed to send a dim value
+ uint8_t dimCmdEnable; // we are allowed to send a dim command - bitfield
+ uint8_t dimDebug; // enables a single dim debug - bitfield
+
+ int sends;
+ int rxs;
+
+} TUYA_STRUCT;
+
+TUYA_STRUCT *pTuya = (TUYA_STRUCT *)0;
+//void TuyaSendCmd(uint8_t cmd, uint8_t payload[] = nullptr, uint16_t payload_len = 0);
+
+void TuyaSendState(uint8_t id, uint8_t type, uint8_t* value, int len);
+
+
+int init_tuya_struct() {
+ if (pTuya) return 0; // done already
+ pTuya = (TUYA_STRUCT *)malloc(sizeof(TUYA_STRUCT));
+ if (!pTuya) return 0;
+ memset(pTuya, 0, sizeof(TUYA_STRUCT));
+ strcpy(pTuya->RGBColor, "000000"); // Stores RGB Color string in Hex format
+ pTuya->CTMin = 153; // Minimum CT level allowed - When SetOption82 is enabled will default to 200
+ pTuya->CTMax = 500; // Maximum CT level allowed - When SetOption82 is enabled will default to 380
+ pTuya->wifi_state = -2; // Keep MCU wifi-status in sync with WifiState()
+ pTuya->defaultDimDelay_ms = 2000; // 2s delay from a power command to a dim command, or from an rxed dim command to sending one.
+#ifdef TUYA_MORE_DEBUG
+ AddLog(LOG_LEVEL_INFO, PSTR("TYA: Init struct done"));
+#endif
+ return 1;
+}
+
+#define D_JSON_TUYA_MCU_RECEIVED "TuyaReceived"
+
+#define D_PRFX_TUYA "Tuya"
+#define D_CMND_TUYA_MCU "MCU"
+#define D_CMND_TUYA_MCU_SEND_STATE "Send"
+#define D_CMND_TUYARGB "RGB"
+#define D_CMND_TUYA_ENUM "Enum"
+#define D_CMND_TUYA_ENUM_LIST "EnumList"
+// #define D_CMND_TUYA_SET_TEMP "SetTemp"
+// #define D_CMND_TUYA_SET_HUM "SetHum"
+// #define D_CMND_TUYA_SET_TIMER "SetTimer"
+
+const char kTuyaSensors[] PROGMEM = // List of available sensors (can be expanded in the future)
+// 71 72 73 74 75
+ "" D_JSON_TEMPERATURE "|TempSet|" D_JSON_HUMIDITY "|HumSet|" D_JSON_ILLUMINANCE
+// 76 77 78 79 80 81 82 83 84
+ "|" D_JSON_TVOC "|" D_JSON_ECO2 "|" D_JSON_CO2 "|" D_JSON_GAS "|" D_ENVIRONMENTAL_CONCENTRATION "||Timer1|Timer2|Timer3|TImer4";
+
+const char kTuyaCommand[] PROGMEM = D_PRFX_TUYA "|" // Prefix
+ D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE "|" D_CMND_TUYARGB "|" D_CMND_TUYA_ENUM "|" D_CMND_TUYA_ENUM_LIST "|TempSetRes|DimDelay";
+
+void (* const TuyaCommand[])(void) PROGMEM = {
+ &CmndTuyaMcu, &CmndTuyaSend, &CmndTuyaRgb, &CmndTuyaEnum, &CmndTuyaEnumList, &CmndTuyaTempSetRes, &CmdTuyaSetDimDelay
+};
+
+const uint8_t TuyaExcludeCMDsFromMQTT[] PROGMEM = { // don't publish this received commands via MQTT if SetOption66 and SetOption137 is active (can be expanded in the future)
+ TUYA_CMD_HEARTBEAT, TUYA_CMD_WIFI_STATE, TUYA_CMD_SET_TIME, TUYA_CMD_UPGRADE_PACKAGE
+};
+
+/*********************************************************************************************\
+ * Web Interface
+\*********************************************************************************************/
+
+bool IsModuleTuya(void) {
+ if (!pTuya) return false;
+ bool is_tuya = pTuya->active;
+//#ifdef ESP8266
+ // This is not a Tuya driven device. It uses a Tuya provided ESP8266. Why it was here is a mystery to me.
+// if (SK03_TUYA == TasmotaGlobal.module_type) {
+// is_tuya = true;
+// }
+//#endif
+ return is_tuya;
+}
+
+bool AsModuleTuyaMS(void) // ModeSet Layout
+{
+ return ((TasmotaGlobal.light_type > LT_RGB) && TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0);
+}
+
+bool TuyaModeSet(void) // ModeSet Status
+{
+ if (!pTuya) return false;
+ return pTuya->ModeSet;
+}
+
+/*********************************************************************************************\
+ * Web Interface
+\*********************************************************************************************/
+
+/*
+TuyaSend dpId,data
+
+TuyaSend0 -> Sends TUYA_CMD_QUERY_STATE
+TuyaSend1 11,1 -> Sends boolean (Type 1) data 0/1 to dpId 11 (Max data length 1 byte)
+TuyaSend2 11,100 -> Sends integer (Type 2) data 100 to dpId 11 (Max data length 4 bytes)
+TuyaSend2 11,0xAABBCCDD -> Sends 4 bytes (Type 2) data to dpId 11 (Max data length 4 bytes)
+TuyaSend3 11,ThisIsTheData -> Sends the supplied string (Type 3) to dpId 11 ( Max data length not-known)
+TuyaSend4 11,1 -> Sends enum (Type 4) data 1 to dpId 11 (Max data length 1 bytes)
+TuyaSend5 11,ABCD -> Sends an HEX string (Type 3) data to dpId
+TuyaSend6 11,ABCD -> Sends raw (Type 0) data to dpId
+
+TuyaSend8 -> Sends TUYA_CMD_QUERY_PRODUCT ?
+*/
+
+void CmndTuyaSend(void) {
+ if (!pTuya) return;
+ switch(XdrvMailbox.index){
+ case 0:
+ TuyaRequestState(0);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ {
+ if (XdrvMailbox.data_len > 0) {
+ char *p;
+ const char *data = "";
+ uint8_t i = 0;
+ uint8_t dpId = 0;
+ for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 2; str = strtok_r(nullptr, ", ", &p)) {
+ if ( i == 0) {
+ // note: can be a number, or 0xnn for hex because base is 0
+ dpId = strtoul(str, nullptr, 0);
+ } else {
+ data = str;
+ }
+ i++;
+ }
+
+ if (1 == XdrvMailbox.index) {
+ TuyaSendBool(dpId, strtoul(data, nullptr, 0));
+ } else if (2 == XdrvMailbox.index) {
+ TuyaSendValue(dpId, strtoull(data, nullptr, 0));
+ } else if (3 == XdrvMailbox.index) {
+ TuyaSendString(dpId, data);
+ } else if (5 == XdrvMailbox.index) {
+ TuyaSendHexString(dpId, data);
+ } else if (4 == XdrvMailbox.index) {
+ TuyaSendEnum(dpId, strtoul(data, nullptr, 0));
+ } else if (6 == XdrvMailbox.index) {
+ TuyaSendRaw(dpId, data);
+ } else if (7 == XdrvMailbox.index) {
+ uint8_t cmd = dpId;
+ // send ANY cmd with payload from hex string
+ // calculates length and checksum for you.
+ // like "0," to send a heartbeat, "3,4" to set wifi led mode,
+ // "0x1c,0110041305060702" - set local time
+ // sends immediately....
+ TuyaSendRawCmd(cmd, data);
+ }
+ }
+ } break;
+
+ case 8:
+ // product info
+ TuyaRequestState(8);
+ break;
+ case 9:
+ Settings->tuyamcu_topic = !Settings->tuyamcu_topic;
+ AddLog(LOG_LEVEL_INFO, PSTR("TYA: TuyaMCU Stat Topic %s"), (Settings->tuyamcu_topic ? PSTR("enabled") : PSTR("disabled")));
+ break;
+ }
+ ResponseCmndDone();
+}
+
+
+void CmdTuyaSetDimDelay(void) {
+ if (!pTuya) return;
+
+ switch(XdrvMailbox.index){
+ case 1: {
+ if (XdrvMailbox.data_len > 0) {
+ int32_t delay = strtol(XdrvMailbox.data, nullptr, 0);
+ pTuya->defaultDimDelay_ms = delay;
+ } else {
+ // report only
+ Response_P(PSTR("{\"%s\":{\"dimdelay\":%d}}"), XdrvMailbox.command, pTuya->defaultDimDelay_ms); // Builds TuyaMCU
+ return;
+ }
+ } break;
+
+ default: // no response
+ return;
+ }
+ ResponseCmndDone();
+}
+
+// TuyaMcu fnid,dpid
+
+void CmndTuyaMcu(void) {
+ if (!pTuya) return;
+ if (XdrvMailbox.data_len > 0) {
+ char *p;
+ uint8_t i = 0;
+ uint8_t parm[3] = { 0 };
+ for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 2; str = strtok_r(nullptr, ", ", &p)) {
+ parm[i] = strtoul(str, nullptr, 0);
+ i++;
+ }
+
+ if (TuyaFuncIdValid(parm[0])) {
+ bool DualDim;
+ if (TUYA_MCU_FUNC_DIMMER2 == parm[0] && parm[1] != 0) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) != 0) { DualDim = true; }
+ } else if (TUYA_MCU_FUNC_DIMMER == parm[0] && parm[1] != 0) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2) != 0) { DualDim = true; }
+ } else if ((TUYA_MCU_FUNC_DIMMER == parm[0] && parm[1] == 0) || (TUYA_MCU_FUNC_DIMMER2 == parm[0] && parm[1] == 0)) { DualDim = false; };
+ if (DualDim) { // If the second dimmer is enabled CT, RGB or WHITE function must be removed
+ if (TuyaGetDpId(TUYA_MCU_FUNC_CT) != 0) { TuyaAddMcuFunc(TUYA_MCU_FUNC_CT, 0); }
+ if (TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0) { TuyaAddMcuFunc(TUYA_MCU_FUNC_RGB, 0); }
+ if (TuyaGetDpId(TUYA_MCU_FUNC_WHITE) != 0) { TuyaAddMcuFunc(TUYA_MCU_FUNC_WHITE, 0); }
+ Settings->flag3.pwm_multi_channels = 1;
+ } else { Settings->flag3.pwm_multi_channels = 0; }
+ TuyaAddMcuFunc(parm[0], parm[1]);
+ TasmotaGlobal.restart_flag = 2;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: TuyaMcu Invalid function id=%d"), parm[0]);
+ }
+ }
+
+ Response_P(PSTR("{\"%s\":["), XdrvMailbox.command); // Builds TuyaMCU
+ bool added = false;
+ for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
+ if (Settings->tuya_fnid_map[i].fnid != 0) {
+ if (added) {
+ ResponseAppend_P(PSTR(","));
+ }
+ ResponseAppend_P(PSTR("{\"fnId\":%d,\"dpId\":%d}" ), Settings->tuya_fnid_map[i].fnid, Settings->tuya_fnid_map[i].dpid);
+ added = true;
+ }
+ }
+ ResponseAppend_P(PSTR("]}"));
+}
+
+void CmndTuyaRgb(void) { // Command to control the RGB format
+ if (!pTuya) return;
+
+ uint16_t payload = XdrvMailbox.payload;
+
+ if (XdrvMailbox.data_len > 0) {
+ if (payload < 0 || payload > 3 || TuyaGetDpId(TUYA_MCU_FUNC_RGB) == 0) {
+ return;
+ } else {
+ if (payload != Settings->tuya_fnid_map[230].dpid) { // fnid 230 is reserved for RGB
+ Settings->tuya_fnid_map[230].fnid = 230;
+ Settings->tuya_fnid_map[230].dpid = payload;
+ }
+ }
+ }
+ ResponseCmndNumber(Settings->tuya_fnid_map[230].dpid);
+}
+
+void CmndTuyaTempSetRes(void)
+{
+ if (!pTuya) return;
+ if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) {
+ Settings->mbflag2.temperature_set_res = XdrvMailbox.payload;
+ }
+ ResponseCmndNumber(Settings->mbflag2.temperature_set_res);
+}
+
+void CmndTuyaEnum(void) { // Command to control up to four type 4 Enum
+ if (!pTuya) return;
+ uint16_t EnumIdx = XdrvMailbox.index;
+ int32_t payload = XdrvMailbox.payload;
+
+ if (EnumIdx > 4 || TuyaGetDpId(TUYA_MCU_FUNC_ENUM1 + (EnumIdx-1)) == 0) {
+ return;
+ }
+
+ if (XdrvMailbox.data_len > 0) {
+ if (payload < 0 || payload > Settings->tuya_fnid_map[EnumIdx + 230].dpid ) {
+ return;
+ } else {
+ if (payload != pTuya->EnumState[EnumIdx-1]) {
+ pTuya->EnumState[EnumIdx-1] = payload;
+ TuyaSendEnum(TuyaGetDpId(TUYA_MCU_FUNC_ENUM1 + (EnumIdx-1)), payload);
+ }
+ ResponseCmndIdxNumber(pTuya->EnumState[EnumIdx-1]);
+ }
+ } else {
+ Response_P(PSTR("{\"%s\":{"), XdrvMailbox.command); // Builds TuyaEnum
+ bool added = false;
+ for (uint8_t i = 0; i <= 3; i++) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_ENUM1 + i) != 0) {
+ if (added) {
+ ResponseAppend_P(PSTR(","));
+ }
+ ResponseAppend_P(PSTR("\"Enum%d\":%d"), i + 1, pTuya->EnumState[i]); // Returns the actual values of Enum as list
+ added = true;
+ }
+ }
+ ResponseAppend_P(PSTR("}}"));
+ }
+}
+
+void CmndTuyaEnumList(void) { // Command to declare the number of items in list for up to four type 4 enum. Min = 0, Max = 31, Default = 0
+ if (!pTuya) return;
+
+ if (XdrvMailbox.data_len > 0) {
+ char *p;
+ uint8_t i = 0;
+ uint8_t parm[3] = { 0 };
+ for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 2; str = strtok_r(nullptr, ", ", &p)) {
+ parm[i] = strtoul(str, nullptr, 0);
+ i++;
+ }
+ if ((parm[0] >= 1 && parm[0] <= 4) && (parm[1] >= 1 && parm[1] <= 31)) {
+ uint16_t idx = parm[0] + 230; // fnid 231, 232, 233 and 234 are reserved for enum
+ Settings->tuya_fnid_map[idx].fnid = idx;
+ Settings->tuya_fnid_map[idx].dpid = parm[1];
+ }
+ }
+ if ((TuyaGetDpId(TUYA_MCU_FUNC_ENUM1) != 0) || (TuyaGetDpId(TUYA_MCU_FUNC_ENUM3) != 0) ||
+ (TuyaGetDpId(TUYA_MCU_FUNC_ENUM3) != 0) || (TuyaGetDpId(TUYA_MCU_FUNC_ENUM4) != 0)) {
+ Response_P(PSTR("{\"%s\":{"), XdrvMailbox.command); // Builds TuyaEnumList
+ bool added = false;
+ for (uint8_t i = 0; i <= 3; i++) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_ENUM1 + i) != 0) {
+ if (added) {
+ ResponseAppend_P(PSTR(","));
+ if ( Settings->tuya_fnid_map[i + 231].dpid > 31 ) { Settings->tuya_fnid_map[i + 231].dpid = 0; } // default to 0 it the value exceed the range
+ }
+ ResponseAppend_P(PSTR("\"Enum%d\":%d"), i + 1, Settings->tuya_fnid_map[i + 231].dpid); // fnid 231, 232, 233 and 234 are reserved for Enum
+ added = true;
+ }
+ }
+ ResponseAppend_P(PSTR("}}"));
+ } else { return; }
+}
+
+int StrCmpNoCase(char const *Str1, char const *Str2) // Compare case sensistive RGB strings
+{
+ for (;; Str1++, Str2++) {
+ int StrCmp = tolower((unsigned char)*Str1) - tolower((unsigned char)*Str2);
+ if (StrCmp != 0 || !*Str1) { return StrCmp; }
+ }
+}
+
+float TuyaAdjustedTemperature(int16_t packetValue, uint8_t res)
+{
+ switch (res)
+ {
+ case 1:
+ return (float)packetValue / 10.0;
+ break;
+ case 2:
+ return (float)packetValue / 100.0;
+ break;
+ case 3:
+ return (float)packetValue / 1000.0;
+ break;
+ default:
+ return (float)packetValue;
+ break;
+ }
+}
+
+/*********************************************************************************************\
+ * Internal Functions
+\*********************************************************************************************/
+
+void TuyaAddMcuFunc(uint8_t fnId, uint8_t dpId) {
+ bool added = false;
+
+ if (fnId == 0 || dpId == 0) { // Delete entry
+ for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
+ if ((dpId > 0 && Settings->tuya_fnid_map[i].dpid == dpId) || (fnId > TUYA_MCU_FUNC_NONE && Settings->tuya_fnid_map[i].fnid == fnId)) {
+ Settings->tuya_fnid_map[i].fnid = TUYA_MCU_FUNC_NONE;
+ Settings->tuya_fnid_map[i].dpid = 0;
+ break;
+ }
+ }
+ } else { // Add or update
+ for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
+ if (Settings->tuya_fnid_map[i].dpid == dpId || Settings->tuya_fnid_map[i].dpid == 0 || Settings->tuya_fnid_map[i].fnid == fnId || Settings->tuya_fnid_map[i].fnid == 0) {
+ if (!added) { // Update entry if exisiting entry or add
+ Settings->tuya_fnid_map[i].fnid = fnId;
+ Settings->tuya_fnid_map[i].dpid = dpId;
+ added = true;
+ } else if (Settings->tuya_fnid_map[i].dpid == dpId || Settings->tuya_fnid_map[i].fnid == fnId) { // Remove existing entry if added to empty place
+ Settings->tuya_fnid_map[i].fnid = TUYA_MCU_FUNC_NONE;
+ Settings->tuya_fnid_map[i].dpid = 0;
+ }
+ }
+ }
+ }
+ UpdateDevices();
+}
+
+void UpdateDevices() {
+ for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
+ uint8_t fnId = Settings->tuya_fnid_map[i].fnid;
+ if (fnId > TUYA_MCU_FUNC_NONE && Settings->tuya_fnid_map[i].dpid > 0) {
+
+ if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) { //Relay
+ bitClear(TasmotaGlobal.rel_inverted, fnId - TUYA_MCU_FUNC_REL1);
+ } else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) { // Inverted Relay
+ bitSet(TasmotaGlobal.rel_inverted, fnId - TUYA_MCU_FUNC_REL1_INV);
+ }
+ }
+ }
+}
+
+inline bool TuyaFuncIdValid(uint8_t fnId) {
+ return (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) ||
+ (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) ||
+ (fnId >= TUYA_MCU_FUNC_DIMMER && fnId <= TUYA_MCU_FUNC_REPORT2) ||
+ (fnId >= TUYA_MCU_FUNC_POWER && fnId <= TUYA_MCU_FUNC_POWER_TOTAL) ||
+ (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) ||
+ (fnId >= TUYA_MCU_FUNC_ENUM1 && fnId <= TUYA_MCU_FUNC_ENUM4) ||
+ (fnId >= TUYA_MCU_FUNC_MOTOR_DIR && fnId <= TUYA_MCU_FUNC_DUMMY) ||
+ (fnId == TUYA_MCU_FUNC_LOWPOWER_MODE) ||
+ (fnId >= TUYA_MCU_FUNC_TEMP && fnId <= TUYA_MCU_FUNC_HUMSET) ||
+ (fnId >= TUYA_MCU_FUNC_LX && fnId <= TUYA_MCU_FUNC_PM25) ||
+ (fnId >= TUYA_MCU_FUNC_TIMER1 && fnId <= TUYA_MCU_FUNC_TIMER4);
+}
+
+uint8_t TuyaGetFuncId(uint8_t dpid) {
+ for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
+ if (Settings->tuya_fnid_map[i].dpid == dpid) {
+ return Settings->tuya_fnid_map[i].fnid;
+ }
+ }
+ return TUYA_MCU_FUNC_NONE;
+}
+
+uint8_t TuyaGetDpId(uint8_t fnId) {
+ for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
+ if (Settings->tuya_fnid_map[i].fnid == fnId) {
+ return Settings->tuya_fnid_map[i].dpid;
+ }
+ }
+ return 0;
+}
+
+uint8_t TuyaFnIdIsDimmer(uint8_t fnId){
+ //TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_DIMMER2, TUYA_MCU_FUNC_CT, TUYA_MCU_FUNC_RGB, TUYA_MCU_FUNC_WHITE,
+
+ if ((fnId >= TUYA_MCU_FUNC_DIMMER) &&
+ (fnId <= TUYA_MCU_FUNC_WHITE)){
+ return 1;
+ }
+ return 0;
+}
+
+uint8_t TuyaDpIdIsDimmer(uint8_t dpId){
+ uint8_t fnId = TuyaGetFuncId(dpId);
+ return TuyaFnIdIsDimmer(fnId);
+}
+
+// pTuya->timeout hit zero
+void Tuya_timeout(){
+ // timeout_state should have been set to the correct state to go to after the timeout
+ if (pTuya->startup_state != TUYA_STARTUP_STATE_WAIT_ACK_QUERY){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Protocol timeout state %d -> %d"), pTuya->startup_state, pTuya->timeout_state);
+ }
+ pTuya->startup_state = pTuya->timeout_state;
+ pTuya->timeout = 0;
+}
+
+void TuyaSendCmd(uint8_t cmd, uint8_t payload[] = nullptr, uint16_t payload_len = 0, int noerror = 0)
+{
+ if (!pTuya->inStateMachine && !noerror){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: TuyaSendCmd should only be called from within the state machine! - if this was a manual command, then ok."));
+ }
+
+ // include ver = 0 in checksum for completeness
+ uint8_t checksum = (0xFF + 0x00 + cmd + (payload_len >> 8) + (payload_len & 0xFF));
+ TuyaSerial->write(0x55); // Tuya header 55AA
+ TuyaSerial->write(0xAA);
+ TuyaSerial->write((uint8_t)0x00); // version 00 - send TO MCU
+ TuyaSerial->write(cmd); // Tuya command
+ TuyaSerial->write(payload_len >> 8); // following data length (Hi)
+ TuyaSerial->write(payload_len & 0xFF); // following data length (Lo)
+ char log_data[700]; // Was MAX_LOGSZ
+ snprintf_P(log_data, sizeof(log_data), PSTR("T:>\"55aa00%02x%02x%02x"), cmd, payload_len >> 8, payload_len & 0xFF);
+ for (uint32_t i = 0; i < payload_len; ++i) {
+ TuyaSerial->write(payload[i]);
+ checksum += payload[i];
+ snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x"), log_data, payload[i]);
+ }
+ TuyaSerial->write(checksum);
+ TuyaSerial->flush();
+ snprintf_P(log_data, sizeof(log_data), PSTR("%s%02x\""), log_data, checksum);
+ AddLogData(LOG_LEVEL_DEBUG, log_data);
+ pTuya->sends ++;
+}
+
+
+// note: normally regularly called with defaults
+// ONLY called with cmd, len, data from an incoming command with ver 03.
+// - and this is ONLY used to recognise acks when they occur/are needed.
+void Tuya_statemachine(int cmd = -1, int len = 0, unsigned char *payload = (unsigned char *)0) {
+ pTuya->inStateMachine = 1;
+ int state = pTuya->startup_state;
+ switch (pTuya->startup_state){
+ case TUYA_STARTUP_STATE_INIT://0
+ if (cmd >= 0) break;
+ TuyaSendCmd(TUYA_CMD_HEARTBEAT);
+ pTuya->timeout = 3000;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_INIT;
+ break;
+ case TUYA_STARTUP_STATE_WAIT_ACK_INIT: // 1
+ if (cmd == TUYA_CMD_HEARTBEAT){
+ pTuya->timeout = 0;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_PRODUCT;
+ }
+ break;
+ case TUYA_STARTUP_STATE_PRODUCT: //2
+ if (cmd >= 0) break;
+ TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT);
+ pTuya->timeout = 1000;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_PRODUCT;
+ break;
+ case TUYA_STARTUP_STATE_WAIT_ACK_PRODUCT: // 3
+ if (cmd == TUYA_CMD_QUERY_PRODUCT){
+ pTuya->timeout = 300; // Optional - we will wait 300ms for this after TUYA_CMD_QUERY_PRODUCT response
+ pTuya->timeout_state = TUYA_STARTUP_STATE_CONF; // move on at timeout.
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_OPTIONAL_NEW_FEATURES;
+ }
+ break;
+ case TUYA_STARTUP_STATE_WAIT_OPTIONAL_NEW_FEATURES: // 4
+ /* Optional - we will wait 300ms for this after TUYA_CMD_QUERY_PRODUCT response
+ After the device is powered on,
+ the MCU sends this command to notify the module of feature configuration
+ after the command 0x01 and before the command 0x02.*/
+ if (cmd == TUYA_CMD_NEW_FEATURES){
+ pTuya->timeout = 0;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_CONF;
+ pTuya->startup_state = TUYA_STARTUP_STATE_CONF;
+ }
+ break;
+ case TUYA_STARTUP_STATE_CONF: // 5
+ if (cmd >= 0) break;
+ TuyaSendCmd(TUYA_CMD_MCU_CONF);
+ pTuya->timeout = 1000;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_CONF;
+ break;
+ case TUYA_STARTUP_STATE_WAIT_ACK_CONF: //
+ if (cmd == TUYA_CMD_MCU_CONF){
+ if (len > 0){
+ pTuya->startup_state = TUYA_STARTUP_STATE_QUERY_STATE;
+ } else {
+ pTuya->startup_state = TUYA_STARTUP_STATE_WIFI_STATE;
+ }
+ pTuya->timeout = 0;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ }
+ break;
+
+ case TUYA_STARTUP_STATE_WIFI_STATE: {//
+ uint8_t t = 0x04;
+ if (cmd >= 0) break;
+ TuyaSendCmd(TUYA_CMD_WIFI_STATE, &t, 1);
+ pTuya->timeout = 1000;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_WIFI;
+ } break;
+ case TUYA_STARTUP_STATE_WAIT_ACK_WIFI://
+ if (cmd == TUYA_CMD_WIFI_STATE){
+ pTuya->timeout = 0;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_QUERY_STATE;
+ }
+ break;
+ case TUYA_STARTUP_STATE_QUERY_STATE://
+ if (cmd >= 0) break;
+ TuyaSendCmd(TUYA_CMD_QUERY_STATE);
+ pTuya->timeout = 1000;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_QUERY;
+ break;
+ case TUYA_STARTUP_STATE_WAIT_ACK_QUERY://
+ if (cmd == TUYA_CMD_STATE){
+ // wait a further 500ms for the next command.
+ // only on timeout, move on to runtime
+ pTuya->timeout = 500;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_QUERY;
+ }
+ break;
+
+ // we hit runtime.....
+ case TUYA_STARTUP_STATE_SEND_CMD://
+ if (pTuya->send_time & 1){
+ TuyaSetTime();
+ pTuya->send_time &= 0xfe;
+ // ??? TODO - if no MCU support, we'll just wait 100ms.
+ // we should *not* get a response - as this is normally a command which is requested
+ pTuya->expectedResponseCmd = TUYA_CMD_SET_TIME;
+ // always wait a bit before sending anything else, otherwise we may overflow the MCU input buffer.
+ pTuya->timeout = 200;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_CMD;
+ break;
+ }
+
+ if (pTuya->wifi_state != TuyaGetTuyaWifiState()) {
+ pTuya->wifi_state = TuyaGetTuyaWifiState();
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Set WiFi LED %d (%d)"), pTuya->wifi_state, WifiState());
+ if (pTuya->low_power_mode) {
+ TuyaSendCmd(TUYA_LOW_POWER_CMD_WIFI_STATE, &pTuya->wifi_state, 1);
+ pTuya->expectedResponseCmd = TUYA_CMD_WIFI_STATE; // ??? TODO
+ pTuya->timeout = 300;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_CMD;
+ break;
+ } else {
+ TuyaSendCmd(TUYA_CMD_WIFI_STATE, &pTuya->wifi_state, 1);
+ pTuya->expectedResponseCmd = TUYA_CMD_WIFI_STATE;
+ pTuya->timeout = 300;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_CMD;
+ break;
+ }
+ }
+
+ if (pTuya->low_power_mode) {
+ if (pTuya->send_success_next_second) {
+ uint8_t success = 1;
+ TuyaSendCmd(TUYA_LOW_POWER_CMD_STATE, &success, 1);
+ pTuya->expectedResponseCmd = TUYA_LOW_POWER_CMD_STATE; // ?? TODO - if no resp, we'll wait 300ms
+ pTuya->timeout = 300;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_CMD;
+ pTuya->send_success_next_second = false;
+ break;
+ }
+ //TuyaSendLowPowerSuccessIfNeeded();
+ }
+
+ // send any DP chang requests
+ // only if different from the received or last send values
+ int i;
+ for (i = 0; i < pTuya->numRxedDPids; i++){
+ TUYA_DP_STORE *dp = &pTuya->DPStore[i];
+ // if set requested, and MCU has reported at least once
+ if (dp->toSet && dp->rxed){
+ // if value is different
+ if ((dp->rxedValueLen != dp->desiredValueLen) || memcmp(dp->rxedValue, dp->desiredValue, dp->desiredValueLen)){
+ uint8_t send = 1;
+ if (TuyaDpIdIsDimmer(dp->DPid)){
+ uint8_t fnId = TuyaGetFuncId(dp->DPid);
+ uint8_t dimindex = 0;
+ if (fnId == TUYA_MCU_FUNC_DIMMER2){ // first dimmer
+ dimindex = 1;
+ }
+ // set every time a dim value is rxed, and if just turned on
+ if (pTuya->dimDelay_ms[dimindex]){
+ if (pTuya->dimDebug & (1<dimDelay_ms[dimindex]);
+ pTuya->dimDebug &= (0xff ^ (1<dimCmdEnable & (1<dimDebug & (1<dimDebug &= (0xff ^ (1<DPid,
+ dp->Type,
+ (uint8_t*)dp->desiredValue, dp->desiredValueLen);
+ // assume it worked? maybe not
+ //dp->rxedValueLen = dp->desiredValueLen;
+ //memcpy(dp->rxedValue, dp->desiredValue, dp->desiredValueLen);
+ dp->toSet = 0;
+ pTuya->expectedResponseCmd = TUYA_CMD_STATE;
+ pTuya->timeout = 300;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_CMD;
+#ifdef TUYA_MORE_DEBUG
+ MqttPublishLoggingAsync(false);
+ SyslogAsync(false);
+#endif
+
+ break;
+ }
+ } else {
+ // if equal values, ignore set
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DPset ign-same value dp%d=0x%x,%d"), dp->DPid, dp->desiredValue[0], dp->desiredValueLen);
+ dp->toSet = 0;
+ }
+ }
+ }
+
+ // triggered from second timer
+ if (pTuya->send_heartbeat) {
+ pTuya->send_heartbeat = 0;
+ pTuya->startup_state = TUYA_STARTUP_STATE_SEND_HEARTBEAT;
+ break;
+ }
+ break;
+
+ case TUYA_STARTUP_STATE_WAIT_ACK_CMD:
+ if (cmd == pTuya->expectedResponseCmd){
+ pTuya->timeout = 0;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_SEND_CMD;
+ }
+ break;
+
+ case TUYA_STARTUP_STATE_SEND_HEARTBEAT://
+ // send a heartbeat, and wait up to a second
+ if (cmd >= 0) break;
+ TuyaSendCmd(TUYA_CMD_HEARTBEAT);
+ pTuya->timeout = 1000;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_INIT;
+ pTuya->startup_state = TUYA_STARTUP_STATE_WAIT_ACK_HEARTBEAT;
+ break;
+
+ // wait for heartbeat return
+ case TUYA_STARTUP_STATE_WAIT_ACK_HEARTBEAT://
+ if (cmd == TUYA_CMD_HEARTBEAT){
+ pTuya->timeout = 0;
+ pTuya->timeout_state = TUYA_STARTUP_STATE_SEND_CMD;
+ pTuya->startup_state = TUYA_STARTUP_STATE_SEND_CMD;
+ if (len > 0 && payload[0] == 0){
+ pTuya->startup_state = TUYA_STARTUP_STATE_INIT;
+ }
+ }
+ if (cmd == TUYA_CMD_STATE){
+ // dealt with in receive
+ }
+ break;
+ }
+
+ if (state != pTuya->startup_state){
+ AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("TYA: %d->%d-%d/%d"), state, pTuya->startup_state, pTuya->sends, pTuya->rxs);
+ }
+
+ pTuya->inStateMachine = 0;
+
+}
+
+void TuyaDumpDPStore(){
+#ifdef TUYA_MORE_DEBUG
+ for (int i = 0; i < pTuya->numRxedDPids; i++){
+ TUYA_DP_STORE *dp = &pTuya->DPStore[i];
+
+/*
+ dp->DPid;
+ dp->Type;
+ dp->rxedValue[TUYA_MAX_STRING_SIZE];
+ dp->desiredValue[TUYA_MAX_STRING_SIZE];
+ dp->toSet;
+ dp->rxed;
+*/
+
+ switch(dp->Type){
+ case TUYA_TYPE_RAW:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DP%d T%d m:0x%X d0x%X s%d r%d"),
+ dp->DPid, dp->Type, dp->rxedValue[0], dp->desiredValue[0], dp->toSet, dp->rxed);
+ break;
+ case TUYA_TYPE_BOOL:
+ case TUYA_TYPE_ENUM:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DP%d T%d m0x%X d0x%X s%d r%d"),
+ dp->DPid, dp->Type, dp->rxedValue[0], dp->desiredValue[0], dp->toSet, dp->rxed);
+ break;
+ case TUYA_TYPE_VALUE:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DP%d T%d m%d d%d s%d r%d"),
+ dp->DPid, dp->Type, TUYAREAD32FROMPTR(dp->rxedValue), TUYAREAD32FROMPTR(dp->desiredValue), dp->toSet, dp->rxed);
+ break;
+ case TUYA_TYPE_STRING:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DP%d T%d m0x%X d0x%X s%d r%d"),
+ dp->DPid, dp->Type, dp->rxedValue[0], dp->desiredValue[0], dp->toSet, dp->rxed);
+ break;
+ }
+ }
+#endif
+}
+
+// sets a desired value for a DPId,
+// and sets a flag to say we want this value.
+// this is then serviced later to ensure we don't send the same value twice.
+// this solves an issue with some wallplate touch dimmers
+// which are killed by sending off when the device is already off.
+void TuyaPostState(uint8_t id, uint8_t type, uint8_t *value, int len = 4){
+ int i;
+ if (!pTuya){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: PostState before pTuya DP %d"), id);
+ return;
+ }
+
+ for (i = 0; i < pTuya->numRxedDPids; i++){
+ TUYA_DP_STORE *dp = &pTuya->DPStore[i];
+/*
+ dp->DPid;
+ dp->Type;
+ dp->rxedValue[TUYA_MAX_STRING_SIZE];
+ dp->desiredValue[TUYA_MAX_STRING_SIZE];
+ dp->toSet;
+ dp->rxed;
+*/
+ if (id == dp->DPid){
+ if (type == dp->Type){
+ if (len <= TUYA_MAX_STRING_SIZE){
+ memcpy(dp->desiredValue, value, len);
+ dp->desiredValueLen = len;
+ dp->toSet = 1;
+ pTuya->requestSend = 1;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DP%d des v set (0x%x,%d)"), id, dp->desiredValue[0], dp->desiredValueLen);
+
+ if (TuyaDpIdIsDimmer(id)){
+ pTuya->dimDebug = 1; // enable debug to be printed once.
+ }
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: DP %d value over len (%d > %d)"), id, len, TUYA_MAX_STRING_SIZE);
+ }
+ break;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: set of dpid %d ignored - type %d != requred %d"), id, type, dp->Type);
+ TuyaDumpDPStore();
+ return;
+ }
+ }
+ }
+ if (i == pTuya->numRxedDPids){
+ if (pTuya->numRxedDPids < TUYA_MAX_STORED_DPs){
+ TUYA_DP_STORE *dp = &pTuya->DPStore[pTuya->numRxedDPids];
+ dp->DPid = id;
+ dp->Type = type;
+ if (len <= TUYA_MAX_STRING_SIZE){
+ memcpy(dp->desiredValue, value, len);
+ dp->desiredValueLen = len;
+ dp->toSet = 1;
+ pTuya->requestSend = 1;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: NEW DP %d desiredvalue set (0x%08x len %d)"), id, dp->desiredValue[0], dp->desiredValueLen);
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: DP %d value over len (%d > %d)"), id, len, TUYA_MAX_STRING_SIZE);
+ }
+ pTuya->numRxedDPids++;
+#ifdef TUYA_MORE_DEBUG
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Add unknown dpid %d in set - num DP:%d"), id, pTuya->numRxedDPids);
+#endif
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Max Stored DPs exceeded at set of unknown dpid %d ignored - num DP:%d"), id, pTuya->numRxedDPids);
+ }
+ }
+#ifdef TUYA_MORE_DEBUG
+ switch(type){
+ case TUYA_TYPE_RAW:
+ case TUYA_TYPE_BOOL:
+ case TUYA_TYPE_ENUM:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: dp%d to %d req"), id, *(uint8_t*)value);
+ break;
+ case TUYA_TYPE_VALUE:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: dp%d to %d req"), id, TUYAREAD32FROMPTR(value));
+ break;
+ case TUYA_TYPE_STRING:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: dp%d to (?) req"), id);
+ break;
+ }
+ TuyaDumpDPStore();
+#endif
+}
+
+
+// note - direct send using TuyaSendCmd
+void TuyaSendState(uint8_t id, uint8_t type, uint8_t* value, int len)
+{
+ uint16_t payload_len = 4;
+ uint8_t payload_buffer[8+TUYA_MAX_STRING_SIZE];
+ payload_buffer[0] = id;
+ payload_buffer[1] = type;
+ switch (type) {
+ case TUYA_TYPE_BOOL:
+ case TUYA_TYPE_ENUM:
+ payload_len += 1;
+ payload_buffer[2] = 0x00;
+ payload_buffer[3] = 0x01;
+ payload_buffer[4] = value[0];
+ break;
+ case TUYA_TYPE_VALUE:
+ payload_len += 4;
+ payload_buffer[2] = 0x00;
+ payload_buffer[3] = 0x04;
+ // note - already reversed
+ payload_buffer[4] = value[0];
+ payload_buffer[5] = value[1];
+ payload_buffer[6] = value[2];
+ payload_buffer[7] = value[3];
+ break;
+ case TUYA_TYPE_STRING:
+ case TUYA_TYPE_RAW:
+ payload_buffer[2] = len >> 8;
+ payload_buffer[3] = len & 0xFF;
+
+ if (len <= TUYA_MAX_STRING_SIZE){
+ for (uint16_t i = 0; i < len; i++) {
+ payload_buffer[payload_len++] = value[i];
+ }
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: SendState: DP %d value over len (%d > %d)"), id, len, TUYA_MAX_STRING_SIZE);
+ return;
+ }
+ break;
+ }
+
+ TuyaSendCmd(TUYA_CMD_SET_DP, payload_buffer, payload_len);
+}
+
+void TuyaSendBool(uint8_t id, bool value)
+{
+ TuyaPostState(id, TUYA_TYPE_BOOL, (uint8_t*)&value, 1);
+}
+
+void TuyaSendValue(uint8_t id, uint32_t value)
+{
+ uint32_t reversed = TUYAREAD32FROMPTR(&value);
+ TuyaPostState(id, TUYA_TYPE_VALUE, (uint8_t*)&reversed, 4);
+}
+
+void TuyaSendEnum(uint8_t id, uint32_t value)
+{
+ TuyaPostState(id, TUYA_TYPE_ENUM, (uint8_t*)&value, 1);
+}
+
+static uint16_t convertHexStringtoBytes (uint8_t * dest, const char src[], uint16_t dest_len){
+ if (NULL == dest || NULL == src || 0 == dest_len){
+ return 0;
+ }
+
+ char hexbyte[3];
+ hexbyte[2] = 0;
+ uint16_t i;
+
+ for (i = 0; i < dest_len; i++) {
+ hexbyte[0] = src[2*i];
+ hexbyte[1] = src[2*i+1];
+ dest[i] = strtol(hexbyte, NULL, 16);
+ }
+
+ return i;
+}
+
+// note - send immediate, not deferred
+void TuyaSendHexString(uint8_t id, const char data[]) {
+
+ uint16_t len = strlen(data)/2;
+ uint8_t value[len];
+ convertHexStringtoBytes(value, data, len);
+ TuyaPostState(id, TUYA_TYPE_STRING, value, len);
+}
+
+// note - send immediate, not deferred
+void TuyaSendString(uint8_t id, const char data[]) {
+ uint16_t len = strlen(data);
+ TuyaPostState(id, TUYA_TYPE_STRING, (uint8_t*) data, len);
+}
+
+void TuyaSendRaw(uint8_t id, const char data[]) {
+ const char* beginPos = strchr(data, 'x');
+ if(!beginPos) {
+ beginPos = strchr(data, 'X');
+ }
+ if(!beginPos) {
+ beginPos = data;
+ } else {
+ beginPos += 1;
+ }
+ uint16_t strSize = strlen(beginPos);
+ uint16_t len = strSize/2;
+ uint8_t value[len];
+ convertHexStringtoBytes(value, beginPos, len);
+ TuyaPostState(id, TUYA_TYPE_RAW, value, len);
+}
+
+// send ANY cmd with payload from hex string
+void TuyaSendRawCmd(uint8_t cmd, const char data[]) {
+ uint16_t strSize = strlen(data);
+ uint16_t len = strSize/2;
+ uint8_t value[len];
+ convertHexStringtoBytes(value, data, len);
+ TuyaSendCmd(cmd, value, len, 1);
+}
+
+
+bool TuyaSetPower(void)
+{
+ bool status = false;
+
+ uint8_t rpower = XdrvMailbox.index;
+ int16_t source = XdrvMailbox.payload;
+
+ uint8_t dpid = TuyaGetDpId(TUYA_MCU_FUNC_REL1 + TasmotaGlobal.active_device - 1);
+ if (dpid == 0) dpid = TuyaGetDpId(TUYA_MCU_FUNC_REL1_INV + TasmotaGlobal.active_device - 1);
+ uint8_t dev = TasmotaGlobal.active_device-1;
+ uint8_t value = bitRead(rpower, dev) ^ bitRead(TasmotaGlobal.rel_inverted, dev);
+
+ if (source != SRC_SWITCH && TuyaSerial && dpid) { // ignore to prevent loop from pushing state from faceplate interaction
+ TuyaSendBool(dpid, value);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: post rpower%d v%d dp%d s%d d%d"), rpower, value, dpid, source, dev);
+ // no longer needed as commands wait for ack.
+ //delay(20); // Hack when power is off and dimmer is set then both commands go too soon to Serial out.
+ status = true;
+ } else {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: rpower%d v%d dp%d ignored s%d d%d"), rpower, value, dpid, source, dev);
+ }
+ return status;
+}
+
+bool TuyaSetChannels(void)
+{
+ uint16_t hue, TuyaData;
+ uint8_t sat, bri;
+ uint8_t TuyaIdx = 0;
+ char hex_char[15];
+ bool noupd = false;
+
+ if ((SRC_SWITCH == TasmotaGlobal.last_source) || (SRC_SWITCH == TasmotaGlobal.last_command_source)) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: setchan disbl SRC_SWITCH"));
+ // but pretend we did set them
+ return true;
+ }
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: setchan"));
+
+ bool LightMode = TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0;
+ uint8_t idx = 0;
+ snprintf_P(hex_char, sizeof(hex_char), PSTR("000000000000"));
+
+ if (LT_SERIAL1 == TasmotaGlobal.light_type) {
+ pTuya->Snapshot[0] = light_state.getDimmer();
+ }
+
+ if (LT_SERIAL2 == TasmotaGlobal.light_type || LT_RGBWC == TasmotaGlobal.light_type) {
+ idx = 1;
+ if (LT_SERIAL2 == TasmotaGlobal.light_type &&
+ Settings->flag3.pwm_multi_channels &&
+ (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2) != 0)) {
+ // Special setup for dual dimmer (like the MOES 2 Way Dimmer) emulating 2 PWM channels
+ pTuya->Snapshot[0] = changeUIntScale(Light.current_color[0], 0, 255, 0, 100);
+ pTuya->Snapshot[1] = changeUIntScale(Light.current_color[1], 0, 255, 0, 100);
+ } else { // CT Light or RGBWC
+ getCTRange(&pTuya->CTMin, &pTuya->CTMax); // SetOption82 - Reduce the CT range from 153..500 to 200..380 to accomodate with Alexa range
+ pTuya->Snapshot[0] = light_state.getDimmer();
+ pTuya->Snapshot[1] = light_state.getCT();
+ }
+ }
+
+ if (LT_RGBW == TasmotaGlobal.light_type) {
+ idx = 1;
+ pTuya->Snapshot[0] = light_state.getDimmer(1);
+ pTuya->Snapshot[1] = light_state.getDimmer(2);
+ }
+
+ if (TasmotaGlobal.light_type > LT_BASIC) {
+
+ if (LT_RGB != TasmotaGlobal.light_type) {
+ for (uint8_t i = 0; i <= idx; i++) {
+ if (pTuya->Snapshot[i] != pTuya->Levels[i]) {
+ if (i == 0 && LightMode && pTuya->ModeSet ) { noupd = true;}
+ if (!noupd) {
+ LightSerialDuty(pTuya->Snapshot[i], &hex_char[0], i+1);
+ //pTuya->Levels[i] = pTuya->Snapshot[i];
+ }
+ noupd = false;
+ }
+ }
+ }
+
+ if (TasmotaGlobal.light_type >= LT_RGB) {
+
+ // There are two types of rgb format, configure the correct one using TuyaRGB command.
+ // The most common is 0HUE0SAT0BRI0 and the less common is RRGGBBFFFF6464 and sometimes both are case sensitive:
+ // 0 type 1 Uppercase - 00DF00DC0244
+ // 1 Type 1 Lowercase - 008003e8037a
+ // 2 Type 2 Uppercase - 00FF00FFFF6464
+ // 3 Type 2 Lowercase - 00e420ffff6464
+
+ uint8_t RGBType = Settings->tuya_fnid_map[230].dpid; // Select the type of RGB payload
+ char scolor[7];
+ LightGetColor(scolor, 1); // Always get the color in hex format
+ light_state.getHSB(&hue, &sat, &bri);
+ sat = changeUIntScale(sat, 0, 255, 0, 100);
+ bri = changeUIntScale(bri, 0, 255, 0, 100);
+
+ if ((RGBType > 1 && (StrCmpNoCase(scolor, pTuya->RGBColor) != 0)) ||
+ (RGBType <= 1 && ((hue != pTuya->Snapshot[2]) || (sat != pTuya->Snapshot[3]) || (bri != pTuya->Snapshot[4])) )) {
+
+ if ((LightMode && pTuya->ModeSet) ||
+ LT_RGB == TasmotaGlobal.light_type) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0) {
+ switch (RGBType) {
+ case 0: // Uppercase Type 1 payload
+ snprintf_P(hex_char, sizeof(hex_char), PSTR("%04X%04X%04X"), hue, sat * 10, bri * 10);
+ break;
+ case 1: // Lowercase Type 1 payload
+ snprintf_P(hex_char, sizeof(hex_char), PSTR("%04x%04x%04x"), hue, sat * 10, bri * 10);
+ break;
+ case 2: // Uppercase Type 2 payload
+ snprintf_P(hex_char, sizeof(hex_char), PSTR("%sFFFF6464"), scolor);
+ break;
+ case 3: // Lowercase Type 2 payload
+ snprintf_P(hex_char, sizeof(hex_char), PSTR("%sffff6464"), LowerCase(scolor, scolor));
+ break;
+ }
+ memcpy_P(pTuya->RGBColor, scolor, strlen(scolor));
+ pTuya->Snapshot[2] = hue;
+ pTuya->Snapshot[3] = sat;
+ pTuya->Snapshot[4] = bri;
+ }
+ LightSerialDuty(0, &hex_char[0], 3);
+ }
+ }
+ }
+ }
+ return true;
+}
+
+void LightSerialDuty(uint16_t duty, char *hex_char, uint8_t TuyaIdx)
+{
+ uint8_t dpid = TuyaGetDpId(TUYA_MCU_FUNC_DIMMER);
+ bool CTLight = false;
+
+ if (TuyaIdx > 0 && TuyaIdx <= 2) {
+
+ if (TuyaIdx == 2) {
+ if (!Settings->flag3.pwm_multi_channels) {
+ CTLight = true;
+ dpid = TuyaGetDpId(TUYA_MCU_FUNC_CT);
+ } else {
+ dpid = TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2);
+ }
+ }
+
+// if (pTuya->ignore_dim && pTuya->ignore_dimmer_cmd_timeout < millis()) {
+// pTuya->ignore_dim = false;
+// }
+ pTuya->ignore_dim = false;
+
+ if (duty > 0 && !pTuya->ignore_dim && TuyaSerial && dpid > 0) {
+ if (TuyaIdx == 2 && CTLight) {
+ duty = changeUIntScale(duty, pTuya->CTMin, pTuya->CTMax, Settings->dimmer_hw_max, 0);
+ } else {
+ duty = changeUIntScale(duty, 0, 100, Settings->dimmer_hw_min, Settings->dimmer_hw_max);
+ }
+
+ // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself
+ if (duty < Settings->dimmer_hw_min) {
+ duty = Settings->dimmer_hw_min;
+ }
+
+ //pTuya->ignore_dimmer_cmd_timeout = millis() + 250; // Ignore serial received dim commands for the next 250ms
+ if (pTuya->ModeSet &&
+ (TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0) &&
+ TasmotaGlobal.light_type > LT_RGB) {
+ TuyaSendEnum(TuyaGetDpId(TUYA_MCU_FUNC_MODESET), 0);
+ }
+ TuyaSendValue(dpid, duty);
+
+ } else {
+ if (dpid > 0 && TuyaIdx <= 2) {
+ int tasduty = duty;
+
+ pTuya->ignore_dim = false; // reset flag
+
+ if (TuyaIdx == 2 && CTLight) {
+ duty = changeUIntScale(duty, pTuya->CTMin, pTuya->CTMax, Settings->dimmer_hw_max, 0);
+ } else {
+ duty = changeUIntScale(duty, 0, 100, Settings->dimmer_hw_min, Settings->dimmer_hw_max);
+ }
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: dim skip duty%d v%d dp%d"), tasduty, duty, dpid); // due to 0 or already set
+ } else {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Cannot set dimmer. Dimmer Id unknown"));
+ }
+ }
+ }
+
+ if (TuyaIdx == 3) {
+ dpid = TuyaGetDpId(TUYA_MCU_FUNC_RGB);
+ if (!pTuya->ModeSet &&
+ (TuyaGetDpId(TUYA_MCU_FUNC_MODESET) != 0) &&
+ TasmotaGlobal.light_type > LT_RGB) {
+ TuyaSendEnum(TuyaGetDpId(TUYA_MCU_FUNC_MODESET), 1);
+ }
+ TuyaSendString(dpid, hex_char);
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: TX RGB hex %s to dpId %d"), hex_char, dpid);
+ }
+}
+
+// only use manually!!!
+void TuyaRequestState(uint8_t state_type)
+{
+ if (TuyaSerial) {
+ // Get current status of MCU
+#ifdef TUYA_MORE_DEBUG
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Read MCU state"));
+#endif
+ pTuya->SuspendTopic = true;
+ pTuya->ignore_topic_timeout = millis() + 1000; // suppress /STAT topic for 1000ms to limit data
+ switch (state_type) {
+ case 0:
+ TuyaSendCmd(TUYA_CMD_QUERY_STATE);
+ break;
+ case 8:
+ TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT);
+ break;
+ }
+ }
+}
+
+void TuyaResetWifi(void)
+{
+ if (!Settings->flag.button_restrict) { // SetOption1 - Control button multipress
+ if (pTuya->wifiTimer > 20000){
+ char scmnd[20];
+ snprintf_P(scmnd, sizeof(scmnd), D_CMND_WIFICONFIG " %d", 2);
+ ExecuteCommand(scmnd, SRC_BUTTON);
+ }
+ pTuya->wifiTimer += 10000;
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Wifi reset button pressed. Press repeatedly to achieve reset"));
+ }
+}
+
+
+///////////////////////////////////////
+// store all DPs received with values,
+// these are used so we don't send DP value which are the same
+// as the MCU has already - e.g. double 'off' can crash dimmers
+void TuyaStoreRxedDP(uint8_t dpid, uint8_t type, uint8_t *data, int dpDataLen){
+ int i;
+ for (i = 0; i < pTuya->numRxedDPids; i++){
+ TUYA_DP_STORE *dp = &pTuya->DPStore[i];
+ if (dp->DPid == dpid){
+ if (type != dp->Type){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Type change in rxed dpId=%d type %d -> %d"), dpid, dp->Type, type);
+ dp->Type = type;
+ }
+
+ // if a relay command, then set dim delay, and if value is zero, disable dim command.
+ // if 1, enable dim command.
+ // make it work for single or dual dimmers...
+ uint8_t fnId = TuyaGetFuncId(dpid);
+ if ((fnId == TUYA_MCU_FUNC_REL1) ||
+ (fnId == TUYA_MCU_FUNC_REL1_INV) ||
+ (fnId == TUYA_MCU_FUNC_REL2) ||
+ (fnId == TUYA_MCU_FUNC_REL2_INV)){
+ uint8_t dimindex = 0;
+ if ((fnId == TUYA_MCU_FUNC_REL2) ||
+ (fnId == TUYA_MCU_FUNC_REL2_INV)){
+ dimindex = 1;
+ }
+
+ pTuya->dimDelay_ms[dimindex] = pTuya->defaultDimDelay_ms;
+ int value = data[0];
+ if (!value){
+ pTuya->dimCmdEnable &= 0xfe; (0xff ^ (1<dimCmdEnable |= (1<rxedValue, data, dpDataLen);
+ dp->rxedValueLen = dpDataLen;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: DP len exceeded dpId=%d type %d (%d > %d"), dpid, type, dpDataLen, TUYA_MAX_STRING_SIZE);
+ }
+ dp->rxed = 1;
+ break;
+ }
+ }
+ if (i == pTuya->numRxedDPids){
+ if (i < TUYA_MAX_STORED_DPs){
+ TUYA_DP_STORE *dp = &pTuya->DPStore[i];
+ dp->DPid = dpid;
+ dp->Type = type;
+ if (dpDataLen <= TUYA_MAX_STRING_SIZE){
+ memcpy(dp->rxedValue, data, dpDataLen);
+ dp->rxedValueLen = dpDataLen;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: DP len exceeded dpId=%d type %d (%d > %d"), dpid, type, dpDataLen, TUYA_MAX_STRING_SIZE);
+ }
+ dp->rxed = 1;
+ pTuya->numRxedDPids++;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Max stored DPs exceeded dpId=%d type %d"), dpid, type);
+ }
+ }
+ TuyaDumpDPStore();
+}
+
+
+////////////////////////////////////////////////
+// process ONE rxed DP value
+void TuyaProcessRxedDP(uint8_t dpid, uint8_t type, uint8_t *data, int dpDataLen){
+ char scmnd[20];
+ bool PowerOff = false;
+ bool tuya_energy_enabled = (XNRG_32 == TasmotaGlobal.energy_driver);
+ uint8_t fnId = TuyaGetFuncId(dpid);
+ uint32_t value = 0;
+
+ if (TuyaFnIdIsDimmer(fnId)){
+ if (fnId == TUYA_MCU_FUNC_DIMMER){ // first dimmer
+ pTuya->dimDelay_ms[0] = pTuya->defaultDimDelay_ms;
+ } else {
+ if (fnId == TUYA_MCU_FUNC_DIMMER2){ // second dimmer
+ pTuya->dimDelay_ms[1] = pTuya->defaultDimDelay_ms;
+ } else { // must be other light, single dimmable thing
+ pTuya->dimDelay_ms[0] = pTuya->defaultDimDelay_ms;
+ }
+ }
+ }
+
+ ////////////////////
+ // get value for types that fit in 4 byte as uint32_t
+ switch(type){
+ case TUYA_TYPE_RAW: // variable length combined?
+ break;
+ case TUYA_TYPE_BOOL: // 1 = 1 byte bool
+ value = data[0];
+ break;
+ case TUYA_TYPE_VALUE: // 2 = 32 bit int
+ value = TUYAREAD32FROMPTR(data);
+ break;
+ case TUYA_TYPE_STRING: // 3
+ break;
+ case TUYA_TYPE_ENUM: // 4 = 1 byte value
+ value = data[0];
+ break;
+ }
+ //////////////////
+
+
+ // incorporated into logs below to save one log line.
+ //AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d is set for dpId=%d"), fnId, dpid);
+ switch(type) {
+ case TUYA_TYPE_RAW: {
+#ifdef USE_ENERGY_SENSOR
+ if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_COMBINED) {
+ if (dpDataLen >= 8) {
+ // data is pTuya->buffer[dpidStart + 4];
+ uint16_t tmpVol = data[4 - 4] << 8 | data[5 - 4];
+ uint16_t tmpCur = data[7 - 4] << 8 | data[8 - 4];
+ uint16_t tmpPow = data[10 - 4] << 8 | data[11 - 4];
+/* uint16_t tmpVol = pTuya->buffer[dpidStart + 4] << 8 | pTuya->buffer[dpidStart + 5];
+ uint16_t tmpCur = pTuya->buffer[dpidStart + 7] << 8 | pTuya->buffer[dpidStart + 8];
+ uint16_t tmpPow = pTuya->buffer[dpidStart + 10] << 8 | pTuya->buffer[dpidStart + 11];*/
+ Energy.voltage[0] = (float)tmpVol / 10;
+ Energy.current[0] = (float)tmpCur / 1000;
+ Energy.active_power[0] = (float)tmpPow;
+
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d Rx ID=%d Voltage=%d Current=%d Active_Power=%d"), fnId, dpid, tmpVol, tmpCur, tmpPow);
+
+ if (RtcTime.valid) {
+ if (pTuya->lastPowerCheckTime != 0 && Energy.active_power[0] > 0) {
+ Energy.kWhtoday[0] += Energy.active_power[0] * (float)(Rtc.utc_time - pTuya->lastPowerCheckTime) / 36.0;
+ EnergyUpdateToday();
+ }
+ pTuya->lastPowerCheckTime = Rtc.utc_time;
+ }
+ } else {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d Rx ID=%d INV_LEN=%d"), fnId, dpid, dpDataLen);
+ }
+ }
+ #endif // USE_ENERGY_SENSOR
+ } break;
+
+ case TUYA_TYPE_BOOL: { // Data Type 1
+ if (fnId >= TUYA_MCU_FUNC_REL1 && fnId <= TUYA_MCU_FUNC_REL8) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("T:fn%d Relay%d-->M%s T%s"), fnId, fnId - TUYA_MCU_FUNC_REL1 + 1, value?"On":"Off",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)?"On":"Off");
+ if (value != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1)) {
+ if (!value) { PowerOff = true; }
+ ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1 + 1, value, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
+ }
+ } else if (fnId >= TUYA_MCU_FUNC_REL1_INV && fnId <= TUYA_MCU_FUNC_REL8_INV) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("T:fn%d Relay%d-Inv-->M%s T%s"), fnId, fnId - TUYA_MCU_FUNC_REL1_INV + 1, value?"Off":"On",bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1?"Off":"On");
+ if (value != bitRead(TasmotaGlobal.power, fnId - TUYA_MCU_FUNC_REL1_INV) ^ 1) {
+ ExecuteCommandPower(fnId - TUYA_MCU_FUNC_REL1_INV + 1, value ^ 1, SRC_SWITCH); // send SRC_SWITCH? to use as flag to prevent loop from inbound states from faceplate interaction
+ if (value) { PowerOff = true; }
+ }
+ } else if (fnId >= TUYA_MCU_FUNC_SWT1 && fnId <= TUYA_MCU_FUNC_SWT4) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("T:fn%d Switch%d --> M%d T%d"),fnId, fnId - TUYA_MCU_FUNC_SWT1 + 1, value, SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1));
+
+ if (SwitchGetVirtual(fnId - TUYA_MCU_FUNC_SWT1) != value) {
+ SwitchSetVirtual(fnId - TUYA_MCU_FUNC_SWT1, value);
+ SwitchHandler(1);
+ }
+ }
+ //if (PowerOff) { pTuya->ignore_dimmer_cmd_timeout = millis() + 250; }
+ } break;
+
+ case TUYA_TYPE_VALUE: { // Data Type 2
+ uint32_t packetValue = value; // TYpe 2 is a 32 bit integer
+ uint8_t dimIndex;
+ bool SnsUpdate = false;
+
+ if ((fnId >= TUYA_MCU_FUNC_TEMP) && (fnId <= TUYA_MCU_FUNC_TIMER4)) { // Sensors start from fnId 71
+ if (packetValue != pTuya->Sensors[fnId-71]) {
+ pTuya->SensorsValid[fnId-71] = true;
+ pTuya->Sensors[fnId-71] = packetValue;
+ SnsUpdate = true;
+ }
+ }
+
+ if (SnsUpdate) {
+ char sname[20];
+ char tempval[5];
+ uint8_t res;
+ bool dont_publish = Settings->flag5.tuyasns_no_immediate;
+
+ if (TasmotaGlobal.uptime < 8) { // delay to avoid multiple topics at the same time at boot time
+ return;
+ } else {
+ if (fnId > 80 || fnId == 74 || fnId == 72) {
+ dont_publish = false;
+ }
+ if (fnId > 74) {
+ res = 0;
+ } else if (fnId > 72) {
+ res = Settings->flag2.humidity_resolution;
+ } else if (fnId == 72) {
+ res = Settings->mbflag2.temperature_set_res;
+ } else {
+ res = Settings->flag2.temperature_resolution;
+ }
+ GetTextIndexed(sname, sizeof(sname), (fnId-71), kTuyaSensors);
+ ResponseClear(); // Clear retained message
+ Response_P(PSTR("{\"TuyaSNS\":{\"%s\":%s}}"), sname, dtostrfd(TuyaAdjustedTemperature(packetValue, res), res, tempval)); // sensor update is just on change
+ if (dont_publish) {
+ XdrvRulesProcess(0);
+ } else {
+ MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_CMND_SENSOR));
+ }
+ }
+ }
+
+ if (fnId == TUYA_MCU_FUNC_DIMMER || fnId == TUYA_MCU_FUNC_REPORT1) { dimIndex = 0; }
+
+ if (fnId == TUYA_MCU_FUNC_DIMMER2 || fnId == TUYA_MCU_FUNC_REPORT2 || fnId == TUYA_MCU_FUNC_CT) { dimIndex = 1; }
+
+ if (dimIndex == 1 && !Settings->flag3.pwm_multi_channels) {
+ pTuya->Levels[1] = changeUIntScale(packetValue, 0, Settings->dimmer_hw_max, pTuya->CTMax, pTuya->CTMin);
+ } else {
+ pTuya->Levels[dimIndex] = changeUIntScale(packetValue, Settings->dimmer_hw_min, Settings->dimmer_hw_max, 0, 100);
+ }
+
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fn%d value %d dp%d "), fnId, packetValue, dpid);
+
+ if ((fnId == TUYA_MCU_FUNC_DIMMER) || (fnId == TUYA_MCU_FUNC_REPORT1) ||
+ (fnId == TUYA_MCU_FUNC_DIMMER2) || (fnId == TUYA_MCU_FUNC_REPORT2) ||
+ (fnId == TUYA_MCU_FUNC_CT) || (fnId == TUYA_MCU_FUNC_WHITE)) {
+
+ // SetOption54 - Apply SetOption20 settings to Tuya device / SetOption131 Allow save dimmer = 0 receved by MCU
+ if (1) {//pTuya->ignore_dimmer_cmd_timeout < millis()) {
+ if ((TasmotaGlobal.power || Settings->flag3.tuya_apply_o20) &&
+ ((pTuya->Levels[dimIndex] > 0 || Settings->flag5.tuya_allow_dimmer_0) &&
+ (pTuya->Levels[dimIndex] != pTuya->Snapshot[dimIndex]))) {
+ //pTuya->ignore_dim = true;
+ TasmotaGlobal.skip_light_fade = true;
+
+ scmnd[0] = '\0';
+ if ((fnId == TUYA_MCU_FUNC_DIMMER) || (fnId == TUYA_MCU_FUNC_REPORT1)) {
+ if (Settings->flag3.pwm_multi_channels && (abs(pTuya->Levels[0] - changeUIntScale(Light.current_color[0], 0, 255, 0, 100))) > 1) {
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_CHANNEL "1 %d"), pTuya->Levels[0]);
+ }
+ else if ((abs(pTuya->Levels[0] - light_state.getDimmer())) > 1) {
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_DIMMER "3 %d"), pTuya->Levels[0]);
+ }
+ }
+ if (((fnId == TUYA_MCU_FUNC_DIMMER2) || (fnId == TUYA_MCU_FUNC_REPORT2)) &&
+ Settings->flag3.pwm_multi_channels && (abs(pTuya->Levels[1] - changeUIntScale(Light.current_color[1], 0, 255, 0, 100))) > 1) {
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_CHANNEL "2 %d"), pTuya->Levels[1]);
+ }
+ if ((fnId == TUYA_MCU_FUNC_CT) && (abs(pTuya->Levels[1] - light_state.getCT())) > 1) {
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLORTEMPERATURE " %d"), pTuya->Levels[1]);
+ }
+ if ((fnId == TUYA_MCU_FUNC_WHITE) && (abs(pTuya->Levels[1] - light_state.getDimmer(2))) > 1) {
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_WHITE " %d"), pTuya->Levels[1]);
+ }
+ if (scmnd[0] != '\0') {
+ ExecuteCommand(scmnd, SRC_SWITCH);
+ }
+ }
+ pTuya->Snapshot[dimIndex] = pTuya->Levels[dimIndex];
+ }
+ }
+ #ifdef USE_ENERGY_SENSOR
+ else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_VOLTAGE) {
+ Energy.voltage[0] = (float)packetValue / 10;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d Rx ID=%d Voltage=%d"), fnId, dpid, packetValue);
+ } else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_CURRENT) {
+ Energy.current[0] = (float)packetValue / 1000;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d Rx ID=%d Current=%d"), fnId, dpid, packetValue);
+ } else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER) {
+ Energy.active_power[0] = (float)packetValue / 10;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d Rx ID=%d Active_Power=%d"), fnId, dpid, packetValue);
+
+ if (RtcTime.valid) {
+ if (pTuya->lastPowerCheckTime != 0 && Energy.active_power[0] > 0) {
+ Energy.kWhtoday[0] += Energy.active_power[0] * (float)(Rtc.utc_time - pTuya->lastPowerCheckTime) / 36.0;
+ EnergyUpdateToday();
+ }
+ pTuya->lastPowerCheckTime = Rtc.utc_time;
+ }
+ } else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_TOTAL) {
+ Energy.import_active[0] = (float)packetValue / 100;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d Rx ID=%d Total_Power=%d"), fnId, dpid, packetValue);
+ EnergyUpdateTotal();
+ }
+ #endif // USE_ENERGY_SENSOR
+ } break;
+
+ case TUYA_TYPE_STRING: { // Data Type 3
+ const unsigned char *dpData = (unsigned char*)data;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: (str) fnId=%d is set for dpId=%d"), dpid);
+ if ((TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0)) {
+
+ uint8_t RGBType = Settings->tuya_fnid_map[230].dpid; // Select the type of hex configured
+ char RgbData[15];
+ char RGB[7];
+ char HSB1[5], HSB2[5], HSB3[5];
+ scmnd[0] = '\0';
+ snprintf_P(RgbData, sizeof(RgbData), PSTR("%.*s"), dpDataLen, dpData);
+
+ if (RGBType <= 1 && dpDataLen == 12) {
+ snprintf_P(HSB1, sizeof(HSB1), PSTR("%.4s\n"), &RgbData[0]);
+ snprintf_P(HSB2, sizeof(HSB2), PSTR("%.4s\n"), &RgbData[4]);
+ snprintf_P(HSB3, sizeof(HSB3), PSTR("%.4s\n"), &RgbData[8]);
+ if ((pTuya->Snapshot[2] != ((int)strtol(HSB1, NULL, 16)) ||
+ (pTuya->Snapshot[3] != ((int)strtol(HSB2, NULL, 16)) / 10) ||
+ (pTuya->Snapshot[4] !=((int)strtol(HSB3, NULL, 16)) / 10)) ) {
+ pTuya->Snapshot[2] = ((int)strtol(HSB1, NULL, 16));
+ pTuya->Snapshot[3] = ((int)strtol(HSB2, NULL, 16)) / 10;
+ pTuya->Snapshot[4] = ((int)strtol(HSB3, NULL, 16)) / 10;
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_HSBCOLOR " %d,%d,%d"), ((int)strtol(HSB1, NULL, 16)),
+ ((int)strtol(HSB2, NULL, 16)) / 10, ((int)strtol(HSB3, NULL, 16)) / 10);
+ }
+ }
+ if (RGBType > 1 && dpDataLen == 14) {
+ snprintf_P(RGB, sizeof(RGB), PSTR("%.6s\n"), &RgbData[0]);
+ if (StrCmpNoCase(RGB, pTuya->RGBColor) != 0) {
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_COLOR " %s"), RGB);
+ memcpy_P(pTuya->RGBColor, RGB, strlen(RGB));
+ }
+ }
+ if (scmnd[0] != '\0') {
+ ExecuteCommand(scmnd, SRC_SWITCH);
+ }
+ }
+
+ } break;
+
+ case TUYA_TYPE_ENUM: { // Data Type 4
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: (enum) fnId=%d is set for dpId=%d"), dpid);
+ if ((fnId == TUYA_MCU_FUNC_MODESET)) { // Toggle light type
+ pTuya->ModeSet = value;
+ pTuya->Levels[3] = value;
+ }
+ if ((fnId >= TUYA_MCU_FUNC_ENUM1) && (fnId <= TUYA_MCU_FUNC_ENUM4)) {
+ for (uint8_t i = 0; i <= 3; i++) {
+ bool noupdate = false;
+ if ((TUYA_MCU_FUNC_ENUM1 + i) == fnId) {
+ if (pTuya->EnumState[i] != value) {
+ pTuya->EnumState[i] = value;
+ snprintf_P(scmnd, sizeof(scmnd), PSTR(D_PRFX_TUYA D_CMND_TUYA_ENUM "%d %d"), i+1, value);
+ ExecuteCommand(scmnd, SRC_SWITCH);
+ }
+ }
+ }
+ }
+ } break;
+ }
+}
+
+
+void TuyaProcessStatePacket(void) {
+ uint8_t dpidStart = 6;
+
+ while (dpidStart + 4 < pTuya->byte_counter) {
+ uint8_t dpid = pTuya->buffer[dpidStart];
+ uint8_t type = pTuya->buffer[dpidStart + 1];
+ uint8_t *data = pTuya->buffer + dpidStart + 4;
+ uint16_t dpDataLen = pTuya->buffer[dpidStart + 2] << 8 | pTuya->buffer[dpidStart + 3];
+ TuyaStoreRxedDP(dpid, type, data, dpDataLen);
+ TuyaProcessRxedDP(dpid, type, data, dpDataLen);
+ dpidStart += dpDataLen + 4;
+ }
+}
+
+void TuyaLowPowerModePacketProcess(void) {
+ switch (pTuya->buffer[3]) {
+ case TUYA_CMD_QUERY_PRODUCT:
+ TuyaHandleProductInfoPacket();
+ //TuyaSetWifiLed();
+ break;
+
+ case TUYA_LOW_POWER_CMD_STATE:
+ TuyaProcessStatePacket();
+ pTuya->send_success_next_second = true;
+ break;
+ }
+
+}
+
+void TuyaHandleProductInfoPacket(void) {
+ uint16_t dataLength = pTuya->buffer[4] << 8 | pTuya->buffer[5];
+ char *data = (char *)&pTuya->buffer[6];
+ AddLog(LOG_LEVEL_INFO, PSTR("TYA: MCU Product ID: %.*s"), dataLength, data);
+}
+
+void TuyaNormalPowerModePacketProcess(void)
+{
+ switch (pTuya->buffer[3]) {
+ case TUYA_CMD_QUERY_PRODUCT:
+ TuyaHandleProductInfoPacket();
+ // next send now done as part of startup state machine
+ //TuyaSendCmd(TUYA_CMD_MCU_CONF);
+ break;
+
+ case TUYA_CMD_HEARTBEAT:
+#ifdef TUYA_MORE_DEBUG
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Hbt"));
+#endif
+ if (pTuya->buffer[6] == 0) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Detected MCU restart"));
+ pTuya->wifi_state = -2;
+ }
+ break;
+
+ case TUYA_CMD_STATE:
+ TuyaProcessStatePacket();
+ break;
+
+ case TUYA_CMD_WIFI_RESET:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX WiFi Reset"));
+ // ack MCU request immediately
+ // https://developer.tuya.com/en/docs/iot/wifi-module-mcu-development-overview-for-homekit?id=Kaa8fvusmgapc
+ // set 'noerror', as we are responding
+ TuyaSendCmd(TUYA_CMD_WIFI_RESET, nullptr, 0, 1);
+ TuyaResetWifi();
+ break;
+ case TUYA_CMD_WIFI_SELECT:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX WiFi Select"));
+ // ack MCU request immediately
+ // https://developer.tuya.com/en/docs/iot/wifi-module-mcu-development-overview-for-homekit?id=Kaa8fvusmgapc
+ // set 'noerror', as we are responding
+ TuyaSendCmd(TUYA_CMD_WIFI_SELECT, nullptr, 0, 1);
+ TuyaResetWifi();
+ break;
+
+ case TUYA_CMD_WIFI_STATE:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX WiFi LED set ACK"));
+ pTuya->wifi_state = TuyaGetTuyaWifiState();
+ break;
+
+ case TUYA_CMD_MCU_CONF:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX MCU configuration Mode=%d"), pTuya->buffer[5]);
+
+ if (pTuya->buffer[5] == 2) { // Processing by ESP module mode
+ uint8_t led1_gpio = pTuya->buffer[6];
+ uint8_t key1_gpio = pTuya->buffer[7];
+ bool key1_set = false;
+ bool led1_set = false;
+ for (uint32_t i = 0; i < nitems(Settings->my_gp.io); i++) {
+ if (Settings->my_gp.io[i] == AGPIO(GPIO_LED1)) led1_set = true;
+ else if (Settings->my_gp.io[i] == AGPIO(GPIO_KEY1)) key1_set = true;
+ }
+ if (!Settings->my_gp.io[led1_gpio] && !led1_set) {
+ Settings->my_gp.io[led1_gpio] = AGPIO(GPIO_LED1);
+ TasmotaGlobal.restart_flag = 2;
+ }
+ if (!Settings->my_gp.io[key1_gpio] && !key1_set) {
+ Settings->my_gp.io[key1_gpio] = AGPIO(GPIO_KEY1);
+ TasmotaGlobal.restart_flag = 2;
+ }
+ }
+ // next send now done as part of startup state machine
+ //TuyaRequestState(0);
+ break;
+#ifdef USE_TUYA_TIME
+ case TUYA_CMD_SET_TIME:
+ // send from state machine.
+ pTuya->send_time = 3;
+ //TuyaSetTime();
+ break;
+#endif
+ default:
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: RX unknown command"));
+ }
+}
+
+/*********************************************************************************************\
+ * API Functions
+\*********************************************************************************************/
+
+bool TuyaModuleSelected(void) {
+#ifdef ESP8266
+ if (TUYA_DIMMER != TasmotaGlobal.module_type) { return false; }
+
+ if (!PinUsed(GPIO_TUYA_RX) || !PinUsed(GPIO_TUYA_TX)) { // fallback to hardware-serial if not explicitly selected
+ SetPin(1, AGPIO(GPIO_TUYA_TX));
+ SetPin(3, AGPIO(GPIO_TUYA_RX));
+ Settings->my_gp.io[1] = AGPIO(GPIO_TUYA_TX);
+ Settings->my_gp.io[3] = AGPIO(GPIO_TUYA_RX);
+ TasmotaGlobal.restart_flag = 2;
+ }
+#endif
+ if (!PinUsed(GPIO_TUYA_RX) || !PinUsed(GPIO_TUYA_TX)) { return false; }
+ // allocate and initialise the sturcture only if we will use it.
+ init_tuya_struct();
+
+ if (!pTuya){ return false; }
+
+ if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) == 0 && TUYA_DIMMER_ID > 0) {
+ TuyaAddMcuFunc(TUYA_MCU_FUNC_DIMMER, TUYA_DIMMER_ID);
+ }
+
+ bool relaySet = false;
+
+ for (uint8_t i = 0 ; i < MAX_TUYA_FUNCTIONS; i++) {
+ if ((Settings->tuya_fnid_map[i].fnid >= TUYA_MCU_FUNC_REL1 && Settings->tuya_fnid_map[i].fnid <= TUYA_MCU_FUNC_REL8 ) ||
+ (Settings->tuya_fnid_map[i].fnid >= TUYA_MCU_FUNC_REL1_INV && Settings->tuya_fnid_map[i].fnid <= TUYA_MCU_FUNC_REL8_INV )) {
+ relaySet = true;
+ TasmotaGlobal.devices_present++;
+ }
+ }
+
+ if (!relaySet && TuyaGetDpId(TUYA_MCU_FUNC_DUMMY) == 0) { //by default the first relay is created automatically the dummy let remove it if not needed
+ TuyaAddMcuFunc(TUYA_MCU_FUNC_REL1, 1);
+ TasmotaGlobal.devices_present++;
+ SettingsSaveAll();
+ }
+
+ // Possible combinations for Lights:
+ // 0: NONE = LT_BASIC
+ // 1: DIMMER = LT_SERIAL1 - Common one channel dimmer
+ // 2: DIMMER, DIMMER2 = LT_SERIAL2 - Two channels dimmer (special setup used with SetOption68)
+ // 3: DIMMER, CT = LT_SERIAL2 - Dimmable light and White Color Temperature
+ // 4: DIMMER, RGB = LT_RGB - RGB Light
+ // 5: DIMMER, RGB, CT = LT_RGBWC - RGB LIght and White Color Temperature
+ // 6: DIMMER, RGB, WHITE = LT_RGBW - RGB LIght and White
+
+ if (TuyaGetDpId(TUYA_MCU_FUNC_DIMMER) != 0) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_CT) != 0) {
+ TasmotaGlobal.light_type = LT_RGBWC;
+ } else if (TuyaGetDpId(TUYA_MCU_FUNC_WHITE) != 0) {
+ TasmotaGlobal.light_type = LT_RGBW;
+ } else { TasmotaGlobal.light_type = LT_RGB; }
+ } else if (TuyaGetDpId(TUYA_MCU_FUNC_CT) != 0 || TuyaGetDpId(TUYA_MCU_FUNC_DIMMER2) != 0) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_RGB) != 0) {
+ TasmotaGlobal.light_type = LT_RGBWC;
+ } else { TasmotaGlobal.light_type = LT_SERIAL2; }
+ } else { TasmotaGlobal.light_type = LT_SERIAL1; }
+ } else {
+ TasmotaGlobal.light_type = LT_BASIC;
+ }
+
+ if (TuyaGetDpId(TUYA_MCU_FUNC_LOWPOWER_MODE) != 0) {
+ pTuya->low_power_mode = true;
+ Settings->flag3.fast_power_cycle_disable = true; // SetOption65 - Disable fast power cycle detection for device reset
+ }
+
+ UpdateDevices();
+ return true;
+}
+
+void TuyaInit(void) {
+ int baudrate = 9600;
+ if (Settings->flag4.tuyamcu_baudrate) { baudrate = 115200; } // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200)
+
+ TuyaSerial = new TasmotaSerial(Pin(GPIO_TUYA_RX), Pin(GPIO_TUYA_TX), 2);
+ if (TuyaSerial->begin(baudrate)) {
+ if (TuyaSerial->hardwareSerial()) { ClaimSerial(); }
+ // Get MCU Configuration
+ pTuya->SuspendTopic = true;
+ pTuya->ignore_topic_timeout = millis() + 1000; // suppress /STAT topic for 1000ms to avoid data overflow
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration at %d bps"), baudrate);
+
+ pTuya->heartbeat_timer = 0; // init heartbeat timer when dimmer init is done
+ return;
+ }
+ pTuya->active = false;
+}
+
+// dump a buffer to debug
+void TuyaDump(unsigned char *buffer, int len){
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Raw Data %*_H"), len, buffer);
+}
+
+// here we have a complete packet with valid checksum
+void TuyaProcessCommand(unsigned char *buffer){
+ uint16_t len = buffer[4] << 8 | buffer[5];
+ uint16_t totallen = len + 7;
+ uint8_t ver = buffer[2];
+ uint8_t cmd = buffer[3];
+
+ pTuya->rxs ++;
+
+
+ // see if we are awaiting this cmd ack
+ // some MCU send 0x00 in ver field,
+ // so we could assume some send 0x01, some 0x02, some 0x03?
+ // I'v not seen any docs about what the VER means!....
+ //if (0x03 == ver) {
+ Tuya_statemachine(cmd, len, (unsigned char *)buffer+6);
+ //}
+
+ Response_P(PSTR("{\"" D_JSON_TUYA_MCU_RECEIVED "\":{\"Data\":\"%*_H\",\"Cmnd\":%d"), totallen, buffer, cmd);
+
+ uint16_t DataVal = 0;
+ uint8_t dpId = 0;
+ uint8_t dpDataType = 0;
+ char DataStr[15];
+ bool isCmdToSuppress = false;
+
+ if (len > 0) {
+ ResponseAppend_P(PSTR(",\"CmndData\":\"%*_H\""), len, (unsigned char*)&buffer[6]);
+ if (TUYA_CMD_STATE == cmd) {
+ //55 AA 03 07 00 0D 01 04 00 01 02 02 02 00 04 00 00 00 1A 40
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+ uint8_t dpidStart = 6;
+ while (dpidStart + 4 < totallen-1) {
+ dpId = buffer[dpidStart];
+ dpDataType = buffer[dpidStart + 1];
+ uint16_t dpDataLen = buffer[dpidStart + 2] << 8 | buffer[dpidStart + 3];
+ const unsigned char *dpData = (unsigned char*)&buffer[dpidStart + 4];
+
+ if (TUYA_CMD_STATE == buffer[3]) {
+ ResponseAppend_P(PSTR(",\"DpType%uId%u\":"), dpDataType, dpId);
+ if (TUYA_TYPE_BOOL == dpDataType && dpDataLen == 1) {
+ ResponseAppend_P(PSTR("%u"), dpData[0]);
+ DataVal = dpData[0];
+ } else if (TUYA_TYPE_VALUE == dpDataType && dpDataLen == 4) {
+ uint32_t dpValue = (uint32_t)dpData[0] << 24 | (uint32_t)dpData[1] << 16 | (uint32_t)dpData[2] << 8 | (uint32_t)dpData[3] << 0;
+ ResponseAppend_P(PSTR("%u"), dpValue);
+ DataVal = dpValue;
+ } else if (TUYA_TYPE_STRING == dpDataType) {
+ ResponseAppend_P(PSTR("\"%.*s\""), dpDataLen, dpData);
+ snprintf_P(DataStr, sizeof(DataStr), PSTR("%.*s"), dpDataLen, dpData);
+ } else if (TUYA_TYPE_ENUM == dpDataType && dpDataLen == 1) {
+ ResponseAppend_P(PSTR("%u"), dpData[0]);
+ DataVal = dpData[0];
+ } else {
+ ResponseAppend_P(PSTR("\"0x%*_H\""), dpDataLen, dpData);
+ snprintf_P(DataStr, sizeof(DataStr), PSTR("%*_H"), dpDataLen, dpData);
+ }
+ }
+
+ ResponseAppend_P(PSTR(",\"%d\":{\"DpId\":%d,\"DpIdType\":%d,\"DpIdData\":\"%*_H\""), dpId, dpId, dpDataType, dpDataLen, dpData);
+ if (TUYA_TYPE_STRING == dpDataType) {
+ ResponseAppend_P(PSTR(",\"Type3Data\":\"%.*s\""), dpDataLen, dpData);
+ }
+ ResponseAppend_P(PSTR("}"));
+ dpidStart += dpDataLen + 4;
+ }
+ }
+ }
+ ResponseAppend_P(PSTR("}}"));
+
+ // SetOption66 - Enable TuyaMcuReceived messages over Mqtt
+ if (Settings->flag3.tuya_serial_mqtt_publish) {
+ for (uint8_t cmdsID = 0; sizeof(TuyaExcludeCMDsFromMQTT) > cmdsID; cmdsID++){
+ if (TuyaExcludeCMDsFromMQTT[cmdsID] == cmd) {
+ isCmdToSuppress = true;
+ break;
+ }
+ }
+ // SetOption137 - (Tuya) When Set, avoid the (MQTT-) publish of defined Tuya CMDs
+ // (see TuyaExcludeCMDsFromMQTT) if SetOption66 is active
+ if (!(isCmdToSuppress && Settings->flag5.tuya_exclude_from_mqtt)) {
+ MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_TUYA_MCU_RECEIVED));
+ }
+ } else {
+ AddLog(LOG_LEVEL_DEBUG, ResponseData());
+ }
+ XdrvRulesProcess(0);
+
+ if (dpId != 0 && Settings->tuyamcu_topic) { // Publish a /STAT Topic ready to use for any home automation system
+ if (!pTuya->SuspendTopic) {
+ char scommand[13];
+ snprintf_P(scommand, sizeof(scommand), PSTR("DpType%uId%u"), dpDataType, dpId);
+ if (dpDataType != 3 && dpDataType != 5) { Response_P(PSTR("%u"), DataVal); }
+ else { Response_P(PSTR("%s"), DataStr); }
+ MqttPublishPrefixTopic_P(STAT, scommand);
+ }
+ }
+
+ if (!pTuya->low_power_mode) {
+ TuyaNormalPowerModePacketProcess();
+ } else {
+ TuyaLowPowerModePacketProcess();
+ }
+}
+
+// processes one byte of Tuya input.
+// on packet complete with good CS, calls TuyaProcessCommand
+void TuyaProcessByte(unsigned char serial_in_byte){
+
+/* I don't think it's safe to do this with RGB possibly containing 55AA in the message.
+ if ((pTuya->cmd_status != 1) &&
+ (pTuya->lastByte == 0x55) &&
+ (serial_in_byte == 0xAA)){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Reset by unexpected 55AA"));
+ TuyaDump(pTuya->buffer, pTuya->byte_counter);
+
+ pTuya->byte_counter = 0;
+ pTuya->buffer[pTuya->byte_counter++] = 0x55;
+ pTuya->cmd_status = 1;
+ pTuya->errorcnt ++;
+ }
+*/
+
+ unsigned int now = millis();
+ if ((pTuya->cmd_status != 0) && (now - pTuya->lastByteTime > TUYA_BYTE_TIMEOUT_MS)){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Reset by char timeout %u > %dms"), now - pTuya->lastByteTime, TUYA_BYTE_TIMEOUT_MS);
+ TuyaDump(pTuya->buffer, pTuya->byte_counter);
+ pTuya->cmd_status = 0;
+ pTuya->errorcnt ++;
+ }
+ pTuya->lastByteTime = now;
+
+ switch(pTuya->cmd_status){
+ case 0: {// wait 55
+ if (serial_in_byte == 0x55) { // Start TUYA Packet
+ pTuya->cmd_status = 1;
+ pTuya->byte_counter = 0;
+ pTuya->buffer[pTuya->byte_counter++] = serial_in_byte;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: E55 0x%02X"), serial_in_byte);
+ pTuya->errorcnt ++;
+ }
+ } break;
+ case 1: {// wait AA
+ if (serial_in_byte == 0xAA) { // Start TUYA Packet
+ pTuya->cmd_status = 2;
+ pTuya->buffer[pTuya->byte_counter++] = serial_in_byte;
+ pTuya->cmd_checksum = 0xFF;
+ } else {
+ // no AA, return to wait for 55
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: EAA 0x%02X"), serial_in_byte);
+ pTuya->errorcnt ++;
+ pTuya->cmd_status = 0;
+ }
+ } break;
+ case 2: {// wait len
+ if (pTuya->byte_counter == 5) { // Get length of data
+ pTuya->data_len = serial_in_byte;
+ pTuya->data_len += pTuya->buffer[4] << 8;
+ if (pTuya->data_len == 0){
+ // straight to CS
+ pTuya->cmd_status = 4;
+ } else {
+ pTuya->cmd_status = 3;
+ }
+ }
+ pTuya->cmd_checksum += serial_in_byte;
+ pTuya->cmd_checksum &= 0xff;
+ pTuya->buffer[pTuya->byte_counter++] = serial_in_byte;
+ } break;
+ case 3: {// wait Data
+ pTuya->buffer[pTuya->byte_counter++] = serial_in_byte;
+ pTuya->cmd_checksum += serial_in_byte;
+ pTuya->cmd_checksum &= 0xff;
+ if (pTuya->byte_counter == (6 + pTuya->data_len)) {
+ pTuya->cmd_status = 4;
+ }
+
+ if (pTuya->byte_counter > TUYA_BUFFER_SIZE-3){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: input overflow"));
+ TuyaDump(pTuya->buffer, pTuya->byte_counter);
+ pTuya->cmd_status = 0;
+ pTuya->byte_counter = 0;
+ }
+ } break;
+ case 4: {// wait CS
+ pTuya->buffer[pTuya->byte_counter++] = serial_in_byte;
+ pTuya->cmd_checksum &= 0xff;
+ if (pTuya->cmd_checksum == serial_in_byte) { // Compare checksum and process packet
+ TuyaProcessCommand(pTuya->buffer);
+ pTuya->cmd_status = 0;
+ pTuya->byte_counter = 0;
+ } else {
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Bad CS 0x%02X != 0x%02X"), serial_in_byte, pTuya->cmd_checksum);
+ TuyaDump(pTuya->buffer, pTuya->byte_counter);
+ pTuya->cmd_status = 0;
+ pTuya->byte_counter = 0;
+ pTuya->errorcnt ++;
+ }
+ } break;
+ }
+ pTuya->lastByte = serial_in_byte;
+}
+
+
+void TuyaSerialInput(void)
+{
+ while (TuyaSerial->available()) {
+ yield();
+ uint8_t serial_in_byte = TuyaSerial->read();
+ TuyaProcessByte(serial_in_byte);
+ }
+}
+
+bool TuyaButtonPressed(void)
+{
+ if (!XdrvMailbox.index && ((PRESSED == XdrvMailbox.payload) && (NOT_PRESSED == Button.last_state[XdrvMailbox.index]))) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: Reset GPIO triggered"));
+ TuyaResetWifi();
+ return true; // Reset GPIO served here
+ }
+ return false; // Don't serve other buttons
+}
+
+uint8_t TuyaGetTuyaWifiState(void) {
+
+ uint8_t wifi_state = 0x02;
+ switch(WifiState()){
+ case WIFI_MANAGER:
+ wifi_state = 0x01;
+ break;
+ case WIFI_RESTART:
+ wifi_state = 0x03;
+ break;
+ }
+
+ if (MqttIsConnected()) {
+ wifi_state = 0x04;
+ }
+
+ return wifi_state;
+}
+
+#ifdef USE_TUYA_TIME
+void TuyaSetTime(void) {
+ if (!RtcTime.valid) { return; }
+
+ uint16_t payload_len = 8;
+ uint8_t payload_buffer[8];
+ uint8_t tuya_day_of_week;
+ if (RtcTime.day_of_week == 1) {
+ tuya_day_of_week = 7;
+ } else {
+ tuya_day_of_week = RtcTime.day_of_week-1;
+ }
+
+ payload_buffer[0] = 0x01;
+ payload_buffer[1] = RtcTime.year %100;
+ payload_buffer[2] = RtcTime.month;
+ payload_buffer[3] = RtcTime.day_of_month;
+ payload_buffer[4] = RtcTime.hour;
+ payload_buffer[5] = RtcTime.minute;
+ payload_buffer[6] = RtcTime.second;
+ payload_buffer[7] = tuya_day_of_week; //1 for Monday in TUYA Doc
+
+ TuyaSendCmd(TUYA_CMD_SET_TIME, payload_buffer, payload_len);
+}
+#endif //USE_TUYA_TIME
+
+/*********************************************************************************************\
+ * Sensors
+\*********************************************************************************************/
+
+void TuyaSensorsShow(bool json)
+{
+ bool RootName = false;
+ bool added = false;
+ char sname[20];
+ char tempval[5];
+ uint8_t res;
+
+ for (uint8_t sensor = TUYA_MCU_FUNC_TEMP; sensor <= TUYA_MCU_FUNC_TIMER4; sensor++) { // Sensors start from fnId 71
+ if (json) {
+ if (TuyaGetDpId(sensor) != 0) {
+
+ if (!RootName) {
+ ResponseAppend_P(PSTR(",\"TuyaSNS\":{"));
+ RootName = true;
+ }
+ if (added) {
+ ResponseAppend_P(PSTR(","));
+ }
+ if (sensor > 74) {
+ res = 0;
+ } else if (sensor > 72) {
+ res = Settings->flag2.humidity_resolution;
+ } else if (sensor == 72) {
+ res = Settings->mbflag2.temperature_set_res;
+ } else {
+ res = Settings->flag2.temperature_resolution;
+ }
+
+ GetTextIndexed(sname, sizeof(sname), (sensor-71), kTuyaSensors);
+ ResponseAppend_P(PSTR("\"%s\":%s"), sname,
+ (pTuya->SensorsValid[sensor-71] ? dtostrfd(TuyaAdjustedTemperature(pTuya->Sensors[sensor-71], res), res, tempval) : PSTR("null")));
+ added = true;
+ }
+ #ifdef USE_WEBSERVER
+ } else {
+ if (TuyaGetDpId(sensor) != 0) {
+ switch (sensor) {
+ case 71:
+ WSContentSend_Temp("", TuyaAdjustedTemperature(pTuya->Sensors[0], Settings->flag2.temperature_resolution));
+ break;
+ case 72:
+ WSContentSend_PD(PSTR("{s}" D_TEMPERATURE " Set{m}%s " D_UNIT_DEGREE "%c{e}"),
+ dtostrfd(TuyaAdjustedTemperature(pTuya->Sensors[1], Settings->mbflag2.temperature_set_res), Settings->mbflag2.temperature_set_res, tempval), TempUnit());
+ break;
+ case 73:
+ WSContentSend_PD(HTTP_SNS_HUM, "", dtostrfd(TuyaAdjustedTemperature(pTuya->Sensors[2], Settings->flag2.humidity_resolution), Settings->flag2.humidity_resolution, tempval));
+ break;
+ case 74:
+ WSContentSend_PD(PSTR("{s}" D_HUMIDITY " Set{m}%s " D_UNIT_PERCENT "{e}"),
+ dtostrfd(TuyaAdjustedTemperature(pTuya->Sensors[3], Settings->flag2.humidity_resolution), Settings->flag2.humidity_resolution, tempval));
+ break;
+ case 75:
+ WSContentSend_PD(HTTP_SNS_ILLUMINANCE, "", pTuya->Sensors[4]);
+ break;
+ case 76:
+ WSContentSend_PD(PSTR("{s}" D_TVOC "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"), pTuya->Sensors[5]);
+ break;
+ case 77:
+ WSContentSend_PD(HTTP_SNS_CO2, "", pTuya->Sensors[6]);
+ break;
+ case 78:
+ WSContentSend_PD(HTTP_SNS_CO2EAVG, "", pTuya->Sensors[7]);
+ break;
+ case 79:
+ WSContentSend_PD(HTTP_SNS_GAS, "", pTuya->Sensors[8]);
+ break;
+ case 80:
+ WSContentSend_PD(PSTR("{s}" D_ENVIRONMENTAL_CONCENTRATION " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"), pTuya->Sensors[9]);
+ break;
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ WSContentSend_PD(PSTR("{s}Timer%d{m}%d{e}"), (sensor-80), pTuya->Sensors[sensor-71]); // No UoM for timers since they can be sec or min
+ break;
+ }
+ }
+
+ #endif // USE_WEBSERVER
+ }
+ }
+#ifdef USE_WEBSERVER
+ if (AsModuleTuyaMS()) {
+ WSContentSend_P(PSTR("{s}" D_JSON_IRHVAC_MODE "{m}%d{e}"), pTuya->ModeSet);
+ }
+#endif // USE_WEBSERVER
+
+ if (RootName) { ResponseJsonEnd();}
+}
+
+#ifdef USE_WEBSERVER
+
+void TuyaAddButton(void) {
+ if (AsModuleTuyaMS()) {
+ WSContentSend_P(HTTP_TABLE100);
+ WSContentSend_P(PSTR(""));
+ char stemp[33];
+ snprintf_P(stemp, sizeof(stemp), PSTR("" D_JSON_IRHVAC_MODE ""));
+ WSContentSend_P(HTTP_DEVICE_CONTROL, 26, TasmotaGlobal.devices_present + 1,
+ (strlen(SettingsText(SET_BUTTON1 + TasmotaGlobal.devices_present))) ? SettingsText(SET_BUTTON1 + TasmotaGlobal.devices_present) : stemp, "");
+ WSContentSend_P(PSTR("
"));
+ }
+}
+
+#endif // USE_WEBSERVER
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+#ifdef USE_ENERGY_SENSOR
+
+bool Xnrg32(uint32_t function)
+{
+ bool result = false;
+
+ if (pTuya && pTuya->active) {
+ if (FUNC_PRE_INIT == function) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_POWER) != 0 || TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) != 0) {
+ if (TuyaGetDpId(TUYA_MCU_FUNC_CURRENT) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) {
+ Energy.current_available = false;
+ }
+ if (TuyaGetDpId(TUYA_MCU_FUNC_VOLTAGE) == 0 && TuyaGetDpId(TUYA_MCU_FUNC_POWER_COMBINED) == 0) {
+ Energy.voltage_available = false;
+ }
+ TasmotaGlobal.energy_driver = XNRG_32;
+ }
+ }
+ }
+ return result;
+}
+#endif // USE_ENERGY_SENSOR
+
+bool Xdrv16(uint32_t function) {
+ bool result = false;
+
+ if (FUNC_MODULE_INIT == function) {
+ result = TuyaModuleSelected();
+ if (pTuya) pTuya->active = result;
+ }
+ else if (pTuya && pTuya->active) {
+ switch (function) {
+ case FUNC_LOOP:
+ case FUNC_SLEEP_LOOP:
+ if (TuyaSerial) { TuyaSerialInput(); }
+ break;
+ case FUNC_PRE_INIT:
+ TuyaInit();
+ break;
+ case FUNC_SET_DEVICE_POWER:
+ result = TuyaSetPower();
+#ifdef TUYA_MORE_DEBUG
+ MqttPublishLoggingAsync(false);
+ SyslogAsync(false);
+#endif
+ break;
+ case FUNC_BUTTON_PRESSED:
+ result = TuyaButtonPressed();
+#ifdef TUYA_MORE_DEBUG
+ MqttPublishLoggingAsync(false);
+ SyslogAsync(false);
+#endif
+ break;
+ case FUNC_EVERY_100_MSECOND:
+ if (pTuya->timeout){
+ pTuya->timeout -= 100;
+ if (pTuya->timeout <= 0){
+ Tuya_timeout();
+ }
+ }
+ for (int i = 0; i < 2; i++){
+ if (pTuya->dimDelay_ms[i]){
+ pTuya->dimDelay_ms[i] -= 100;
+ if (pTuya->dimDelay_ms[i] <= 0){
+ pTuya->dimDelay_ms[i] = 0;
+ AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: DimDelay%d->0"), i);
+ }
+ }
+ }
+ Tuya_statemachine();
+ break;
+ case FUNC_EVERY_SECOND:
+ if (pTuya->wifiTimer > 0){
+ pTuya->wifiTimer -= 1000;
+ if (pTuya->wifiTimer <= 0){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Wifi reset aborted."));
+ pTuya->wifiTimer = 0;
+ }
+ }
+ // now done in state machine
+ //if (TuyaSerial && pTuya->wifi_state != TuyaGetTuyaWifiState()) { TuyaSetWifiLed(); }
+ if (!pTuya->low_power_mode) {
+ pTuya->heartbeat_timer++;
+ if (pTuya->heartbeat_timer > 10) {
+ pTuya->heartbeat_timer = 0;
+ pTuya->send_heartbeat = 1;
+ }
+#ifdef USE_TUYA_TIME
+ if (!(TasmotaGlobal.uptime % 60)) {
+ // if we have never been asked for time, send it ourselves
+ // as this was the original TAS implementation.
+ // if we DO get asked for time, then send_time & 2 will be set, so we no longer send from here.
+ if (!pTuya->send_time & 2){
+ pTuya->send_time |= 1;
+ }
+ }
+#endif //USE_TUYA_TIME
+ } else {
+ // done in state machine
+ //TuyaSendLowPowerSuccessIfNeeded();
+ }
+ if (pTuya->ignore_topic_timeout < millis()) { pTuya->SuspendTopic = false; }
+ if (pTuya->lasterrorcnt != pTuya->errorcnt){
+ AddLog(LOG_LEVEL_ERROR, PSTR("TYA: Errorcnt %d->%d"), pTuya->lasterrorcnt, pTuya->errorcnt);
+ pTuya->lasterrorcnt = pTuya->errorcnt;
+ }
+ break;
+ case FUNC_SET_CHANNELS:
+ result = TuyaSetChannels();
+#ifdef TUYA_MORE_DEBUG
+ MqttPublishLoggingAsync(false);
+ SyslogAsync(false);
+#endif
+ break;
+ case FUNC_MQTT_INIT:
+ // why here? done as part of startup state machine
+ //TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT);
+ break;
+ case FUNC_COMMAND:
+ result = DecodeCommand(kTuyaCommand, TuyaCommand);
+ break;
+ case FUNC_JSON_APPEND:
+ TuyaSensorsShow(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_ADD_MAIN_BUTTON:
+ TuyaAddButton();
+ break;
+ case FUNC_WEB_SENSOR:
+ TuyaSensorsShow(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_TUYA_MCU
+#endif // USE_LIGHT
\ No newline at end of file
From b2239b4dce170a83ed6dc72b15a13c32e896c73c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 13 Nov 2022 15:15:10 +0100
Subject: [PATCH 179/319] Disable TUYA_MORE_DEBUG
---
.../tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino
index 21df2e281..969235e71 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_16_tuyamcu_v2.ino
@@ -45,6 +45,10 @@
#define TUYA_DIMMER_ID 0
#endif
+//#define TUYA_MORE_DEBUG
+
+/*********************************************************************************************/
+
#define TUYA_CMD_HEARTBEAT 0x00
#define TUYA_CMD_QUERY_PRODUCT 0x01
#define TUYA_CMD_MCU_CONF 0x02
@@ -108,8 +112,6 @@
// uses subcommands, 01->learning, 02->data, 03->report.
#define TUYA_CMD_RF 0x33 // not implemented
-
-
#define TUYA_LOW_POWER_CMD_WIFI_STATE 0x02
#define TUYA_LOW_POWER_CMD_WIFI_RESET 0x03
#define TUYA_LOW_POWER_CMD_WIFI_CONFIG 0x04
@@ -128,16 +130,8 @@
#define TUYA_BYTE_TIMEOUT_MS 500
-#define TUYA_MORE_DEBUG
-
-
-
-#include
-
-
#define TUYAREAD32FROMPTR(x) (((uint8_t*)x)[0] << 24 | ((uint8_t*)x)[1] << 16 | ((uint8_t*)x)[2] << 8 | ((uint8_t*)x)[3])
-
enum {
TUYA_STARTUP_STATE_INIT = 0,
TUYA_STARTUP_STATE_WAIT_ACK_INIT, // 1
@@ -164,7 +158,7 @@ enum {
};
-
+#include
TasmotaSerial *TuyaSerial = nullptr;
#define TUYA_MAX_STORED_DPs 10
@@ -269,7 +263,6 @@ TUYA_STRUCT *pTuya = (TUYA_STRUCT *)0;
void TuyaSendState(uint8_t id, uint8_t type, uint8_t* value, int len);
-
int init_tuya_struct() {
if (pTuya) return 0; // done already
pTuya = (TUYA_STRUCT *)malloc(sizeof(TUYA_STRUCT));
From 9a104364501e193f2dfb06165476aea77674f1f1 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sun, 13 Nov 2022 16:46:26 +0100
Subject: [PATCH 180/319] rm pip install zopfli
---
pio-tools/gzip-firmware.py | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/pio-tools/gzip-firmware.py b/pio-tools/gzip-firmware.py
index 26a00abe8..90e7f80d6 100644
--- a/pio-tools/gzip-firmware.py
+++ b/pio-tools/gzip-firmware.py
@@ -3,14 +3,6 @@ import os
import shutil
import pathlib
import tasmotapiolib
-
-# Upgrade pip
-env.Execute("$PYTHONEXE -m pip install --upgrade pip")
-# Install zopfli gz compressor from the PyPi registry
-env.Execute("$PYTHONEXE -m pip install zopfli")
-
-# Import zoepfli compress
-from zopfli.gzip import compress
import gzip
def map_gzip(source, target, env):
@@ -39,7 +31,7 @@ if not tasmotapiolib.is_env_set(tasmotapiolib.DISABLE_MAP_GZ, env):
# gzip only for ESP8266
if env["PIOPLATFORM"] != "espressif32":
-
+ from zopfli.gzip import compress
def bin_gzip(source, target, env):
# create string with location and file names based on variant
bin_file = tasmotapiolib.get_final_bin_path(env)
From 0cfa2aba74ae3e7974395001fc288decf3cbd7c9 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 13 Nov 2022 18:00:49 +0100
Subject: [PATCH 181/319] WS2812 sends signal to only ``Pixels`` leds instead
of sending to 512 leds
---
CHANGELOG.md | 1 +
tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino | 54 +++++++++++++++++--
2 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c8470d738..c7c6a0588 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
- TuyaMcu rewrite by btsimonh (#17051)
+- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
index e7a65a5ee..c0f7ff7e5 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
@@ -669,20 +669,37 @@ void Ws2812ShowScheme(void)
}
}
-void Ws2812ModuleSelected(void)
+bool Ws2812ReinitStrip(void)
{
+ if (strip != nullptr) {
+ Ws2812Clear();
+ if (!strip->CanShow()) {
+ // we're doing DMA, so wait for a decent amount of time
+ delay(10);
+ }
+ delete strip;
+ strip = nullptr;
+ }
+
#if (USE_WS2812_HARDWARE == NEO_HW_P9813)
if (PinUsed(GPIO_P9813_CLK) && PinUsed(GPIO_P9813_DAT)) { // RGB led
- strip = new NeoPixelBus(WS2812_MAX_LEDS, Pin(GPIO_P9813_CLK), Pin(GPIO_P9813_DAT));
+ strip = new NeoPixelBus(Settings->light_pixels, Pin(GPIO_P9813_CLK), Pin(GPIO_P9813_DAT));
#else
if (PinUsed(GPIO_WS2812)) { // RGB led
// For DMA, the Pin is ignored as it uses GPIO3 due to DMA hardware use.
- strip = new NeoPixelBus(WS2812_MAX_LEDS, Pin(GPIO_WS2812));
+ strip = new NeoPixelBus(Settings->light_pixels, Pin(GPIO_WS2812));
#endif // NEO_HW_P9813
strip->Begin();
Ws2812Clear();
+ return true;
+ }
+ return false;
+}
+void Ws2812ModuleSelected(void)
+{
+ if (Ws2812ReinitStrip()) {
Ws2812.scheme_offset = Light.max_scheme +1;
Light.max_scheme += WS2812_SCHEMES;
@@ -725,7 +742,7 @@ void CmndPixels(void)
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= WS2812_MAX_LEDS)) {
Settings->light_pixels = XdrvMailbox.payload;
Settings->light_rotation = 0;
- Ws2812Clear();
+ Ws2812ReinitStrip();
Light.update = true;
}
ResponseCmndNumber(Settings->light_pixels);
@@ -735,7 +752,7 @@ void CmndStepPixels(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) {
Settings->light_step_pixels = (XdrvMailbox.payload > WS2812_MAX_LEDS) ? WS2812_MAX_LEDS : XdrvMailbox.payload;
- Ws2812Clear();
+ Ws2812ReinitStrip();
Light.update = true;
}
ResponseCmndNumber(Settings->light_step_pixels);
@@ -767,6 +784,33 @@ void CmndWidth(void)
}
}
+/*********************************************************************************************\
+ * Internal calls for ArtNet
+\*********************************************************************************************/
+// check is the Neopixel strip is configured
+bool Ws2812StripConfigured(void) {
+ return strip != nullptr;
+}
+size_t Ws2812StripGetPixelSize(void) {
+ return strip->PixelSize();
+}
+// return true if strip was dirty and an actual refresh was triggered
+bool Ws2812StripRefresh(void) {
+ if (strip->IsDirty()) {
+ strip->Show();
+ return true;
+ } else {
+ return false;
+ }
+}
+void Ws2812CopyPixels(const uint8_t *buf, size_t len, size_t offset_in_matrix) {
+ uint8_t *pixels = strip->Pixels();
+ memmove(&pixels[offset_in_matrix], buf, len);
+ strip->Dirty();
+}
+
+
+
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
From 6738eec4c3c2903b4cde9bedbdda1bed22ddd792 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sun, 13 Nov 2022 18:04:44 +0100
Subject: [PATCH 182/319] Change version naming
---
platformio.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index 57b6c9404..4ac907b33 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -110,7 +110,7 @@ build_flags = ${esp_defaults.build_flags}
[core]
; *** Esp8266 Tasmota modified Arduino core based on core 2.7.4. Added Backport for PWM selection
-platform = https://github.com/tasmota/platform-espressif8266/releases/download/v2.7.4.9/platform-espressif8266-2.7.4.9.zip
+platform = https://github.com/tasmota/platform-espressif8266/releases/download/v2.7.4/platform-espressif8266-2.7.4.zip
platform_packages =
build_unflags = ${esp_defaults.build_unflags}
build_flags = ${esp82xx_defaults.build_flags}
From 0e5f79da9c3292b15f9c00cdbb8e6876c100454d Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 13 Nov 2022 18:05:13 +0100
Subject: [PATCH 183/319] Fix to Leds set_bytes, and added persistance to
ArtNet Berry
---
.../berry_tasmota/src/embedded/leds.be | 5 +-
.../src/solidify/solidified_leds.h | 37 +++++++------
tasmota/berry/artnet/artnet.be | 53 +++++++++++++++++++
3 files changed, 76 insertions(+), 19 deletions(-)
diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be
index 23f24ef07..7a1461d90 100644
--- a/lib/libesp32/berry_tasmota/src/embedded/leds.be
+++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be
@@ -318,10 +318,11 @@ class Leds : Leds_ntv
# setbytes(row, bytes)
# sets the raw bytes for `row`, copying at most 3 or 4 x col bytes
- def set_bytes(row, buf, offset)
+ def set_bytes(row, buf, offset, len)
var h_bytes = self.h * self.pix_size
+ if (len > h_bytes) len = h_bytes end
var offset_in_matrix = self.offset + row * h_bytes
- self.pix_buffer.setbytes(offset_in_matrix, buf, offset, h_bytes)
+ self.pix_buffer.setbytes(offset_in_matrix, buf, offset, len)
end
# Leds_matrix specific
diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
index 8c8692405..c6caa2eab 100644
--- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
+++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h
@@ -1308,8 +1308,8 @@ be_local_closure(Leds_matrix_is_dirty, /* name */
********************************************************************/
be_local_closure(Leds_matrix_set_bytes, /* name */
be_nested_proto(
- 12, /* nstack */
- 4, /* argc */
+ 13, /* nstack */
+ 5, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
@@ -1325,21 +1325,24 @@ be_local_closure(Leds_matrix_set_bytes, /* name */
}),
&be_const_str_set_bytes,
&be_const_str_solidified,
- ( &(const binstruction[14]) { /* code */
- 0x88100100, // 0000 GETMBR R4 R0 K0
- 0x88140101, // 0001 GETMBR R5 R0 K1
- 0x08100805, // 0002 MUL R4 R4 R5
- 0x88140102, // 0003 GETMBR R5 R0 K2
- 0x08180204, // 0004 MUL R6 R1 R4
- 0x00140A06, // 0005 ADD R5 R5 R6
- 0x88180103, // 0006 GETMBR R6 R0 K3
- 0x8C180D04, // 0007 GETMET R6 R6 K4
- 0x5C200A00, // 0008 MOVE R8 R5
- 0x5C240400, // 0009 MOVE R9 R2
- 0x5C280600, // 000A MOVE R10 R3
- 0x5C2C0800, // 000B MOVE R11 R4
- 0x7C180A00, // 000C CALL R6 5
- 0x80000000, // 000D RET 0
+ ( &(const binstruction[17]) { /* code */
+ 0x88140100, // 0000 GETMBR R5 R0 K0
+ 0x88180101, // 0001 GETMBR R6 R0 K1
+ 0x08140A06, // 0002 MUL R5 R5 R6
+ 0x24180805, // 0003 GT R6 R4 R5
+ 0x781A0000, // 0004 JMPF R6 #0006
+ 0x5C100A00, // 0005 MOVE R4 R5
+ 0x88180102, // 0006 GETMBR R6 R0 K2
+ 0x081C0205, // 0007 MUL R7 R1 R5
+ 0x00180C07, // 0008 ADD R6 R6 R7
+ 0x881C0103, // 0009 GETMBR R7 R0 K3
+ 0x8C1C0F04, // 000A GETMET R7 R7 K4
+ 0x5C240C00, // 000B MOVE R9 R6
+ 0x5C280400, // 000C MOVE R10 R2
+ 0x5C2C0600, // 000D MOVE R11 R3
+ 0x5C300800, // 000E MOVE R12 R4
+ 0x7C1C0A00, // 000F CALL R7 5
+ 0x80000000, // 0010 RET 0
})
)
);
diff --git a/tasmota/berry/artnet/artnet.be b/tasmota/berry/artnet/artnet.be
index 1fcdd5053..b4f36f98b 100644
--- a/tasmota/berry/artnet/artnet.be
+++ b/tasmota/berry/artnet/artnet.be
@@ -38,6 +38,15 @@ class ArtNet
tasmota.global.sleep = 5
end
+ def stop()
+ import introspect
+ # if usd_server has a stop() method, call it
+ if introspect.get(self.udp_server, "stop")
+ self.udp_server.stop()
+ end
+ self.matrix.clear()
+ end
+
def fast_loop()
var universe_start = self.universe_start
var universe_end = self.universe_end
@@ -82,6 +91,50 @@ class ArtNet
self.matrix.show()
end
end
+
+ static def read_persist()
+ import persist
+ var conf = dyn()
+
+ conf.gpio = persist.find("artnet_gpio", 0) # gpio number from template
+ conf.rows = persist.find("artnet_rows", 5) # number of rows (min: 1)
+ conf.cols = persist.find("artnet_cols", 5) # number of columns (min: 1)
+ conf.offs = persist.find("artnet_offs", 0) # offset in the led strip where the matrix starts (min: 0)
+ conf.alt = persist.find("artnet_alt", false) # are the rows in alternate directions
+
+ conf.univ = persist.find("artnet_univ", 0) # start universe
+
+ # conf.addr = persist.find("artnet_addr", "uni") # listening mode, either 'uni' or 'multi' for multicast
+ conf.port = persist.find("artnet_port", 6454) # UDP port number
+
+ conf.auto = persist.find("artnet_auto", true) # autorun at startup
+ return conf
+ end
+
+ static def run_from_conf()
+ import persist
+
+ var conf = ArtNet.read_persist()
+ var r = conf.rows
+ var c = conf.cols
+
+ var strip = Leds(r * c, gpio.pin(gpio.WS2812, conf.gpio))
+ var matrix = strip.create_matrix(r, c, conf.offs)
+ if conf.alt matrix.set_alternate(true)
+ end
+ var dmx = ArtNet(matrix, conf.univ, conf.port)
+
+ global._artnet = dmx
+ end
+
+ static def stop_global()
+ var dmx = global._artnet
+ if type(dmx) == 'instance'
+ dmx.stop()
+ global._artnet = nil # dereference
+ tasmota.gc() # force gc
+ end
+ end
end
return ArtNet
From 2549203c13bd63f3c2ef0a6f6ea3d07f8d60b9a6 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 13 Nov 2022 18:22:39 +0100
Subject: [PATCH 184/319] Added WS2812 and Light ArtNet DMX control over UDP
port 6454
---
CHANGELOG.md | 1 +
.../jsmn-shadinger-1.0/src/JsonParser.cpp | 3 +
.../jsmn-shadinger-1.0/src/JsonParser.h | 1 +
tasmota/include/i18n.h | 4 +
tasmota/include/tasmota_types.h | 8 +-
tasmota/my_user_config.h | 3 +
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 40 +-
.../xdrv_04_light_artnet.ino | 425 ++++++++++++++++++
8 files changed, 472 insertions(+), 13 deletions(-)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c7c6a0588..63408c2e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
- Added ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
+- Added WS2812 and Light ArtNet DMX control over UDP port 6454
### Breaking Changed
diff --git a/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp b/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp
index 0668faa1a..22229e3f1 100644
--- a/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp
+++ b/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp
@@ -370,6 +370,9 @@ uint64_t JsonParserToken::getULong(void) const { return getULong(0); }
float JsonParserToken::getFloat(void) const { return getFloat(0); }
const char * JsonParserToken::getStr(void) const { return getStr(""); }
+bool JsonParserObject::getBool(const char * needle, bool val) const {
+ return (*this)[needle].getBool(val);
+}
int32_t JsonParserObject::getInt(const char * needle, int32_t val) const {
return (*this)[needle].getInt(val);
}
diff --git a/lib/default/jsmn-shadinger-1.0/src/JsonParser.h b/lib/default/jsmn-shadinger-1.0/src/JsonParser.h
index 03a0aba65..9d61044fd 100644
--- a/lib/default/jsmn-shadinger-1.0/src/JsonParser.h
+++ b/lib/default/jsmn-shadinger-1.0/src/JsonParser.h
@@ -162,6 +162,7 @@ public:
const char * findConstCharNull(const char * needle) const;
// all-in-one methods: search for key (case insensitive), convert value and set default
+ bool getBool(const char *, bool val) const;
int32_t getInt(const char *, int32_t) const;
uint32_t getUInt(const char *, uint32_t) const;
uint64_t getULong(const char *, uint64_t) const;
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index ff4546996..85445545b 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -502,6 +502,10 @@
#define D_CMND_PALETTE "Palette"
#define D_CMND_PIXELS "Pixels"
#define D_CMND_STEPPIXELS "StepPixels"
+#define D_CMND_ARTNET_START "ArtNetStart"
+#define D_CMND_ARTNET_STOP "ArtNetStop"
+#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
+#define D_SO_ARTNET_AUTORUN "ArtNetAutorun"
#define D_CMND_RGBWWTABLE "RGBWWTable"
#define D_CMND_ROTATION "Rotation"
#define D_CMND_SCHEME "Scheme"
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index 7f952b8f5..d1dd5c9eb 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -181,7 +181,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
struct { // SetOption146 .. SetOption177
uint32_t use_esp32_temperature : 1; // bit 0 (v12.1.1.1) - SetOption146 - (ESP32) Show ESP32 internal temperature sensor
uint32_t mqtt_disable_sserialrec : 1; // bit 1 (v12.1.1.2) - SetOption147 - (MQTT) Disable publish SSerialReceived MQTT messages, you must use event trigger rules instead.
- uint32_t spare02 : 1; // bit 2
+ uint32_t artnet_autorun : 1; // bit 2 (v12.2.0.4) - SetOption148 - (Light) start DMX ArtNet at boot, listen to UDP port as soon as network is up
uint32_t spare03 : 1; // bit 3
uint32_t spare04 : 1; // bit 4
uint32_t spare05 : 1; // bit 5
@@ -722,14 +722,14 @@ typedef struct {
char user_template_name[15]; // 720 15 bytes - Backward compatibility since v8.2.0.3
#ifdef ESP8266
- mytmplt8285 ex_user_template8; // 72F 14 bytes (ESP8266) - Free since 9.0.0.1
+ uint8_t ex_user_template8[5]; // 72F 14 bytes (ESP8266) - Free since 9.0.0.1 - only 5 bytes referenced now
#endif // ESP8266
#ifdef ESP32
uint8_t webcam_clk; // 72F
WebCamCfg2 webcam_config2; // 730
-
- uint8_t free_esp32_734[9]; // 734
#endif // ESP32
+ uint16_t artnet_universe; // 734
+ uint8_t free_esp32_734[7]; // 736
uint8_t novasds_startingoffset; // 73D
uint8_t web_color[18][3]; // 73E
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index b5cd3ebd1..c59d4a5ea 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -571,6 +571,9 @@
#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code)
//#define USE_LSC_MCSL // Add support for GPE Multi color smart light as sold by Action in the Netherlands (+1k1 code)
+// #define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code)
+ #define USE_LIGHT_ARTNET_MCAST 239,255,25,54 // Multicast address used to listen: 239.255.25.24
+
// -- Counter input -------------------------------
#define USE_COUNTER // Enable inputs as counter (+0k8 code)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index 164e4d708..e6cafd584 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -135,7 +135,7 @@ const uint8_t LIGHT_COLOR_SIZE = 25; // Char array scolor size
const char kLightCommands[] PROGMEM = "|" // No prefix
// SetOptions synonyms
D_SO_CHANNELREMAP "|" D_SO_MULTIPWM "|" D_SO_ALEXACTRANGE "|" D_SO_POWERONFADE "|" D_SO_PWMCT "|"
- D_SO_WHITEBLEND "|"
+ D_SO_WHITEBLEND "|" D_SO_ARTNET_AUTORUN "|"
// Other commands
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_DIMMER_RANGE "|" D_CMND_DIMMER_STEP "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
D_CMND_RGBWWTABLE "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|"
@@ -150,11 +150,14 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
#ifdef USE_DGR_LIGHT_SEQUENCE
"|" D_CMND_SEQUENCE_OFFSET
#endif // USE_DGR_LIGHT_SEQUENCE
+#ifdef USE_LIGHT_ARTNET
+ "|" D_CMND_ARTNET_START "|" D_CMND_ARTNET_STOP "|" D_CMND_ARTNET_CONFIG
+#endif
"|UNDOCA" ;
SO_SYNONYMS(kLightSynonyms,
37, 68, 82, 91, 92,
- 105,
+ 105, 148,
);
void (* const LightCommand[])(void) PROGMEM = {
@@ -171,6 +174,9 @@ void (* const LightCommand[])(void) PROGMEM = {
#ifdef USE_DGR_LIGHT_SEQUENCE
&CmndSequenceOffset,
#endif // USE_DGR_LIGHT_SEQUENCE
+#ifdef USE_LIGHT_ARTNET
+ &CmndArtNetStart, &CmndArtNetStop, &CmndArtNetConfig,
+#endif
&CmndUndocA };
// Light color mode, either RGB alone, or white-CT alone, or both only available if ct_rgb_linked is false
@@ -1862,7 +1868,7 @@ void LightAnimate(void)
break;
#endif
default:
- XlgtCall(FUNC_SET_SCHEME);
+ XlgtCall(FUNC_SET_SCHEME);
}
#ifdef USE_DEVICE_GROUPS
@@ -2229,6 +2235,10 @@ void LightSetOutputs(const uint16_t *cur_col_10) {
XdrvMailbox.data = (char*)cur_col;
XdrvMailbox.topic = (char*)scale_col;
XdrvMailbox.command = (char*)cur_col_10;
+#ifdef USE_LIGHT_ARTNET
+ if (ArtNetSetChannels()) { /* Serviced */}
+ else
+#endif
if (XlgtCall(FUNC_SET_CHANNELS)) { /* Serviced */ }
else if (XdrvCall(FUNC_SET_CHANNELS)) { /* Serviced */ }
XdrvMailbox.data = tmp_data;
@@ -3413,6 +3423,9 @@ bool Xdrv04(uint32_t function)
LightSetOutputs(Light.fade_cur_10);
}
}
+#ifdef USE_LIGHT_ARTNET
+ ArtNetLoop();
+#endif // USE_LIGHT_ARTNET
break;
case FUNC_EVERY_50_MSECOND:
LightAnimate();
@@ -3428,12 +3441,6 @@ bool Xdrv04(uint32_t function)
case FUNC_BUTTON_MULTI_PRESSED:
result = XlgtCall(FUNC_BUTTON_MULTI_PRESSED);
break;
- case FUNC_NETWORK_UP:
- XlgtCall(FUNC_NETWORK_UP);
- break;
- case FUNC_NETWORK_DOWN:
- XlgtCall(FUNC_NETWORK_DOWN);
- break;
#ifdef USE_WEBSERVER
case FUNC_WEB_ADD_MAIN_BUTTON:
XlgtCall(FUNC_WEB_ADD_MAIN_BUTTON);
@@ -3451,6 +3458,21 @@ bool Xdrv04(uint32_t function)
case FUNC_PRE_INIT:
LightInit();
break;
+#ifdef USE_LIGHT_ARTNET
+ case FUNC_JSON_APPEND:
+ ArtNetJSONAppend();
+ break;
+ case FUNC_NETWORK_UP:
+ if (Settings->flag6.artnet_autorun) {
+ if (!ArtNetStart()) {
+ Settings->flag6.artnet_autorun = false; // disable autorun if it failed, avoid nasty loop errors
+ }
+ }
+ break;
+ case FUNC_NETWORK_DOWN:
+ ArtNetStop();
+ break;
+#endif // USE_LIGHT_ARTNET
}
}
return result;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
new file mode 100644
index 000000000..4ce80f126
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -0,0 +1,425 @@
+/*
+ xdrv_04_light_artnet.ino - Converter functions for lights
+
+ Copyright (C) 2020 Stephan Hadinger & Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+
+#ifdef USE_LIGHT
+#ifdef USE_LIGHT_ARTNET
+
+#ifndef WS2812_ARTNET_UDP_BUFFER_SIZE
+#define WS2812_ARTNET_UDP_BUFFER_SIZE 140 // Max 30 columns with 4 bytes per pixel
+#endif
+
+#ifndef WS2812_ARTNET_UDP_MAX_PACKETS
+#define WS2812_ARTNET_UDP_MAX_PACKETS 30 // Max 30 rows (packets consecutive)
+#endif
+
+#ifndef WS2812_ARTNET_MAX_SLEEP
+#define WS2812_ARTNET_MAX_SLEEP 5 // sleep at most 5ms
+#endif
+
+typedef struct {
+ uint8_t rows = 1; // number of rows (min:1)
+ uint8_t cols = 0; // number of columns (if cols == 0 then apply to the entire light)
+ uint8_t offs = 0; // offset in the led strip where the matrix starts (min: 0)
+ bool alt = false; // are the rows in alternate directions
+ uint16_t univ = 0; // start at universe number (+1)
+ uint16_t port = 6454; // UDP port number
+ uint8_t dimm = 100; // Dimmer 0..100
+ bool on = true;
+ bool matrix = true; // true if light is a WS2812 matrix, false if single light
+ // metrics
+ uint32_t packet_received = 0;
+ uint32_t packet_accepted = 0;
+ uint32_t strip_refresh = 0;
+} ArtNetConfig;
+
+uint32_t * packets_per_row = nullptr;
+
+ArtNetConfig artnet_conf;
+
+#ifdef ESP8266
+#include "UdpListener.h"
+UdpListener * ArtNetUdp = nullptr;
+#else
+WiFiUDP * ArtNetUdp;
+#endif
+
+bool artnet_udp_connected = false;
+// IPAddress artnet_udp_remote_ip; // remote IP address
+// uint16_t artnet_udp_remote_port; // remote port
+
+
+/*********************************************************************************************\
+ * ArtNet support
+\*********************************************************************************************/
+
+void ArtNetLoadSettings(void) {
+ // read settings and copy locally
+ artnet_conf.dimm = Settings->light_dimmer;
+ artnet_conf.cols = Settings->light_step_pixels;
+ artnet_conf.rows = (artnet_conf.cols != 0) ? Settings->light_pixels / artnet_conf.cols : 0;
+ artnet_conf.offs = Settings->light_rotation;
+ artnet_conf.alt = Settings->flag.ws_clock_reverse; // SetOption16
+ artnet_conf.univ = Settings->artnet_universe;
+ artnet_conf.on = (Light.power & 1);
+ ArtNetValidate();
+}
+
+// validate that parameters in artnet_conf are in valid ranges
+void ArtNetValidate(void) {
+ if (artnet_conf.dimm > 100) { artnet_conf.dimm = 100; }
+ if (artnet_conf.cols == 0 || artnet_conf.rows == 0) { artnet_conf.rows = 1; } // if single light, both are supposed to be 0
+ artnet_conf.matrix = (artnet_conf.cols > 0) && Ws2812StripConfigured();
+ if (artnet_conf.univ > 32767) { artnet_conf.univ = 0; }
+ if (artnet_conf.port == 0) { artnet_conf.port = 6454; }
+}
+
+void ArtNetSaveSettings(void) {
+ ArtNetValidate();
+ // write to settings
+ Settings->light_dimmer = artnet_conf.dimm;
+ Settings->light_step_pixels = artnet_conf.cols;
+ if (artnet_conf.cols > 0) { Settings->light_pixels = artnet_conf.rows * artnet_conf.cols; }
+ Settings->light_rotation = artnet_conf.offs;
+ Settings->artnet_universe = artnet_conf.univ;
+ Settings->flag.ws_clock_reverse = artnet_conf.alt; // SetOption16
+}
+
+
+bool ArtNetSetChannels(void)
+{
+ if (artnet_udp_connected && ArtNetUdp != nullptr) {
+ // ArtNet is running
+ if (artnet_conf.matrix) {
+ if (Light.power & 1) { return true; } // serviced, don't cascade to WS2812
+ } else {
+ return false; // if regular bulb, cascade change
+ }
+ } else if (Settings->flag6.artnet_autorun) {
+ // ArtNet is not running but is planned to get running
+ return true; // if ArtNet autorun is own but has not started yet, block update to lights
+ }
+ return false;
+}
+
+// process ArtNet packet
+// returns `true` if strip is dirty, i.e. we changed the value of some leds
+void ArtNetProcessPacket(uint8_t * buf, size_t len) {
+ artnet_conf.packet_received++;
+ if (buf == nullptr || len <= 18) { return; }
+ // is the signature correct?
+ // 4172742D4E657400
+ static const char ARTNET_SIG[] = "Art-Net";
+ if (memcmp(buf, ARTNET_SIG, sizeof(ARTNET_SIG))) { return; }
+
+ uint16_t opcode = buf[8] | (buf[9] << 8);
+ uint16_t protocol = (buf[10] << 8) | buf[11]; // Big Endian
+ uint16_t universe = buf[14] | (buf[15] << 8);
+ uint16_t datalen = (buf[16] << 8) | buf[17];
+ // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DMX: opcode=0x%04X procotol=%i universe=%i datalen=%i univ_start=%i univ_end=%i"), opcode, protocol, universe, datalen, artnet_conf.univ, artnet_conf.univ + artnet_conf.rows);
+ if (opcode != 0x5000 || protocol != 14) { return; }
+
+ if (len + 18 < datalen) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("DMX: packet is truncated, ignoring packet"));
+ }
+
+ if (universe < artnet_conf.univ || universe >= artnet_conf.univ + artnet_conf.rows) { return; } // universe is not ours, ignore
+ size_t idx = 18; // start of payload data in the UDP frame
+ uint16_t row = universe - artnet_conf.univ;
+
+ if (artnet_conf.matrix) {
+ // Ws2812 led strip
+ size_t pix_size = Ws2812StripGetPixelSize();
+ datalen = datalen - (datalen % pix_size);
+
+ if (artnet_conf.alt && (row % 2)) {
+ for (int32_t i = idx, j = idx + datalen - pix_size; i < j; i += pix_size, j -= pix_size) {
+ for (int32_t k = 0; k < pix_size; k++) {
+ uint8_t temp = buf[i+k];
+ buf[i+k] = buf[j+k];
+ buf[j+k] = temp;
+ }
+ }
+ }
+
+ // process dimmer
+ if (artnet_conf.dimm != 100) {
+ // No Gamma for now
+ if (pix_size == 3) {
+ for (int32_t i = idx; i < idx+datalen; i += pix_size) {
+ buf[i] = changeUIntScale(buf[i], 0, 100, 0, artnet_conf.dimm);
+ buf[i+1] = changeUIntScale(buf[i+1], 0, 100, 0, artnet_conf.dimm);
+ buf[i+2] = changeUIntScale(buf[i+2], 0, 100, 0, artnet_conf.dimm);
+ }
+ } else if (pix_size == 4) {
+ for (int32_t i = idx; i < idx+datalen; i += pix_size) {
+ buf[i] = changeUIntScale(buf[i], 0, 100, 0, artnet_conf.dimm);
+ buf[i+1] = changeUIntScale(buf[i+1], 0, 100, 0, artnet_conf.dimm);
+ buf[i+2] = changeUIntScale(buf[i+2], 0, 100, 0, artnet_conf.dimm);
+ buf[i+3] = changeUIntScale(buf[i+2], 0, 100, 0, artnet_conf.dimm);
+ }
+ }
+ }
+
+ // process pixels
+ size_t h_bytes = artnet_conf.cols * pix_size; // size in bytes of a single row
+ size_t offset_in_matrix = artnet_conf.offs * pix_size + row * h_bytes;
+ if (datalen > h_bytes) { datalen = h_bytes; } // copy at most one line
+
+ Ws2812CopyPixels(&buf[idx], datalen, offset_in_matrix);
+ } else {
+ // single light
+ uint8_t r8 = buf[idx+1];
+ uint8_t g8 = buf[idx];
+ uint8_t b8 = buf[idx+2];
+ uint16_t dimmer10 = changeUIntScale(artnet_conf.dimm, 0, 100, 0, 1023);
+ uint16_t color[LST_MAX] = {0};
+ color[0] = changeUIntScale(r8, 0, 255, 0, dimmer10);
+ color[1] = changeUIntScale(g8, 0, 255, 0, dimmer10);
+ color[2] = changeUIntScale(b8, 0, 255, 0, dimmer10);
+ // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DMX: %02X-%02X-%02X univ=%i rows=%i max_univ=%i"), buf[idx+1], buf[idx], buf[idx+2], universe, row, artnet_conf.univ + artnet_conf.rows);
+ LightSetOutputs(color);
+ }
+ // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DMX: ok universe=%i datalen=%i"), universe, datalen);
+ artnet_conf.packet_accepted++;
+ if (packets_per_row) {
+ packets_per_row[row]++;
+ }
+}
+
+//
+// Called at event loop, checks for incoming data from the CC2530
+//
+void ArtNetLoop(void)
+{
+ if (artnet_udp_connected && ArtNetUdp != nullptr) {
+ ArtNetLoadSettings();
+ bool packet_ready = false;
+ int32_t packet_len = 0;
+#ifdef ESP8266
+ packet_ready = ArtNetUdp->next();
+ while (packet_ready) {
+ UdpPacket *packet;
+ packet = ArtNetUdp->read();
+ uint8_t * packet_buffer = (uint8_t*) &packet->buf;
+ packet_len = packet->len;
+#else
+ packet_len = ArtNetUdp->parsePacket();
+ packet_ready = (packet_len > 0);
+ while (packet_ready) {
+ uint8_t packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
+
+ packet_len = ArtNetUdp->read(packet_buffer, UDP_BUFFER_SIZE);
+ ArtNetUdp->flush(); // Finish reading the current packet
+#endif
+ // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet %*_H (%d)"), 32, packet_buffer, packet_len);
+ if (artnet_conf.on) {
+ ArtNetProcessPacket(packet_buffer, packet_len);
+ }
+
+#ifdef ESP8266
+ packet_ready = ArtNetUdp->next();
+ if (!packet_ready) {
+ // if no more incoming packet, still wait for 20 microseconds
+ delay(1); // delayMicroseconds seems broken, need to
+ packet_ready = ArtNetUdp->next();
+ }
+#else
+ packet_len = ArtNetUdp->parsePacket();
+ packet_ready = (packet_len > 0);
+ if (!packet_ready) {
+ // if no more incoming packet, still wait for 20 microseconds
+ delayMicroseconds(20);
+ packet_len = ArtNetUdp->parsePacket();
+ packet_ready = (packet_len > 0);
+ }
+#endif
+ }
+ if (artnet_conf.on) { // ignore action if not on
+ if (artnet_conf.matrix) {
+ if (Ws2812StripRefresh()) {
+ artnet_conf.strip_refresh++; // record metric
+ }
+ }
+ }
+ }
+}
+
+
+//
+// Published state
+//
+void ArtNetJSONAppend(void) {
+ if (artnet_udp_connected) {
+ ResponseAppend_P(PSTR(",\"ArtNet\":{\"PacketsReceived\":%u,\"PacketsAccepted\":%u,\"Frames\":%u"),
+ artnet_conf.packet_received, artnet_conf.packet_accepted, artnet_conf.strip_refresh);
+ if (packets_per_row) {
+ ResponseAppend_P(PSTR(",\"PacketsPerRow\":["));
+ for (int32_t i = 0; i < artnet_conf.rows; i++) {
+ ResponseAppend_P(PSTR("%s%i"), i ? "," : "", packets_per_row[i]);
+ }
+ ResponseAppend_P(PSTR("]"));
+ }
+ ResponseAppend_P(PSTR("}"));
+ }
+}
+
+//
+// Command `ArtNetConfig`
+// Params: JSON
+// {"Rows":5, "Cols":5, "Offset":0, "Alternate":false, "Universe":0, "Port":6454}
+//
+void CmndArtNetConfig() {
+ bool was_running = artnet_udp_connected;
+ if (was_running) {
+ ArtNetStop();
+ }
+ ArtNetLoadSettings();
+
+ TrimSpace(XdrvMailbox.data);
+ if (strlen(XdrvMailbox.data) > 0) {
+ JsonParser parser(XdrvMailbox.data);
+ JsonParserObject root = parser.getRootObject();
+ if (!root) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; }
+
+ artnet_conf.rows = root.getUInt(PSTR("Rows"), artnet_conf.rows);
+ artnet_conf.cols = root.getUInt(PSTR("Cols"), artnet_conf.cols);
+ artnet_conf.offs = root.getUInt(PSTR("Offset"), artnet_conf.offs);
+ artnet_conf.alt = root.getBool(PSTR("Alternate"), artnet_conf.alt);
+ artnet_conf.univ = root.getUInt(PSTR("Universe"), artnet_conf.univ);
+ artnet_conf.port = root.getUInt(PSTR("Port"), artnet_conf.port);
+ artnet_conf.dimm = root.getUInt(PSTR("Dimmer"), artnet_conf.dimm);
+
+ ArtNetSaveSettings();
+ }
+
+ if (was_running) {
+ ArtNetStart();
+ }
+ // display the current or new configuration
+ // {"Rows":5, "Cols":5, "Offset":0, "Alternate":false, "Universe":0, "Port":6454}
+ Response_P(PSTR("{\"Rows\":%u,\"Cols\":%u,\"Dimmer\":%u,\"Offset\":%u"
+ ",\"Alternate\":%s,\"Universe\":%u,\"Port\":%u}"),
+ artnet_conf.rows, artnet_conf.cols, artnet_conf.dimm, artnet_conf.offs,
+ artnet_conf.alt ? "true":"false", artnet_conf.univ, artnet_conf.port);
+}
+
+// ArtNetStart
+// Returns true if ok
+bool ArtNetStart(void) {
+ ArtNetLoadSettings();
+ if (!artnet_udp_connected && !TasmotaGlobal.restart_flag) {
+ if (ArtNetUdp == nullptr) {
+#ifdef ESP8266
+ ArtNetUdp = new UdpListener(WS2812_ARTNET_UDP_MAX_PACKETS);
+#else
+ ArtNetUdp = new WiFiUDP();
+#endif
+ if (ArtNetUdp == nullptr) {
+ AddLog(LOG_LEVEL_INFO, PSTR("DMX: cannot allocate memory"));
+ return false;
+ }
+ }
+
+#ifdef ESP8266
+ ArtNetUdp->reset();
+ ip_addr_t addr = IPADDR4_INIT(INADDR_ANY);
+ if ((igmp_joingroup(WiFi.localIP(), IPAddress(USE_LIGHT_ARTNET_MCAST)) == ERR_OK) &&
+ (ArtNetUdp->listen(&addr, artnet_conf.port))) {
+ // if (ArtNetUdp->listen(&addr, artnet_conf.port)) {
+#else
+ if (ArtNetUdp->beginMulticast(IPAddress(USE_LIGHT_ARTNET_MCAST), artnet_conf.port)) {
+#endif
+ // OK
+ AddLog(LOG_LEVEL_INFO, PSTR("DMX: listening to port %i"), artnet_conf.port);
+ artnet_udp_connected = true;
+
+ packets_per_row = (uint32_t*) malloc(artnet_conf.rows * sizeof(uint32_t*));
+ if (packets_per_row) { memset((void*)packets_per_row, 0, artnet_conf.rows * sizeof(uint32_t*)); }
+ // set sleep to at most 5
+ if (TasmotaGlobal.sleep > WS2812_ARTNET_MAX_SLEEP) {
+ TasmotaGlobal.sleep = WS2812_ARTNET_MAX_SLEEP;
+ }
+
+ // change settings to ArtNet specific scheme
+ Settings->flag6.artnet_autorun = true;
+
+ // change strip configuration
+ if (artnet_conf.matrix) {
+ if ((Settings->light_pixels != artnet_conf.rows * artnet_conf.cols + artnet_conf.offs) || (Settings->light_rotation != 0)) {
+ Settings->light_pixels = artnet_conf.rows * artnet_conf.cols + artnet_conf.offs;
+ Settings->light_rotation = 0;
+ Ws2812ReinitStrip();
+ }
+ }
+
+ // turn power on if it's not
+ if (!(Light.power & 1)) {
+ LightPowerOn();
+ }
+ } else {
+ AddLog(LOG_LEVEL_INFO, PSTR("DMX: error opening port %i"), artnet_conf.port);
+ return false;
+ }
+ }
+ return true;
+}
+
+//
+// Command `ArtNetStart`
+// Params: XXX
+//
+void CmndArtNetStart(void) {
+ if (ArtNetStart()) {
+ ResponseCmndDone();
+ } else {
+ ResponseCmndError();
+ }
+}
+
+// Stop the ArtNet UDP flow and disconnect server
+void ArtNetStop(void) {
+ artnet_udp_connected = false;
+ if (ArtNetUdp != nullptr) {
+#ifdef ESP8266
+ ArtNetUdp->disconnect();
+#else
+ ArtNetUdp->stop();
+#endif
+ delete ArtNetUdp;
+ ArtNetUdp = nullptr;
+ }
+ if (packets_per_row) {
+ free((void*)packets_per_row);
+ packets_per_row = nullptr;
+ }
+}
+
+void CmndArtNetStop(void) {
+ ArtNetStop();
+ // restore default scheme
+ Settings->light_scheme = LS_POWER;
+ // Restore sleep value
+ TasmotaGlobal.sleep = Settings->sleep;
+ // OK
+ ResponseCmndDone();
+}
+
+#endif // USE_LIGHT_ARTNET
+#endif // USE_LIGHT
From 912574f8d7015a2bdb4de93251f5f592c8536be5 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Mon, 14 Nov 2022 01:18:32 +0100
Subject: [PATCH 185/319] unconditional RgxClients, ip dict with mac as key
---
platformio_tasmota_cenv_sample.ini | 1 -
.../xdrv_58_range_extender.ino | 17 +++++------------
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini
index 2eb6bce81..e086b1094 100644
--- a/platformio_tasmota_cenv_sample.ini
+++ b/platformio_tasmota_cenv_sample.ini
@@ -11,7 +11,6 @@ build_flags = ${env:tasmota32_base.build_flags}
-D FIRMWARE_TASMOTA32
-D USE_WIFI_RANGE_EXTENDER
-D USE_WIFI_RANGE_EXTENDER_NAPT
- -D USE_WIFI_RANGE_EXTENDER_CLIENTS
[env:tasmota32s3-file]
extends = env:tasmota32_base
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index c8af4b4d2..e5b26bef1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -96,10 +96,8 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
"|"
"NAPT"
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
-#ifdef USE_WIFI_RANGE_EXTENDER_CLIENTS
"|"
"Clients"
-#endif // USE_WIFI_RANGE_EXTENDER_CLIENTS
"|"
"Address"
"|"
@@ -112,9 +110,7 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
&CmndRgxNAPT,
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
-#ifdef USE_WIFI_RANGE_EXTENDER_CLIENTS
&CmndRgxClients,
-#endif // USE_WIFI_RANGE_EXTENDER_CLIENTS
&CmndRgxAddresses,
&CmndRgxAddresses,
};
@@ -133,6 +129,7 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
#ifdef ESP32
#include "lwip/lwip_napt.h"
#include
+#include "esp_wifi.h"
#endif // ESP32
#define RGX_NOT_CONFIGURED 0
@@ -172,29 +169,25 @@ void RgxCheckConfig(void)
}
}
-#ifdef USE_WIFI_RANGE_EXTENDER_CLIENTS
-#include "esp_wifi.h"
-
void CmndRgxClients(void)
{
wifi_sta_list_t wifi_sta_list = {0};
tcpip_adapter_sta_list_t adapter_sta_list = {0};
-
+
esp_wifi_ap_get_sta_list(&wifi_sta_list);
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
- Response_P(PSTR("["));
+ Response_P(PSTR("{\"RgxClients\":{"));
const char *sep = "";
for (int i=0; i
Date: Mon, 14 Nov 2022 01:47:00 +0100
Subject: [PATCH 186/319] add rssi for each entry of RgxClients list
---
tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index e5b26bef1..7eb017f29 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -173,7 +173,7 @@ void CmndRgxClients(void)
{
wifi_sta_list_t wifi_sta_list = {0};
tcpip_adapter_sta_list_t adapter_sta_list = {0};
-
+
esp_wifi_ap_get_sta_list(&wifi_sta_list);
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
@@ -182,8 +182,8 @@ void CmndRgxClients(void)
for (int i=0; i
Date: Mon, 14 Nov 2022 02:25:24 +0100
Subject: [PATCH 187/319] ap sta list header esp_wifi.h is ESP32 only
---
.../tasmota_xdrv_driver/xdrv_58_range_extender.ino | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 7eb017f29..d8a5125b7 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -35,8 +35,7 @@ CONFIG_LWIP_IP_FORWARD option set, and optionally CONFIG_LWIP_IPV4_NAPT.
If you want to support NAPT (removing the need for routes on a core router):
#define USE_WIFI_RANGE_EXTENDER_NAPT
-If you want to list AP clients (MAC and IP) with command RgxClients:
-#define USE_WIFI_RANGE_EXTENDER_CLIENTS
+List AP clients (MAC, IP and RSSI) with command RgxClients on ESP32
An example full static configuration:
@@ -96,8 +95,10 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
"|"
"NAPT"
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
+#ifdef ESP32
"|"
"Clients"
+#endif // ESP32
"|"
"Address"
"|"
@@ -110,7 +111,9 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
&CmndRgxNAPT,
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
+#ifdef ESP32
&CmndRgxClients,
+#endif // ESP32
&CmndRgxAddresses,
&CmndRgxAddresses,
};
@@ -169,6 +172,7 @@ void RgxCheckConfig(void)
}
}
+#ifdef ESP32
void CmndRgxClients(void)
{
wifi_sta_list_t wifi_sta_list = {0};
@@ -182,12 +186,13 @@ void CmndRgxClients(void)
for (int i=0; i
Date: Mon, 14 Nov 2022 12:04:36 +0100
Subject: [PATCH 188/319] Update changelogs
---
.github/PULL_REQUEST_TEMPLATE.md | 2 +-
CHANGELOG.md | 7 ++++---
RELEASENOTES.md | 9 ++++++---
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 88dc78c9d..839f266d8 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,7 +6,7 @@
- [ ] The pull request is done against the latest development branch
- [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
- - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9
+ - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4
- [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.5
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 63408c2e8..0ef41cf34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,8 +7,8 @@ All notable changes to this project will be documented in this file.
### Added
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
-- Added ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
-- Added WS2812 and Light ArtNet DMX control over UDP port 6454
+- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
+- WS2812 and Light ArtNet DMX control over UDP port 6454 (#17059)
### Breaking Changed
@@ -16,7 +16,8 @@ All notable changes to this project will be documented in this file.
- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
- TuyaMcu rewrite by btsimonh (#17051)
-- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds
+- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
+- ESP8266 core library rename from v2.7.4.9 to v2.7.4
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 6de9a4302..eb70b0d8e 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -31,11 +31,11 @@ While fallback or downgrading is common practice it was never supported due to S
## Supported Core versions
-This release will be supported from ESP8266/Arduino library Core version **2.7.4.9** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
+This release will be supported from ESP8266/Arduino library Core version **2.7.4** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
This release will be supported from ESP32/Arduino library Core version **2.0.5.3**.
-Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.5.3 have been removed.
+Support of ESP8266 Core versions before 2.7.4 and ESP32 Core versions before 2.0.5.3 have been removed.
## Support of TLS
@@ -52,7 +52,7 @@ Easy initial installation of Tasmota can be performed using the [Tasmota WebInst
## Provided Binary Downloads
### ESP8266 or ESP8285 based
-The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.4.9**.
+The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.4**.
- **tasmota.bin** = The Tasmota version with most drivers for 1M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota4M.bin** = The Tasmota version with most drivers and filesystem for 4M+ flash.
@@ -119,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971)
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
+- WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
@@ -128,12 +129,14 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
### Changed
+- ESP8266 core library rename from v2.7.4.9 to v2.7.4
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
- TuyaMcu rewrite by btsimonh [#17051](https://github.com/arendst/Tasmota/issues/17051)
+- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds [#17055](https://github.com/arendst/Tasmota/issues/17055)
### Fixed
- Serial bridge default serial configuration from 5N1 to 8N1 regression from v10.1.0.3
From bfbdd49aafe5a21d2247c30db5cbc6735e5e534c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 14 Nov 2022 12:52:25 +0100
Subject: [PATCH 189/319] Revert change 2.7.4.9
---
.github/PULL_REQUEST_TEMPLATE.md | 2 +-
CHANGELOG.md | 1 -
RELEASENOTES.md | 7 +++----
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 839f266d8..88dc78c9d 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -6,7 +6,7 @@
- [ ] The pull request is done against the latest development branch
- [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
- - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4
+ - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9
- [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.5
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0ef41cf34..148711895 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,7 +17,6 @@ All notable changes to this project will be documented in this file.
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
- TuyaMcu rewrite by btsimonh (#17051)
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
-- ESP8266 core library rename from v2.7.4.9 to v2.7.4
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index eb70b0d8e..cc3faf528 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -31,11 +31,11 @@ While fallback or downgrading is common practice it was never supported due to S
## Supported Core versions
-This release will be supported from ESP8266/Arduino library Core version **2.7.4** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
+This release will be supported from ESP8266/Arduino library Core version **2.7.4.9** due to reported security and stability issues on previous Core version. This will also support gzipped binaries.
This release will be supported from ESP32/Arduino library Core version **2.0.5.3**.
-Support of ESP8266 Core versions before 2.7.4 and ESP32 Core versions before 2.0.5.3 have been removed.
+Support of ESP8266 Core versions before 2.7.4.9 and ESP32 Core versions before 2.0.5.3 have been removed.
## Support of TLS
@@ -52,7 +52,7 @@ Easy initial installation of Tasmota can be performed using the [Tasmota WebInst
## Provided Binary Downloads
### ESP8266 or ESP8285 based
-The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.4**.
+The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.4.9**.
- **tasmota.bin** = The Tasmota version with most drivers for 1M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota4M.bin** = The Tasmota version with most drivers and filesystem for 4M+ flash.
@@ -129,7 +129,6 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
### Changed
-- ESP8266 core library rename from v2.7.4.9 to v2.7.4
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
From aad82c027f02be5cf8791f94eaddbe6f5a8d1e2b Mon Sep 17 00:00:00 2001
From: joba-1
Date: Mon, 14 Nov 2022 13:02:04 +0100
Subject: [PATCH 190/319] change rgx client mac format in list as requested
---
tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index d8a5125b7..7352861dd 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -186,7 +186,7 @@ void CmndRgxClients(void)
for (int i=0; i
Date: Mon, 14 Nov 2022 14:20:41 +0100
Subject: [PATCH 191/319] Rename ArtNet to Art-Net
---
CHANGELOG.md | 8 ++++----
RELEASENOTES.md | 4 ++--
tasmota/my_user_config.h | 2 +-
tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 148711895..665c9659b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
-- WS2812 and Light ArtNet DMX control over UDP port 6454 (#17059)
+- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
### Breaking Changed
@@ -39,9 +39,9 @@ All notable changes to this project will be documented in this file.
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
- Berry ``bytes().reverse()`` method (#16977)
-- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
+- ESP32 Support for DMX Art-Net Led matrix animations (#16984)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
-- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
+- ESP32 DMX Art-Net optimization to avoid any object allocation and avoid garbage collector pauses
- Berry add ``dyn`` class
### Changed
@@ -64,7 +64,7 @@ All notable changes to this project will be documented in this file.
- Berry add `bytes().setbytes()` (#16892)
- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
-- Prepare for DMX Artnet support on ESP32
+- Prepare for DMX Art-Net support on ESP32
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index cc3faf528..fdc8a7b16 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -119,11 +119,11 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971)
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
-- WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
+- WS2812 and Light Art-Net DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
-- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
+- ESP32 Support for DMX Art-Net Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
### Breaking Changed
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index c59d4a5ea..e2803f8d4 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -571,7 +571,7 @@
#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code)
//#define USE_LSC_MCSL // Add support for GPE Multi color smart light as sold by Action in the Netherlands (+1k1 code)
-// #define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code)
+// #define USE_LIGHT_ARTNET // Add support for DMX/Art-Net via UDP on port 6454 (+3.5k code)
#define USE_LIGHT_ARTNET_MCAST 239,255,25,54 // Multicast address used to listen: 239.255.25.24
// -- Counter input -------------------------------
diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
index c0f7ff7e5..9d6e36f15 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
@@ -785,7 +785,7 @@ void CmndWidth(void)
}
/*********************************************************************************************\
- * Internal calls for ArtNet
+ * Internal calls for Art-Net
\*********************************************************************************************/
// check is the Neopixel strip is configured
bool Ws2812StripConfigured(void) {
From 5b1aff5141841ab601eea7219ab3cefb6fe66804 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 14 Nov 2022 17:11:38 +0100
Subject: [PATCH 192/319] Add RTC logging to energy
---
tasmota/tasmota.ino | 4 ++--
tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 8 ++++++++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 4681a56ef..a9c6f6ba9 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -127,7 +127,7 @@ typedef struct {
} TRtcReboot;
TRtcReboot RtcReboot;
#ifdef ESP32
-RTC_NOINIT_ATTR TRtcReboot RtcDataReboot;
+static RTC_NOINIT_ATTR TRtcReboot RtcDataReboot;
#endif // ESP32
typedef struct {
@@ -154,7 +154,7 @@ typedef struct {
} TRtcSettings;
TRtcSettings RtcSettings;
#ifdef ESP32
-RTC_NOINIT_ATTR TRtcSettings RtcDataSettings;
+static RTC_NOINIT_ATTR TRtcSettings RtcDataSettings;
#endif // ESP32
struct TIME_T {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index 27b941ac2..ba8ca1c53 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -347,6 +347,7 @@ void Energy200ms(void)
if (!Energy.kWhtoday_offset_init && (RtcTime.day_of_year == Settings->energy_kWhdoy)) {
for (uint32_t i = 0; i < 3; i++) {
Energy.kWhtoday_offset[i] = Settings->energy_kWhtoday_ph[i];
+// RtcSettings.energy_kWhtoday_ph[i] = 0;
}
Energy.kWhtoday_offset_init = true;
}
@@ -1107,6 +1108,13 @@ void EnergySnsInit(void)
XnrgCall(FUNC_INIT);
if (TasmotaGlobal.energy_driver) {
+
+ AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: Rtc valid %d, kWhtoday_ph Rtc %d/%d/%d, Set %d/%d/%d"),
+ RtcSettingsValid(),
+ RtcSettings.energy_kWhtoday_ph[0],RtcSettings.energy_kWhtoday_ph[1],RtcSettings.energy_kWhtoday_ph[2],
+ Settings->energy_kWhtoday_ph[0],Settings->energy_kWhtoday_ph[1],Settings->energy_kWhtoday_ph[2]
+ );
+
for (uint32_t i = 0; i < 3; i++) {
// Energy.kWhtoday_offset[i] = 0; // Reset by EnergyDrvInit()
// 20220805 - Change from https://github.com/arendst/Tasmota/issues/16118
From 62c3a92ae794286768ebfa5277ed4bb3634eb7c6 Mon Sep 17 00:00:00 2001
From: Cyril Pawelko
Date: Mon, 14 Nov 2022 18:42:57 +0100
Subject: [PATCH 193/319] Zigbee plugin to fix Moes-Tuya KCTW1Z Humidity
For device
Should work with TS0201:_TZ3000_itnrsufe , regarding https://zigbee.blakadder.com/Tuya_KCTW1Z.html
---
tasmota/zigbee/Tuya_KCTW1Z.zb | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 tasmota/zigbee/Tuya_KCTW1Z.zb
diff --git a/tasmota/zigbee/Tuya_KCTW1Z.zb b/tasmota/zigbee/Tuya_KCTW1Z.zb
new file mode 100644
index 000000000..f778cc983
--- /dev/null
+++ b/tasmota/zigbee/Tuya_KCTW1Z.zb
@@ -0,0 +1,5 @@
+#Z2Tv1
+# Tuya fix humidity by 10
+# https://zigbee.blakadder.com/Tuya_KCTW1Z.html
+:TS0201,_TZ3000_ywagc4rj
+0405/0000=0405/0000,mul:10
From 20d9975d6f30d78781c865708692c39d71df0cc3 Mon Sep 17 00:00:00 2001
From: Andreas Achtzehn
Date: Mon, 14 Nov 2022 20:20:04 +0100
Subject: [PATCH 194/319] Support for I2C device HMC5883L (3-axis magnetic
sensor)
---
I2CDEVICES.md | 1 +
tasmota/my_user_config.h | 1 +
.../tasmota_xsns_sensor/xsns_101_hmc5883l.ino | 249 ++++++++++++++++++
3 files changed, 251 insertions(+)
create mode 100644 tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino
diff --git a/I2CDEVICES.md b/I2CDEVICES.md
index d3b2cd418..3ef236eeb 100644
--- a/I2CDEVICES.md
+++ b/I2CDEVICES.md
@@ -107,3 +107,4 @@ Index | Define | Driver | Device | Address(es) | Description
70 | USE_LUXV30B | xsns_99 | LUXV30B | 0x4A | DFRobot SEN0390 V30B lux sensor
71 | USE_QMC5883L | xsns_33 | QMC5883L | 0x0D | Magnetic Field Sensor
72 | USE_INA3221 | xsns_100 | INA3221 | 0x40-0x43 | 3-channels Voltage and Current sensor
+ 73 | USE_HMC5883L | xsns_101 | HMC5883L | 0x1E | 3-channels Magnetic Field Sensor
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e2803f8d4..23415f8fd 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -691,6 +691,7 @@
// #define USE_HYT // [I2CDriver68] Enable HYTxxx temperature and humidity sensor (I2C address 0x28) (+0k5 code)
// #define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code)
// #define USE_QMC5883L // [I2CDriver71] Enable QMC5883L magnetic induction sensor (I2C address 0x0D) (+0k8 code)
+// #define USE_HMC5883L // [I2CDriver73] Enable HMC5883L magnetic induction sensor (I2C address 0x1E)
// #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
// #define USE_INA3221 // [I2CDriver72] Enable INA3221 3-channel DC voltage and current sensor (I2C address 0x40-0x44) (+3.2k code)
// #define INA3221_ADDRESS1 // allow to change the 1st address to search for INA3221 to 0x41..0x43
diff --git a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino
new file mode 100644
index 000000000..56a311354
--- /dev/null
+++ b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino
@@ -0,0 +1,249 @@
+/*
+ xsns_101_hmc5883l.ino - HMC5883L 3-Axis Digital Compass sensor support for Tasmota
+ (inspired by Helge Scheunemann)
+ Copyright (C) 2022 Andreas Achtzehn
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_I2C
+#ifdef USE_HMC5883L
+/*********************************************************************************************\
+ * HMC5883L is 3-Axis Digital Compass sensor
+ *
+ * Datasheet: https://cdn-shop.adafruit.com/datasheets/HMC5883L_3-Axis_Digital_Compass_IC.pdf
+ * I2C Address: 0x1E
+\*********************************************************************************************/
+
+// Define driver ID
+#define XSNS_101 101
+#define XI2C_73 73 // See I2CDEVICES.md
+
+/* The default I2C address of this chip */
+#define HMC5883L_ADDR 0x1E
+
+/* Register locations */
+#define HMC5883L_X_LSB 0x04
+#define HMC5883L_X_MSB 0x03
+#define HMC5883L_Y_LSB 0x08
+#define HMC5883L_Y_MSB 0x07
+#define HMC5883L_Z_LSB 0x06
+#define HMC5883L_Z_MSB 0x05
+#define HMC5883L_STATUS 0x09
+#define HMC5883L_CONFIG_A 0x00
+#define HMC5883L_CONFIG_B 0x01
+#define HMC5883L_MODE 0x02
+#define HMC5883L_CHIP_ID_A 0x0A
+#define HMC5883L_CHIP_ID_B 0x0B
+#define HMC5883L_CHIP_ID_C 0x0C
+
+/* Bit values for the STATUS register */
+const uint8_t HMC5883L_STATUS_RDY = 0b00000001;
+const uint8_t HMC5883L_STATUS_LOCK = 0b00000010;
+
+/* Modes for the sampling in the MODE register */
+const uint8_t HMC5883L_MODE_CONT = 0b00000000;
+const uint8_t HMC5883L_MODE_SINGLE = 0b00000001;
+const uint8_t HMC5883L_MODE_IDLE = 0b00000010;
+
+/* Gain value mask for CONFIG B register */
+const uint8_t HMC5883L_CONFIG_B_GAIN_MASK = 0b11100000; // shift operation, values 0-7
+const uint8_t HMC5883L_CONFIG_B_GAIN_SHIFT = 5;
+
+/* Averaging value for CONFIG A register: pow(2,N) */
+const uint8_t HMC5883L_CONFIG_A_AVG_MASK = 0b01100000;
+const uint8_t HMC5883L_CONFIG_A_AVG_SHIFT = 5;
+
+/* Data output rate */
+const uint8_t HMC5883L_CONFIG_A_RATE_MASK = 0b00011100;
+const uint8_t HMC5883L_CONFIG_A_RATE_SHIFT = 2;
+
+/* Data measurement mode */
+const uint8_t HMC5883L_CONFIG_A_MMODE_NORM = 0;
+const uint8_t HMC5883L_CONFIG_A_MMODE_POSBIAS = 1;
+const uint8_t HMC5883L_CONFIG_A_MMODE_NEGBIAS = 2;
+const uint8_t HMC5883L_CONFIG_A_MMODE_MASK = 0b00000011;
+const uint8_t HMC5883L_CONFIG_A_MMODE_SHIFT = 0;
+
+/* Data output X register A contains the MSB from the measurement result,
+and data output X register B contains the LSB from the measurement result. The value stored in these two registers is a
+16-bit value in 2’s complement form, whose range is 0xF800 to 0x07FF. */
+
+
+
+ // data field
+struct HMC5883L_s {
+ int16_t MX, MY, MZ;
+ uint16_t magnitude;
+ int8_t measurement_mode;
+ int8_t data_rate;
+ int8_t average_mode;
+ int8_t gain;
+ int8_t mode;
+} *HMC5883L = nullptr;
+
+
+// Change configuration registers of the device
+bool HMC5883L_SetConfig() {
+ if ( HMC5883L == nullptr ) { return false; }
+
+ uint8_t cfgA = (( (HMC5883L->measurement_mode) << HMC5883L_CONFIG_A_MMODE_SHIFT ) & HMC5883L_CONFIG_A_MMODE_MASK ) |
+ (( (HMC5883L->data_rate ) << HMC5883L_CONFIG_A_RATE_SHIFT ) & HMC5883L_CONFIG_A_RATE_MASK ) |
+ (( (HMC5883L->average_mode ) << HMC5883L_CONFIG_A_AVG_SHIFT ) & HMC5883L_CONFIG_A_AVG_MASK );
+
+ uint8_t cfgB = (( (HMC5883L->gain ) << HMC5883L_CONFIG_B_GAIN_SHIFT ) & HMC5883L_CONFIG_B_GAIN_MASK );
+
+ AddLog(LOG_LEVEL_INFO,"HMC5883L: CONFIG A: %#X CONFIG B: %#X MODE: %#X",cfgA, cfgB, HMC5883L->mode);
+
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_A, cfgA ) == false) {
+ AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting CONFIG A failed.");
+ return false;
+ }
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_B, cfgB ) == false) {
+ AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting CONFIG B failed.");
+ return false;
+ }
+ if (HMC5883L->mode == HMC5883L_MODE_CONT) {
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_CONT ) == false)
+ { AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting continuous mode failed.");
+ return false; }
+ }
+ return true;
+}
+
+// Initialize the device
+void HMC5883L_Init() {
+ if (!I2cSetDevice(HMC5883L_ADDR)) { return; }
+
+ HMC5883L = (HMC5883L_s *)calloc(1, sizeof(struct HMC5883L_s));
+ // standard configuration
+ HMC5883L->gain = 5;
+ HMC5883L->average_mode = 3;
+ HMC5883L->data_rate = 2;
+ HMC5883L->measurement_mode = HMC5883L_CONFIG_A_MMODE_NORM;
+ HMC5883L->mode = HMC5883L_MODE_SINGLE;
+
+ HMC5883L_SetConfig();
+
+ I2cSetActiveFound(HMC5883L_ADDR, "HMC5883L");
+}
+
+//Read the magnetic data
+void HMC5883L_ReadData(void) {
+ if (HMC5883L->mode == HMC5883L_MODE_SINGLE) {
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_SINGLE ) == false)
+ { return; }
+ }
+
+ while (!(I2cRead8(HMC5883L_ADDR, HMC5883L_STATUS) & HMC5883L_STATUS_RDY)) { } // Chip not yet ready, next round try again
+
+ HMC5883L->MX = I2cReadS16(HMC5883L_ADDR, HMC5883L_X_MSB); // Select starting with MSB register
+ HMC5883L->MY = I2cReadS16(HMC5883L_ADDR, HMC5883L_Y_MSB);
+ HMC5883L->MZ = I2cReadS16(HMC5883L_ADDR, HMC5883L_Z_MSB);
+
+ // calculate magnetic induction magnitude
+ HMC5883L->magnitude = SqrtInt((HMC5883L->MX * HMC5883L->MX) + (HMC5883L->MY * HMC5883L->MY) + (HMC5883L->MZ * HMC5883L->MZ));
+}
+
+/*********************************************************************************************\
+ * Presentation
+\*********************************************************************************************/
+
+#ifdef USE_WEBSERVER
+const char HTTP_SNS_HMC5883L[] PROGMEM =
+ "{s}HMC5883L " D_MX "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = , {m} = | , {e} = |
+ "{s}HMC5883L " D_MY "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = , {m} = | , {e} = |
+ "{s}HMC5883L " D_MZ "{m}%d " D_UNIT_MICROTESLA "{e}" // {s} = , {m} = | , {e} = |
+ "{s}HMC5883L " D_MAGNETICFLD "{m}%d " D_UNIT_MICROTESLA "{e}"; // {s} = , {m} = | , {e} = |
+#endif
+
+void HMC5883L_Show(uint8_t json) {
+ if (json) {
+ ResponseAppend_P(PSTR(",\"HMC5883L\":{\"" D_JSON_MX "\":%d,\"" D_JSON_MY "\":%d,\"" D_JSON_MZ "\":%d,\"" D_JSON_MAGNETICFLD "\":%u,\""),
+ HMC5883L->MX, HMC5883L->MY, HMC5883L->MZ, HMC5883L->magnitude);
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_PD(HTTP_SNS_HMC5883L, HMC5883L->MX, HMC5883L->MY, HMC5883L->MZ, HMC5883L->magnitude);
+#endif
+ }
+}
+
+// Process configuration commands
+bool HMC5883L_Command() {
+ bool commandKnown = false;
+ char cmd[20];
+ char ss2[20];
+
+ subStr(cmd, XdrvMailbox.data, ",", 1);
+ int8_t value = atoi(subStr(ss2, XdrvMailbox.data, ",", 2));
+
+ if (strcmp(cmd,"GAIN")) {
+ HMC5883L->gain = value;
+ commandKnown = true;
+ }
+ if (strcmp(cmd,"AVG")) {
+ HMC5883L->average_mode = value;
+ commandKnown = true;
+ }
+ if (strcmp(cmd,"RATE")) {
+ HMC5883L->data_rate = value;
+ commandKnown = true;
+ }
+ if (strcmp(cmd,"MMODE")) {
+ HMC5883L->measurement_mode = value;
+ commandKnown = true;
+ }
+
+ //AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC5883L: cmd: (%s) value: %d cmdKnown: %d"), cmd, value,commandKnown);
+
+ if (commandKnown == false) { return false; }
+
+ AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC5883L: Reconfiguring."));
+
+ return HMC5883L_SetConfig();
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns101(uint32_t function) {
+ if (!I2cEnabled(XI2C_73)) { return false; }
+
+ if (FUNC_INIT == function) {
+ HMC5883L_Init();
+ }
+ else if (HMC5883L != nullptr) {
+ switch (function) {
+ case FUNC_COMMAND_SENSOR:
+ if (XSNS_101 == XdrvMailbox.index)
+ return HMC5883L_Command(); // Return true on success
+ break;
+ case FUNC_JSON_APPEND:
+ HMC5883L_Show(1);
+ break;
+ case FUNC_EVERY_SECOND:
+ HMC5883L_ReadData();
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ HMC5883L_Show(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return true;
+}
+#endif // USE_HMC5883L
+#endif // USE_I2C
From 7950800cb22df97e54866303b80ddee55f656420 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 14 Nov 2022 21:15:38 +0100
Subject: [PATCH 195/319] ESP32 LVGL library from v8.3.2 to v8.3.3 (no
functional change)
---
CHANGELOG.md | 1 +
lib/libesp32_lvgl/lvgl/library.json | 2 +-
lib/libesp32_lvgl/lvgl/library.properties | 2 +-
lib/libesp32_lvgl/lvgl/lv_conf_template.h | 2 +-
lib/libesp32_lvgl/lvgl/lvgl.h | 2 +-
5 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 665c9659b..739f5543b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
- TuyaMcu rewrite by btsimonh (#17051)
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
+- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/lib/libesp32_lvgl/lvgl/library.json b/lib/libesp32_lvgl/lvgl/library.json
index 58e13fca2..fe8ef4c15 100644
--- a/lib/libesp32_lvgl/lvgl/library.json
+++ b/lib/libesp32_lvgl/lvgl/library.json
@@ -1,6 +1,6 @@
{
"name": "lvgl",
- "version": "8.3.2",
+ "version": "8.3.3",
"keywords": "graphics, gui, embedded, tft, lvgl",
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
"repository": {
diff --git a/lib/libesp32_lvgl/lvgl/library.properties b/lib/libesp32_lvgl/lvgl/library.properties
index 2d4880773..816446a93 100644
--- a/lib/libesp32_lvgl/lvgl/library.properties
+++ b/lib/libesp32_lvgl/lvgl/library.properties
@@ -1,5 +1,5 @@
name=lvgl
-version=8.3.2
+version=8.3.3
author=kisvegabor
maintainer=kisvegabor,embeddedt,pete-pjb
sentence=Full-featured Graphics Library for Embedded Systems
diff --git a/lib/libesp32_lvgl/lvgl/lv_conf_template.h b/lib/libesp32_lvgl/lvgl/lv_conf_template.h
index 618bf7f92..3d087f0f3 100644
--- a/lib/libesp32_lvgl/lvgl/lv_conf_template.h
+++ b/lib/libesp32_lvgl/lvgl/lv_conf_template.h
@@ -1,6 +1,6 @@
/**
* @file lv_conf.h
- * Configuration file for v8.3.2
+ * Configuration file for v8.3.3
*/
/*
diff --git a/lib/libesp32_lvgl/lvgl/lvgl.h b/lib/libesp32_lvgl/lvgl/lvgl.h
index 4cd9a8326..c0be411b2 100644
--- a/lib/libesp32_lvgl/lvgl/lvgl.h
+++ b/lib/libesp32_lvgl/lvgl/lvgl.h
@@ -15,7 +15,7 @@ extern "C" {
***************************/
#define LVGL_VERSION_MAJOR 8
#define LVGL_VERSION_MINOR 3
-#define LVGL_VERSION_PATCH 1
+#define LVGL_VERSION_PATCH 3
#define LVGL_VERSION_INFO ""
/*********************
From d2d384dc72c02a0d74c485b67787f33cd2e98aae Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 14 Nov 2022 22:46:08 +0100
Subject: [PATCH 196/319] Zigbee improved Aqara plug support and completed
cluster 0x0702
---
CHANGELOG.md | 1 +
.../xdrv_23_zigbee_5_0_constants.ino | 1146 +++++++++--------
.../xdrv_23_zigbee_5_1_attributes.ino | 30 +-
.../xdrv_23_zigbee_5_2_converters.ino | 33 +-
tasmota/zigbee/Aqara_plug.zb | 6 +
5 files changed, 653 insertions(+), 563 deletions(-)
create mode 100644 tasmota/zigbee/Aqara_plug.zb
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 665c9659b..dcde1f5df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
- TuyaMcu rewrite by btsimonh (#17051)
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
+- Zigbee improved Aqara plug support and completed cluster 0x0702
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_0_constants.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_0_constants.ino
index 9320867e2..38e1e7bac 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_0_constants.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_0_constants.ino
@@ -287,15 +287,28 @@ const char Z_strings[] PROGMEM =
"ConfigStatus" "\x00"
"Contact" "\x00"
"ControlSequenceOfOperation" "\x00"
+ "ControlTemperature" "\x00"
"Coordinate1" "\x00"
"Coordinate2" "\x00"
"Coordinate3" "\x00"
+ "CurrentBlock" "\x00"
+ "CurrentBlockPeriodConsumptionDelivered" "\x00"
"CurrentGroup" "\x00"
+ "CurrentInletEnergyCarrierDemand" "\x00"
+ "CurrentInletEnergyCarrierSummation" "\x00"
+ "CurrentMaxDemandDelivered" "\x00"
+ "CurrentMaxDemandDeliveredTime" "\x00"
+ "CurrentMaxDemandReceived" "\x00"
+ "CurrentMaxDemandReceivedTime" "\x00"
+ "CurrentOutletEnergyCarrierDemand" "\x00"
+ "CurrentOutletEnergyCarrierSummation" "\x00"
"CurrentPositionLift" "\x00"
"CurrentPositionLiftPercentage" "\x00"
"CurrentPositionTilt" "\x00"
"CurrentPositionTiltPercentage" "\x00"
"CurrentScene" "\x00"
+ "CurrentSummationDelivered" "\x00"
+ "CurrentSummationReceived" "\x00"
"CurrentTemperature" "\x00"
"CurrentTemperatureSetPoint" "\x00"
"CurrentZoneSensitivityLevel" "\x00"
@@ -318,10 +331,14 @@ const char Z_strings[] PROGMEM =
"DCVoltageMin" "\x00"
"DCVoltageMultiplier" "\x00"
"DCVoltageOverload" "\x00"
+ "DFTSummation" "\x00"
+ "DailyConsumptionTarget" "\x00"
+ "DailyFreezeTime" "\x00"
"DataQualityID" "\x00"
"DateCode" "\x00"
"DecelerationTimeLift" "\x00"
"DefaultMoveRate" "\x00"
+ "DefaultUpdatePeriod" "\x00"
"DehumidificationCooling" "\x00"
"DehumidificationHysteresis" "\x00"
"DehumidificationLockout" "\x00"
@@ -355,7 +372,6 @@ const char Z_strings[] PROGMEM =
"ElectricalMeasurementType" "\x00"
"EnergyFormatting" "\x00"
"EnergyRemote" "\x00"
- "EnergyTotal" "\x00"
"EnhancedColorMode" "\x00"
"EnhancedCurrentHue" "\x00"
"EurotronicErrors" "\x00"
@@ -364,10 +380,12 @@ const char Z_strings[] PROGMEM =
"FanModeSequence" "\x00"
"FastPollTimeout" "\x00"
"FastPollTimeoutMax" "\x00"
+ "FastPollUpdatePeriod" "\x00"
"Fire" "\x00"
"FlowMaxMeasuredValue" "\x00"
"FlowMinMeasuredValue" "\x00"
"FlowRate" "\x00"
+ "FlowRestriction" "\x00"
"FlowTolerance" "\x00"
"GPHueStop" "\x00"
"GPIdentify" "\x00"
@@ -455,12 +473,14 @@ const char Z_strings[] PROGMEM =
"IlluminanceMinMeasuredValue" "\x00"
"IlluminanceTargetLevel" "\x00"
"IlluminanceTolerance" "\x00"
+ "InletTemperature" "\x00"
"InstalledClosedLimitLift" "\x00"
"InstalledClosedLimitTilt" "\x00"
"InstalledOpenLimitLift" "\x00"
"InstalledOpenLimitTilt" "\x00"
"IntermediateSetpointsLift" "\x00"
"IntermediateSetpointsTilt" "\x00"
+ "IntervalReadReportingPeriod" "\x00"
"IntrinsicBallastFactor" "\x00"
"LampAlarmMode" "\x00"
"LampBurnHours" "\x00"
@@ -610,6 +630,7 @@ const char Z_strings[] PROGMEM =
"OpenPeriod" "\x00"
"OppleMode" "\x00"
"OutdoorTemperature" "\x00"
+ "OutletTemperature" "\x00"
"OverTempTotalDwell" "\x00"
"PICoolingDemand" "\x00"
"PIHeatingDemand" "\x00"
@@ -638,6 +659,7 @@ const char Z_strings[] PROGMEM =
"PowerOnTimer" "\x00"
"PowerSource" "\x00"
"PowerThreshold" "\x00"
+ "PresetReadingTime" "\x00"
"Pressure" "\x00"
"PressureMaxMeasuredValue" "\x00"
"PressureMaxScaledValue" "\x00"
@@ -647,6 +669,7 @@ const char Z_strings[] PROGMEM =
"PressureScaledTolerance" "\x00"
"PressureScaledValue" "\x00"
"PressureTolerance" "\x00"
+ "PreviousBlockPeriodConsumptionDelivered" "\x00"
"Primary1Intensity" "\x00"
"Primary1X" "\x00"
"Primary1Y" "\x00"
@@ -668,6 +691,7 @@ const char Z_strings[] PROGMEM =
"ProductCode" "\x00"
"ProductRevision" "\x00"
"ProductURL" "\x00"
+ "ProfileIntervalPeriod" "\x00"
"ProxyTable" "\x00"
"QualityMeasure" "\x00"
"RGB" "\x00"
@@ -712,6 +736,7 @@ const char Z_strings[] PROGMEM =
"ReactivePower" "\x00"
"ReactivePowerPhB" "\x00"
"ReactivePowerPhC" "\x00"
+ "ReadingSnapShotTime" "\x00"
"RecallScene" "\x00"
"RelativeHumidity" "\x00"
"RelativeHumidityDisplay" "\x00"
@@ -753,6 +778,7 @@ const char Z_strings[] PROGMEM =
"StartUpOnOff" "\x00"
"Status" "\x00"
"StoreScene" "\x00"
+ "SupplyStatus" "\x00"
"SwitchActions" "\x00"
"SwitchType" "\x00"
"SystemMode" "\x00"
@@ -797,6 +823,7 @@ const char Z_strings[] PROGMEM =
"VelocityLift" "\x00"
"ViewGroup" "\x00"
"ViewScene" "\x00"
+ "VolumePerReport" "\x00"
"Water" "\x00"
"WhitePointX" "\x00"
"WhitePointY" "\x00"
@@ -1047,551 +1074,578 @@ enum Z_offsets {
Zo_ConfigStatus = 3878,
Zo_Contact = 3891,
Zo_ControlSequenceOfOperation = 3899,
- Zo_Coordinate1 = 3926,
- Zo_Coordinate2 = 3938,
- Zo_Coordinate3 = 3950,
- Zo_CurrentGroup = 3962,
- Zo_CurrentPositionLift = 3975,
- Zo_CurrentPositionLiftPercentage = 3995,
- Zo_CurrentPositionTilt = 4025,
- Zo_CurrentPositionTiltPercentage = 4045,
- Zo_CurrentScene = 4075,
- Zo_CurrentTemperature = 4088,
- Zo_CurrentTemperatureSetPoint = 4107,
- Zo_CurrentZoneSensitivityLevel = 4134,
- Zo_CustomerName = 4162,
- Zo_DCCurrent = 4175,
- Zo_DCCurrentDivisor = 4185,
- Zo_DCCurrentMax = 4202,
- Zo_DCCurrentMin = 4215,
- Zo_DCCurrentMultiplier = 4228,
- Zo_DCCurrentOverload = 4248,
- Zo_DCOverloadAlarmsMask = 4266,
- Zo_DCPower = 4287,
- Zo_DCPowerDivisor = 4295,
- Zo_DCPowerMax = 4310,
- Zo_DCPowerMin = 4321,
- Zo_DCPowerMultiplier = 4332,
- Zo_DCVoltage = 4350,
- Zo_DCVoltageDivisor = 4360,
- Zo_DCVoltageMax = 4377,
- Zo_DCVoltageMin = 4390,
- Zo_DCVoltageMultiplier = 4403,
- Zo_DCVoltageOverload = 4423,
- Zo_DataQualityID = 4441,
- Zo_DateCode = 4455,
- Zo_DecelerationTimeLift = 4464,
- Zo_DefaultMoveRate = 4485,
- Zo_DehumidificationCooling = 4501,
- Zo_DehumidificationHysteresis = 4525,
- Zo_DehumidificationLockout = 4552,
- Zo_DehumidificationMaxCool = 4576,
- Zo_DeviceEnabled = 4600,
- Zo_DeviceTempAlarmMask = 4614,
- Zo_Dimmer = 4634,
- Zo_DimmerCurrentFrequency = 4641,
- Zo_DimmerDown = 4664,
- Zo_DimmerMaxFrequency = 4675,
- Zo_DimmerMaxLevel = 4694,
- Zo_DimmerMinFrequency = 4709,
- Zo_DimmerMinLevel = 4728,
- Zo_DimmerMove = 4743,
- Zo_DimmerOptions = 4754,
- Zo_DimmerRemainingTime = 4768,
- Zo_DimmerStartUpLevel = 4788,
- Zo_DimmerStep = 4807,
- Zo_DimmerStepDown = 4818,
- Zo_DimmerStepUp = 4833,
- Zo_DimmerStop = 4846,
- Zo_DimmerUp = 4857,
- Zo_DisableLocalConfig = 4866,
- Zo_DoorClosedEvents = 4885,
- Zo_DoorOpenEvents = 4902,
- Zo_DoorState = 4917,
- Zo_DriftCompensation = 4927,
- Zo_DstEnd = 4945,
- Zo_DstShift = 4952,
- Zo_DstStart = 4961,
- Zo_ElectricalMeasurementType = 4970,
- Zo_EnergyFormatting = 4996,
- Zo_EnergyRemote = 5013,
- Zo_EnergyTotal = 5026,
- Zo_EnhancedColorMode = 5038,
- Zo_EnhancedCurrentHue = 5056,
- Zo_EurotronicErrors = 5075,
- Zo_EurotronicHostFlags = 5092,
- Zo_FanMode = 5112,
- Zo_FanModeSequence = 5120,
- Zo_FastPollTimeout = 5136,
- Zo_FastPollTimeoutMax = 5152,
- Zo_Fire = 5171,
- Zo_FlowMaxMeasuredValue = 5176,
- Zo_FlowMinMeasuredValue = 5197,
- Zo_FlowRate = 5218,
- Zo_FlowTolerance = 5227,
- Zo_GPHueStop = 5241,
- Zo_GPIdentify = 5251,
- Zo_GPLevelStop = 5262,
- Zo_GPLockDoor = 5274,
- Zo_GPMoveColor = 5285,
- Zo_GPMoveDown = 5297,
- Zo_GPMoveDownOnOff = 5308,
- Zo_GPMoveHueDown = 5324,
- Zo_GPMoveHueUp = 5338,
- Zo_GPMoveSatDown = 5350,
- Zo_GPMoveSatUp = 5364,
- Zo_GPMoveUp = 5376,
- Zo_GPMoveUpOnOff = 5385,
- Zo_GPOff = 5399,
- Zo_GPOn = 5405,
- Zo_GPPress1of1 = 5410,
- Zo_GPPress1of2 = 5422,
- Zo_GPPress2of2 = 5434,
- Zo_GPRelease = 5446,
- Zo_GPRelease1of1 = 5456,
- Zo_GPRelease1of2 = 5470,
- Zo_GPRelease2of2 = 5484,
- Zo_GPSatStop = 5498,
- Zo_GPScene0 = 5508,
- Zo_GPScene1 = 5517,
- Zo_GPScene10 = 5526,
- Zo_GPScene11 = 5536,
- Zo_GPScene12 = 5546,
- Zo_GPScene13 = 5556,
- Zo_GPScene14 = 5566,
- Zo_GPScene15 = 5576,
- Zo_GPScene2 = 5586,
- Zo_GPScene3 = 5595,
- Zo_GPScene4 = 5604,
- Zo_GPScene5 = 5613,
- Zo_GPScene6 = 5622,
- Zo_GPScene7 = 5631,
- Zo_GPScene8 = 5640,
- Zo_GPScene9 = 5649,
- Zo_GPShortPress1of1 = 5658,
- Zo_GPShortPress1of2 = 5675,
- Zo_GPShortPress2of2 = 5692,
- Zo_GPStepColor = 5709,
- Zo_GPStepDown = 5721,
- Zo_GPStepDownOnOff = 5732,
- Zo_GPStepHueDown = 5748,
- Zo_GPStepHueUp = 5762,
- Zo_GPStepSatDown = 5774,
- Zo_GPStepSatUp = 5788,
- Zo_GPStepUp = 5800,
- Zo_GPStepUpOnOff = 5809,
- Zo_GPToggle = 5823,
- Zo_GPUnlockDoor = 5832,
- Zo_GenericDeviceClass = 5845,
- Zo_GenericDeviceType = 5864,
- Zo_GetAllGroups = 5882,
- Zo_GetGroup = 5895,
- Zo_GetSceneMembership = 5904,
- Zo_GlassBreak = 5923,
- Zo_GroupNameSupport = 5934,
- Zo_HVACSystemTypeConfiguration = 5951,
- Zo_HWVersion = 5979,
- Zo_HarmonicCurrentMultiplier = 5989,
- Zo_HighTempDwellTripPoint = 6015,
- Zo_HighTempThreshold = 6038,
- Zo_Hue = 6056,
- Zo_HueMove = 6060,
- Zo_HueSat = 6068,
- Zo_HueStep = 6075,
- Zo_HueStepDown = 6083,
- Zo_HueStepUp = 6095,
- Zo_Humidity = 6105,
- Zo_HumidityMaxMeasuredValue = 6114,
- Zo_HumidityMinMeasuredValue = 6139,
- Zo_HumidityTolerance = 6164,
- Zo_IASCIEAddress = 6182,
- Zo_Identify = 6196,
- Zo_IdentifyQuery = 6205,
- Zo_IdentifyTime = 6219,
- Zo_Illuminance = 6232,
- Zo_IlluminanceLevelStatus = 6244,
- Zo_IlluminanceLightSensorType = 6267,
- Zo_IlluminanceMaxMeasuredValue = 6294,
- Zo_IlluminanceMinMeasuredValue = 6322,
- Zo_IlluminanceTargetLevel = 6350,
- Zo_IlluminanceTolerance = 6373,
- Zo_InstalledClosedLimitLift = 6394,
- Zo_InstalledClosedLimitTilt = 6419,
- Zo_InstalledOpenLimitLift = 6444,
- Zo_InstalledOpenLimitTilt = 6467,
- Zo_IntermediateSetpointsLift = 6490,
- Zo_IntermediateSetpointsTilt = 6516,
- Zo_IntrinsicBallastFactor = 6542,
- Zo_LampAlarmMode = 6565,
- Zo_LampBurnHours = 6579,
- Zo_LampBurnHoursTripPoint = 6593,
- Zo_LampManufacturer = 6616,
- Zo_LampRatedHours = 6633,
- Zo_LampType = 6648,
- Zo_LastConfiguredBy = 6657,
- Zo_LastMessageLQI = 6674,
- Zo_LastMessageRSSI = 6689,
- Zo_LastSetTime = 6705,
- Zo_LegrandHeatingMode = 6717,
- Zo_LegrandMode = 6736,
- Zo_LegrandOpt1 = 6748,
- Zo_LegrandOpt2 = 6760,
- Zo_LegrandOpt3 = 6772,
- Zo_LidlPower = 6784,
- Zo_LineCurrent = 6794,
- Zo_LineCurrentPhB = 6806,
- Zo_LineCurrentPhC = 6821,
- Zo_LinkKey = 6836,
- Zo_LocalTemperature = 6844,
- Zo_LocalTemperatureCalibration = 6861,
- Zo_LocalTime = 6889,
- Zo_LocationAge = 6899,
- Zo_LocationDescription = 6911,
- Zo_LocationMethod = 6931,
- Zo_LocationPower = 6946,
- Zo_LocationType = 6960,
- Zo_LockAlarmMask = 6973,
- Zo_LockDefaultConfigurationRegister = 6987,
- Zo_LockEnableInsideStatusLED = 7020,
- Zo_LockEnableLocalProgramming = 7046,
- Zo_LockEnableLogging = 7073,
- Zo_LockEnableOneTouchLocking = 7091,
- Zo_LockEnablePrivacyModeButton = 7117,
- Zo_LockKeypadOperationEventMask = 7145,
- Zo_LockKeypadProgrammingEventMask = 7174,
- Zo_LockLEDSettings = 7205,
- Zo_LockLanguage = 7221,
- Zo_LockManualOperationEventMask = 7234,
- Zo_LockOperatingMode = 7263,
- Zo_LockRFIDOperationEventMask = 7281,
- Zo_LockRFIDProgrammingEventMask = 7308,
- Zo_LockRFOperationEventMask = 7337,
- Zo_LockRFProgrammingEventMask = 7362,
- Zo_LockSoundVolume = 7389,
- Zo_LockState = 7405,
- Zo_LockSupportedOperatingModes = 7415,
- Zo_LockType = 7443,
- Zo_LongPollInterval = 7452,
- Zo_LongPollIntervalMin = 7469,
- Zo_LowTempDwellTripPoint = 7489,
- Zo_LowTempThreshold = 7511,
- Zo_MainsAlarmMask = 7528,
- Zo_MainsFrequency = 7543,
- Zo_MainsVoltage = 7558,
- Zo_MainsVoltageDwellTripPoint = 7571,
- Zo_MainsVoltageMaxThreshold = 7598,
- Zo_MainsVoltageMinThreshold = 7623,
- Zo_Manufacturer = 7648,
- Zo_MaxCoolSetpointLimit = 7661,
- Zo_MaxHeatSetpointLimit = 7682,
- Zo_MaxPINCodeLength = 7703,
- Zo_MaxProxyTableEntries = 7720,
- Zo_MaxRFIDCodeLength = 7741,
- Zo_MaxSearchCounter = 7759,
- Zo_MaxSinkTableEntries = 7776,
- Zo_MaxTempExperienced = 7796,
- Zo_Measured11thHarmonicCurrent = 7815,
- Zo_Measured1stHarmonicCurrent = 7843,
- Zo_Measured3rdHarmonicCurrent = 7870,
- Zo_Measured5thHarmonicCurrent = 7897,
- Zo_Measured7thHarmonicCurrent = 7924,
- Zo_Measured9thHarmonicCurrent = 7951,
- Zo_MeasuredPhase11thHarmonicCurrent = 7978,
- Zo_MeasuredPhase1stHarmonicCurrent = 8011,
- Zo_MeasuredPhase3rdHarmonicCurrent = 8043,
- Zo_MeasuredPhase5thHarmonicCurrent = 8075,
- Zo_MeasuredPhase7thHarmonicCurrent = 8107,
- Zo_MeasuredPhase9thHarmonicCurrent = 8139,
- Zo_MeterTypeID = 8171,
- Zo_MinCoolSetpointLimit = 8183,
- Zo_MinHeatSetpointLimit = 8204,
- Zo_MinPINCodeLength = 8225,
- Zo_MinRFIDCodeLength = 8242,
- Zo_MinSetpointDeadBand = 8260,
- Zo_MinTempExperienced = 8280,
- Zo_Mode = 8299,
- Zo_Model = 8304,
- Zo_ModelId = 8310,
- Zo_MotorStepSize = 8318,
- Zo_Movement = 8332,
- Zo_MullerLightMode = 8341,
- Zo_MultiApplicationType = 8357,
- Zo_MultiDescription = 8378,
- Zo_MultiInApplicationType = 8395,
- Zo_MultiInDescription = 8418,
- Zo_MultiInNumberOfStates = 8437,
- Zo_MultiInOutOfService = 8459,
- Zo_MultiInReliability = 8479,
- Zo_MultiInStatusFlags = 8498,
- Zo_MultiInValue = 8517,
- Zo_MultiNumberOfStates = 8530,
- Zo_MultiOutApplicationType = 8550,
- Zo_MultiOutDescription = 8574,
- Zo_MultiOutNumberOfStates = 8594,
- Zo_MultiOutOfService = 8617,
- Zo_MultiOutOutOfService = 8635,
- Zo_MultiOutReliability = 8656,
- Zo_MultiOutRelinquishDefault = 8676,
- Zo_MultiOutStatusFlags = 8702,
- Zo_MultiOutValue = 8722,
- Zo_MultiReliability = 8736,
- Zo_MultiRelinquishDefault = 8753,
- Zo_MultiStatusFlags = 8776,
- Zo_MultiValue = 8793,
- Zo_MultipleScheduling = 8804,
- Zo_NeutralCurrent = 8823,
- Zo_NotificationRetryNumber = 8838,
- Zo_NotificationRetryTimer = 8862,
- Zo_NumberOfDevices = 8885,
- Zo_NumberOfHolidaySchedulesSupported = 8901,
- Zo_NumberOfLogRecordsSupported = 8935,
- Zo_NumberOfPINUsersSupported = 8963,
- Zo_NumberOfPrimaries = 8989,
- Zo_NumberOfRFIDUsersSupported = 9007,
- Zo_NumberOfResets = 9034,
- Zo_NumberOfTotalUsersSupported = 9049,
- Zo_NumberOfWeekDaySchedulesSupportedPerUser = 9077,
- Zo_NumberOfYearDaySchedulesSupportedPerUser = 9118,
- Zo_NumberOfZoneSensitivityLevelsSupported = 9159,
- Zo_NumberRSSIMeasurements = 9198,
- Zo_NumberofActuationsLift = 9221,
- Zo_NumberofActuationsTilt = 9244,
- Zo_Occupancy = 9267,
- Zo_OccupancySensorType = 9277,
- Zo_OccupiedCoolingSetpoint = 9297,
- Zo_OccupiedHeatingSetpoint = 9321,
- Zo_OffTransitionTime = 9345,
- Zo_OffWaitTime = 9363,
- Zo_OnLevel = 9375,
- Zo_OnOff = 9383,
- Zo_OnOffTransitionTime = 9389,
- Zo_OnTime = 9409,
- Zo_OnTransitionTime = 9416,
- Zo_OpenPeriod = 9433,
- Zo_OppleMode = 9444,
- Zo_OutdoorTemperature = 9454,
- Zo_OverTempTotalDwell = 9473,
- Zo_PICoolingDemand = 9492,
- Zo_PIHeatingDemand = 9508,
- Zo_PIROccupiedToUnoccupiedDelay = 9524,
- Zo_PIRUnoccupiedToOccupiedDelay = 9553,
- Zo_PIRUnoccupiedToOccupiedThreshold = 9582,
- Zo_POD = 9615,
- Zo_Panic = 9619,
- Zo_PartNumber = 9625,
- Zo_PathLossExponent = 9636,
- Zo_PersistentMemoryWrites = 9653,
- Zo_PersonalAlarm = 9676,
- Zo_PhaseHarmonicCurrentMultiplier = 9690,
- Zo_PhysicalClosedLimit = 9721,
- Zo_PhysicalClosedLimitLift = 9741,
- Zo_PhysicalClosedLimitTilt = 9765,
- Zo_PhysicalEnvironment = 9789,
- Zo_Power = 9809,
- Zo_PowerDivisor = 9815,
- Zo_PowerFactor = 9828,
- Zo_PowerFactorPhB = 9840,
- Zo_PowerFactorPhC = 9855,
- Zo_PowerMultiplier = 9870,
- Zo_PowerOffEffect = 9886,
- Zo_PowerOnRecall = 9901,
- Zo_PowerOnTimer = 9915,
- Zo_PowerSource = 9928,
- Zo_PowerThreshold = 9940,
- Zo_Pressure = 9955,
- Zo_PressureMaxMeasuredValue = 9964,
- Zo_PressureMaxScaledValue = 9989,
- Zo_PressureMinMeasuredValue = 10012,
- Zo_PressureMinScaledValue = 10037,
- Zo_PressureScale = 10060,
- Zo_PressureScaledTolerance = 10074,
- Zo_PressureScaledValue = 10098,
- Zo_PressureTolerance = 10118,
- Zo_Primary1Intensity = 10136,
- Zo_Primary1X = 10154,
- Zo_Primary1Y = 10164,
- Zo_Primary2Intensity = 10174,
- Zo_Primary2X = 10192,
- Zo_Primary2Y = 10202,
- Zo_Primary3Intensity = 10212,
- Zo_Primary3X = 10230,
- Zo_Primary3Y = 10240,
- Zo_Primary4Intensity = 10250,
- Zo_Primary4X = 10268,
- Zo_Primary4Y = 10278,
- Zo_Primary5Intensity = 10288,
- Zo_Primary5X = 10306,
- Zo_Primary5Y = 10316,
- Zo_Primary6Intensity = 10326,
- Zo_Primary6X = 10344,
- Zo_Primary6Y = 10354,
- Zo_ProductCode = 10364,
- Zo_ProductRevision = 10376,
- Zo_ProductURL = 10392,
- Zo_ProxyTable = 10403,
- Zo_QualityMeasure = 10414,
- Zo_RGB = 10429,
- Zo_RHDehumidificationSetpoint = 10433,
- Zo_RMSCurrent = 10460,
- Zo_RMSCurrentMax = 10471,
- Zo_RMSCurrentMaxPhB = 10485,
- Zo_RMSCurrentMaxPhC = 10502,
- Zo_RMSCurrentMin = 10519,
- Zo_RMSCurrentMinPhB = 10533,
- Zo_RMSCurrentMinPhC = 10550,
- Zo_RMSCurrentPhB = 10567,
- Zo_RMSCurrentPhC = 10581,
- Zo_RMSExtremeOverVoltage = 10595,
- Zo_RMSExtremeOverVoltagePeriod = 10617,
- Zo_RMSExtremeOverVoltagePeriodPhB = 10645,
- Zo_RMSExtremeOverVoltagePeriodPhC = 10676,
- Zo_RMSExtremeUnderVoltage = 10707,
- Zo_RMSExtremeUnderVoltagePeriod = 10730,
- Zo_RMSExtremeUnderVoltagePeriodPhB = 10759,
- Zo_RMSExtremeUnderVoltagePeriodPhC = 10791,
- Zo_RMSVoltage = 10823,
- Zo_RMSVoltageMax = 10834,
- Zo_RMSVoltageMaxPhB = 10848,
- Zo_RMSVoltageMaxPhC = 10865,
- Zo_RMSVoltageMin = 10882,
- Zo_RMSVoltageMinPhB = 10896,
- Zo_RMSVoltageMinPhC = 10913,
- Zo_RMSVoltagePhB = 10930,
- Zo_RMSVoltagePhC = 10944,
- Zo_RMSVoltageSag = 10958,
- Zo_RMSVoltageSagPeriod = 10972,
- Zo_RMSVoltageSagPeriodPhB = 10992,
- Zo_RMSVoltageSagPeriodPhC = 11015,
- Zo_RMSVoltageSwell = 11038,
- Zo_RMSVoltageSwellPeriod = 11054,
- Zo_RMSVoltageSwellPeriodPhB = 11076,
- Zo_RMSVoltageSwellPeriodPhC = 11101,
- Zo_ReactiveCurrent = 11126,
- Zo_ReactiveCurrentPhB = 11142,
- Zo_ReactiveCurrentPhC = 11161,
- Zo_ReactivePower = 11180,
- Zo_ReactivePowerPhB = 11194,
- Zo_ReactivePowerPhC = 11211,
- Zo_RecallScene = 11228,
- Zo_RelativeHumidity = 11240,
- Zo_RelativeHumidityDisplay = 11257,
- Zo_RelativeHumidityMode = 11281,
- Zo_RemainingTime = 11302,
- Zo_RemoteSensing = 11316,
- Zo_RemoveAllGroups = 11330,
- Zo_RemoveAllScenes = 11346,
- Zo_RemoveGroup = 11362,
- Zo_RemoveScene = 11374,
- Zo_ReportingPeriod = 11386,
- Zo_ResetAlarm = 11402,
- Zo_ResetAllAlarms = 11413,
- Zo_SWBuildID = 11428,
- Zo_Sat = 11438,
- Zo_SatMove = 11442,
- Zo_SatStep = 11450,
- Zo_SceneCount = 11458,
- Zo_SceneNameSupport = 11469,
- Zo_SceneValid = 11486,
- Zo_ScheduleMode = 11497,
- Zo_SeaPressure = 11510,
- Zo_SecurityLevel = 11522,
- Zo_ServerActiveFunctionality = 11536,
- Zo_ServerFunctionality = 11562,
- Zo_SharedSecurityKey = 11582,
- Zo_SharedSecurityKeyType = 11600,
- Zo_ShortPollInterval = 11622,
- Zo_Shutter = 11640,
- Zo_ShutterClose = 11648,
- Zo_ShutterLift = 11661,
- Zo_ShutterOpen = 11673,
- Zo_ShutterStop = 11685,
- Zo_ShutterTilt = 11697,
- Zo_SinkTable = 11709,
- Zo_SoftwareRevision = 11719,
- Zo_StackVersion = 11736,
- Zo_StandardTime = 11749,
- Zo_StartUpOnOff = 11762,
- Zo_Status = 11775,
- Zo_StoreScene = 11782,
- Zo_SwitchActions = 11793,
- Zo_SwitchType = 11807,
- Zo_SystemMode = 11818,
- Zo_TRVBoost = 11829,
- Zo_TRVChildProtection = 11838,
- Zo_TRVMirrorDisplay = 11857,
- Zo_TRVMode = 11874,
- Zo_TRVWindowOpen = 11882,
- Zo_TempTarget = 11896,
- Zo_Temperature = 11907,
- Zo_TemperatureDisplayMode = 11919,
- Zo_TemperatureMaxMeasuredValue = 11942,
- Zo_TemperatureMinMeasuredValue = 11970,
- Zo_TemperatureTolerance = 11998,
- Zo_TerncyDuration = 12019,
- Zo_TerncyRotate = 12034,
- Zo_ThSetpoint = 12047,
- Zo_ThermostatAlarmMask = 12058,
- Zo_ThermostatKeypadLockout = 12078,
- Zo_ThermostatOccupancy = 12102,
- Zo_ThermostatRunningMode = 12122,
- Zo_ThermostatScheduleProgrammingVisibility = 12144,
- Zo_Time = 12184,
- Zo_TimeEpoch = 12189,
- Zo_TimeStatus = 12199,
- Zo_TimeZone = 12210,
- Zo_TotalActivePower = 12219,
- Zo_TotalApparentPower = 12236,
- Zo_TotalProfileNum = 12255,
- Zo_TotalReactivePower = 12271,
- Zo_TuyaCalibration = 12290,
- Zo_TuyaCalibrationTime = 12306,
- Zo_TuyaMCUVersion = 12326,
- Zo_TuyaMotorReversal = 12341,
- Zo_TuyaMovingState = 12359,
- Zo_TuyaQuery = 12375,
- Zo_UnoccupiedCoolingSetpoint = 12385,
- Zo_UnoccupiedHeatingSetpoint = 12411,
- Zo_UtilityName = 12437,
- Zo_ValidUntilTime = 12449,
- Zo_ValvePosition = 12464,
- Zo_VelocityLift = 12478,
- Zo_ViewGroup = 12491,
- Zo_ViewScene = 12501,
- Zo_Water = 12511,
- Zo_WhitePointX = 12517,
- Zo_WhitePointY = 12529,
- Zo_WindowCoveringType = 12541,
- Zo_X = 12560,
- Zo_Y = 12562,
- Zo_ZCLVersion = 12564,
- Zo_ZoneID = 12575,
- Zo_ZoneState = 12582,
- Zo_ZoneStatus = 12592,
- Zo_ZoneStatusChange = 12603,
- Zo_ZoneType = 12620,
- Zo__ = 12629,
- Zo_xx = 12631,
- Zo_xx000A00 = 12634,
- Zo_xx0A = 12643,
- Zo_xx0A00 = 12648,
- Zo_xx19 = 12655,
- Zo_xx190A = 12660,
- Zo_xx190A00 = 12667,
- Zo_xxxx = 12676,
- Zo_xxxx00 = 12681,
- Zo_xxxx0A00 = 12688,
- Zo_xxxxyy = 12697,
- Zo_xxxxyyyy = 12704,
- Zo_xxxxyyyy0A00 = 12713,
- Zo_xxxxyyzz = 12726,
- Zo_xxyy = 12735,
- Zo_xxyy0A00 = 12740,
- Zo_xxyyyy = 12749,
- Zo_xxyyyy000000000000 = 12756,
- Zo_xxyyyy0A0000000000 = 12775,
- Zo_xxyyyyzz = 12794,
- Zo_xxyyyyzzzz = 12803,
- Zo_xxyyzzzz = 12814,
+ Zo_ControlTemperature = 3926,
+ Zo_Coordinate1 = 3945,
+ Zo_Coordinate2 = 3957,
+ Zo_Coordinate3 = 3969,
+ Zo_CurrentBlock = 3981,
+ Zo_CurrentBlockPeriodConsumptionDelivered = 3994,
+ Zo_CurrentGroup = 4033,
+ Zo_CurrentInletEnergyCarrierDemand = 4046,
+ Zo_CurrentInletEnergyCarrierSummation = 4078,
+ Zo_CurrentMaxDemandDelivered = 4113,
+ Zo_CurrentMaxDemandDeliveredTime = 4139,
+ Zo_CurrentMaxDemandReceived = 4169,
+ Zo_CurrentMaxDemandReceivedTime = 4194,
+ Zo_CurrentOutletEnergyCarrierDemand = 4223,
+ Zo_CurrentOutletEnergyCarrierSummation = 4256,
+ Zo_CurrentPositionLift = 4292,
+ Zo_CurrentPositionLiftPercentage = 4312,
+ Zo_CurrentPositionTilt = 4342,
+ Zo_CurrentPositionTiltPercentage = 4362,
+ Zo_CurrentScene = 4392,
+ Zo_CurrentSummationDelivered = 4405,
+ Zo_CurrentSummationReceived = 4431,
+ Zo_CurrentTemperature = 4456,
+ Zo_CurrentTemperatureSetPoint = 4475,
+ Zo_CurrentZoneSensitivityLevel = 4502,
+ Zo_CustomerName = 4530,
+ Zo_DCCurrent = 4543,
+ Zo_DCCurrentDivisor = 4553,
+ Zo_DCCurrentMax = 4570,
+ Zo_DCCurrentMin = 4583,
+ Zo_DCCurrentMultiplier = 4596,
+ Zo_DCCurrentOverload = 4616,
+ Zo_DCOverloadAlarmsMask = 4634,
+ Zo_DCPower = 4655,
+ Zo_DCPowerDivisor = 4663,
+ Zo_DCPowerMax = 4678,
+ Zo_DCPowerMin = 4689,
+ Zo_DCPowerMultiplier = 4700,
+ Zo_DCVoltage = 4718,
+ Zo_DCVoltageDivisor = 4728,
+ Zo_DCVoltageMax = 4745,
+ Zo_DCVoltageMin = 4758,
+ Zo_DCVoltageMultiplier = 4771,
+ Zo_DCVoltageOverload = 4791,
+ Zo_DFTSummation = 4809,
+ Zo_DailyConsumptionTarget = 4822,
+ Zo_DailyFreezeTime = 4845,
+ Zo_DataQualityID = 4861,
+ Zo_DateCode = 4875,
+ Zo_DecelerationTimeLift = 4884,
+ Zo_DefaultMoveRate = 4905,
+ Zo_DefaultUpdatePeriod = 4921,
+ Zo_DehumidificationCooling = 4941,
+ Zo_DehumidificationHysteresis = 4965,
+ Zo_DehumidificationLockout = 4992,
+ Zo_DehumidificationMaxCool = 5016,
+ Zo_DeviceEnabled = 5040,
+ Zo_DeviceTempAlarmMask = 5054,
+ Zo_Dimmer = 5074,
+ Zo_DimmerCurrentFrequency = 5081,
+ Zo_DimmerDown = 5104,
+ Zo_DimmerMaxFrequency = 5115,
+ Zo_DimmerMaxLevel = 5134,
+ Zo_DimmerMinFrequency = 5149,
+ Zo_DimmerMinLevel = 5168,
+ Zo_DimmerMove = 5183,
+ Zo_DimmerOptions = 5194,
+ Zo_DimmerRemainingTime = 5208,
+ Zo_DimmerStartUpLevel = 5228,
+ Zo_DimmerStep = 5247,
+ Zo_DimmerStepDown = 5258,
+ Zo_DimmerStepUp = 5273,
+ Zo_DimmerStop = 5286,
+ Zo_DimmerUp = 5297,
+ Zo_DisableLocalConfig = 5306,
+ Zo_DoorClosedEvents = 5325,
+ Zo_DoorOpenEvents = 5342,
+ Zo_DoorState = 5357,
+ Zo_DriftCompensation = 5367,
+ Zo_DstEnd = 5385,
+ Zo_DstShift = 5392,
+ Zo_DstStart = 5401,
+ Zo_ElectricalMeasurementType = 5410,
+ Zo_EnergyFormatting = 5436,
+ Zo_EnergyRemote = 5453,
+ Zo_EnhancedColorMode = 5466,
+ Zo_EnhancedCurrentHue = 5484,
+ Zo_EurotronicErrors = 5503,
+ Zo_EurotronicHostFlags = 5520,
+ Zo_FanMode = 5540,
+ Zo_FanModeSequence = 5548,
+ Zo_FastPollTimeout = 5564,
+ Zo_FastPollTimeoutMax = 5580,
+ Zo_FastPollUpdatePeriod = 5599,
+ Zo_Fire = 5620,
+ Zo_FlowMaxMeasuredValue = 5625,
+ Zo_FlowMinMeasuredValue = 5646,
+ Zo_FlowRate = 5667,
+ Zo_FlowRestriction = 5676,
+ Zo_FlowTolerance = 5692,
+ Zo_GPHueStop = 5706,
+ Zo_GPIdentify = 5716,
+ Zo_GPLevelStop = 5727,
+ Zo_GPLockDoor = 5739,
+ Zo_GPMoveColor = 5750,
+ Zo_GPMoveDown = 5762,
+ Zo_GPMoveDownOnOff = 5773,
+ Zo_GPMoveHueDown = 5789,
+ Zo_GPMoveHueUp = 5803,
+ Zo_GPMoveSatDown = 5815,
+ Zo_GPMoveSatUp = 5829,
+ Zo_GPMoveUp = 5841,
+ Zo_GPMoveUpOnOff = 5850,
+ Zo_GPOff = 5864,
+ Zo_GPOn = 5870,
+ Zo_GPPress1of1 = 5875,
+ Zo_GPPress1of2 = 5887,
+ Zo_GPPress2of2 = 5899,
+ Zo_GPRelease = 5911,
+ Zo_GPRelease1of1 = 5921,
+ Zo_GPRelease1of2 = 5935,
+ Zo_GPRelease2of2 = 5949,
+ Zo_GPSatStop = 5963,
+ Zo_GPScene0 = 5973,
+ Zo_GPScene1 = 5982,
+ Zo_GPScene10 = 5991,
+ Zo_GPScene11 = 6001,
+ Zo_GPScene12 = 6011,
+ Zo_GPScene13 = 6021,
+ Zo_GPScene14 = 6031,
+ Zo_GPScene15 = 6041,
+ Zo_GPScene2 = 6051,
+ Zo_GPScene3 = 6060,
+ Zo_GPScene4 = 6069,
+ Zo_GPScene5 = 6078,
+ Zo_GPScene6 = 6087,
+ Zo_GPScene7 = 6096,
+ Zo_GPScene8 = 6105,
+ Zo_GPScene9 = 6114,
+ Zo_GPShortPress1of1 = 6123,
+ Zo_GPShortPress1of2 = 6140,
+ Zo_GPShortPress2of2 = 6157,
+ Zo_GPStepColor = 6174,
+ Zo_GPStepDown = 6186,
+ Zo_GPStepDownOnOff = 6197,
+ Zo_GPStepHueDown = 6213,
+ Zo_GPStepHueUp = 6227,
+ Zo_GPStepSatDown = 6239,
+ Zo_GPStepSatUp = 6253,
+ Zo_GPStepUp = 6265,
+ Zo_GPStepUpOnOff = 6274,
+ Zo_GPToggle = 6288,
+ Zo_GPUnlockDoor = 6297,
+ Zo_GenericDeviceClass = 6310,
+ Zo_GenericDeviceType = 6329,
+ Zo_GetAllGroups = 6347,
+ Zo_GetGroup = 6360,
+ Zo_GetSceneMembership = 6369,
+ Zo_GlassBreak = 6388,
+ Zo_GroupNameSupport = 6399,
+ Zo_HVACSystemTypeConfiguration = 6416,
+ Zo_HWVersion = 6444,
+ Zo_HarmonicCurrentMultiplier = 6454,
+ Zo_HighTempDwellTripPoint = 6480,
+ Zo_HighTempThreshold = 6503,
+ Zo_Hue = 6521,
+ Zo_HueMove = 6525,
+ Zo_HueSat = 6533,
+ Zo_HueStep = 6540,
+ Zo_HueStepDown = 6548,
+ Zo_HueStepUp = 6560,
+ Zo_Humidity = 6570,
+ Zo_HumidityMaxMeasuredValue = 6579,
+ Zo_HumidityMinMeasuredValue = 6604,
+ Zo_HumidityTolerance = 6629,
+ Zo_IASCIEAddress = 6647,
+ Zo_Identify = 6661,
+ Zo_IdentifyQuery = 6670,
+ Zo_IdentifyTime = 6684,
+ Zo_Illuminance = 6697,
+ Zo_IlluminanceLevelStatus = 6709,
+ Zo_IlluminanceLightSensorType = 6732,
+ Zo_IlluminanceMaxMeasuredValue = 6759,
+ Zo_IlluminanceMinMeasuredValue = 6787,
+ Zo_IlluminanceTargetLevel = 6815,
+ Zo_IlluminanceTolerance = 6838,
+ Zo_InletTemperature = 6859,
+ Zo_InstalledClosedLimitLift = 6876,
+ Zo_InstalledClosedLimitTilt = 6901,
+ Zo_InstalledOpenLimitLift = 6926,
+ Zo_InstalledOpenLimitTilt = 6949,
+ Zo_IntermediateSetpointsLift = 6972,
+ Zo_IntermediateSetpointsTilt = 6998,
+ Zo_IntervalReadReportingPeriod = 7024,
+ Zo_IntrinsicBallastFactor = 7052,
+ Zo_LampAlarmMode = 7075,
+ Zo_LampBurnHours = 7089,
+ Zo_LampBurnHoursTripPoint = 7103,
+ Zo_LampManufacturer = 7126,
+ Zo_LampRatedHours = 7143,
+ Zo_LampType = 7158,
+ Zo_LastConfiguredBy = 7167,
+ Zo_LastMessageLQI = 7184,
+ Zo_LastMessageRSSI = 7199,
+ Zo_LastSetTime = 7215,
+ Zo_LegrandHeatingMode = 7227,
+ Zo_LegrandMode = 7246,
+ Zo_LegrandOpt1 = 7258,
+ Zo_LegrandOpt2 = 7270,
+ Zo_LegrandOpt3 = 7282,
+ Zo_LidlPower = 7294,
+ Zo_LineCurrent = 7304,
+ Zo_LineCurrentPhB = 7316,
+ Zo_LineCurrentPhC = 7331,
+ Zo_LinkKey = 7346,
+ Zo_LocalTemperature = 7354,
+ Zo_LocalTemperatureCalibration = 7371,
+ Zo_LocalTime = 7399,
+ Zo_LocationAge = 7409,
+ Zo_LocationDescription = 7421,
+ Zo_LocationMethod = 7441,
+ Zo_LocationPower = 7456,
+ Zo_LocationType = 7470,
+ Zo_LockAlarmMask = 7483,
+ Zo_LockDefaultConfigurationRegister = 7497,
+ Zo_LockEnableInsideStatusLED = 7530,
+ Zo_LockEnableLocalProgramming = 7556,
+ Zo_LockEnableLogging = 7583,
+ Zo_LockEnableOneTouchLocking = 7601,
+ Zo_LockEnablePrivacyModeButton = 7627,
+ Zo_LockKeypadOperationEventMask = 7655,
+ Zo_LockKeypadProgrammingEventMask = 7684,
+ Zo_LockLEDSettings = 7715,
+ Zo_LockLanguage = 7731,
+ Zo_LockManualOperationEventMask = 7744,
+ Zo_LockOperatingMode = 7773,
+ Zo_LockRFIDOperationEventMask = 7791,
+ Zo_LockRFIDProgrammingEventMask = 7818,
+ Zo_LockRFOperationEventMask = 7847,
+ Zo_LockRFProgrammingEventMask = 7872,
+ Zo_LockSoundVolume = 7899,
+ Zo_LockState = 7915,
+ Zo_LockSupportedOperatingModes = 7925,
+ Zo_LockType = 7953,
+ Zo_LongPollInterval = 7962,
+ Zo_LongPollIntervalMin = 7979,
+ Zo_LowTempDwellTripPoint = 7999,
+ Zo_LowTempThreshold = 8021,
+ Zo_MainsAlarmMask = 8038,
+ Zo_MainsFrequency = 8053,
+ Zo_MainsVoltage = 8068,
+ Zo_MainsVoltageDwellTripPoint = 8081,
+ Zo_MainsVoltageMaxThreshold = 8108,
+ Zo_MainsVoltageMinThreshold = 8133,
+ Zo_Manufacturer = 8158,
+ Zo_MaxCoolSetpointLimit = 8171,
+ Zo_MaxHeatSetpointLimit = 8192,
+ Zo_MaxPINCodeLength = 8213,
+ Zo_MaxProxyTableEntries = 8230,
+ Zo_MaxRFIDCodeLength = 8251,
+ Zo_MaxSearchCounter = 8269,
+ Zo_MaxSinkTableEntries = 8286,
+ Zo_MaxTempExperienced = 8306,
+ Zo_Measured11thHarmonicCurrent = 8325,
+ Zo_Measured1stHarmonicCurrent = 8353,
+ Zo_Measured3rdHarmonicCurrent = 8380,
+ Zo_Measured5thHarmonicCurrent = 8407,
+ Zo_Measured7thHarmonicCurrent = 8434,
+ Zo_Measured9thHarmonicCurrent = 8461,
+ Zo_MeasuredPhase11thHarmonicCurrent = 8488,
+ Zo_MeasuredPhase1stHarmonicCurrent = 8521,
+ Zo_MeasuredPhase3rdHarmonicCurrent = 8553,
+ Zo_MeasuredPhase5thHarmonicCurrent = 8585,
+ Zo_MeasuredPhase7thHarmonicCurrent = 8617,
+ Zo_MeasuredPhase9thHarmonicCurrent = 8649,
+ Zo_MeterTypeID = 8681,
+ Zo_MinCoolSetpointLimit = 8693,
+ Zo_MinHeatSetpointLimit = 8714,
+ Zo_MinPINCodeLength = 8735,
+ Zo_MinRFIDCodeLength = 8752,
+ Zo_MinSetpointDeadBand = 8770,
+ Zo_MinTempExperienced = 8790,
+ Zo_Mode = 8809,
+ Zo_Model = 8814,
+ Zo_ModelId = 8820,
+ Zo_MotorStepSize = 8828,
+ Zo_Movement = 8842,
+ Zo_MullerLightMode = 8851,
+ Zo_MultiApplicationType = 8867,
+ Zo_MultiDescription = 8888,
+ Zo_MultiInApplicationType = 8905,
+ Zo_MultiInDescription = 8928,
+ Zo_MultiInNumberOfStates = 8947,
+ Zo_MultiInOutOfService = 8969,
+ Zo_MultiInReliability = 8989,
+ Zo_MultiInStatusFlags = 9008,
+ Zo_MultiInValue = 9027,
+ Zo_MultiNumberOfStates = 9040,
+ Zo_MultiOutApplicationType = 9060,
+ Zo_MultiOutDescription = 9084,
+ Zo_MultiOutNumberOfStates = 9104,
+ Zo_MultiOutOfService = 9127,
+ Zo_MultiOutOutOfService = 9145,
+ Zo_MultiOutReliability = 9166,
+ Zo_MultiOutRelinquishDefault = 9186,
+ Zo_MultiOutStatusFlags = 9212,
+ Zo_MultiOutValue = 9232,
+ Zo_MultiReliability = 9246,
+ Zo_MultiRelinquishDefault = 9263,
+ Zo_MultiStatusFlags = 9286,
+ Zo_MultiValue = 9303,
+ Zo_MultipleScheduling = 9314,
+ Zo_NeutralCurrent = 9333,
+ Zo_NotificationRetryNumber = 9348,
+ Zo_NotificationRetryTimer = 9372,
+ Zo_NumberOfDevices = 9395,
+ Zo_NumberOfHolidaySchedulesSupported = 9411,
+ Zo_NumberOfLogRecordsSupported = 9445,
+ Zo_NumberOfPINUsersSupported = 9473,
+ Zo_NumberOfPrimaries = 9499,
+ Zo_NumberOfRFIDUsersSupported = 9517,
+ Zo_NumberOfResets = 9544,
+ Zo_NumberOfTotalUsersSupported = 9559,
+ Zo_NumberOfWeekDaySchedulesSupportedPerUser = 9587,
+ Zo_NumberOfYearDaySchedulesSupportedPerUser = 9628,
+ Zo_NumberOfZoneSensitivityLevelsSupported = 9669,
+ Zo_NumberRSSIMeasurements = 9708,
+ Zo_NumberofActuationsLift = 9731,
+ Zo_NumberofActuationsTilt = 9754,
+ Zo_Occupancy = 9777,
+ Zo_OccupancySensorType = 9787,
+ Zo_OccupiedCoolingSetpoint = 9807,
+ Zo_OccupiedHeatingSetpoint = 9831,
+ Zo_OffTransitionTime = 9855,
+ Zo_OffWaitTime = 9873,
+ Zo_OnLevel = 9885,
+ Zo_OnOff = 9893,
+ Zo_OnOffTransitionTime = 9899,
+ Zo_OnTime = 9919,
+ Zo_OnTransitionTime = 9926,
+ Zo_OpenPeriod = 9943,
+ Zo_OppleMode = 9954,
+ Zo_OutdoorTemperature = 9964,
+ Zo_OutletTemperature = 9983,
+ Zo_OverTempTotalDwell = 10001,
+ Zo_PICoolingDemand = 10020,
+ Zo_PIHeatingDemand = 10036,
+ Zo_PIROccupiedToUnoccupiedDelay = 10052,
+ Zo_PIRUnoccupiedToOccupiedDelay = 10081,
+ Zo_PIRUnoccupiedToOccupiedThreshold = 10110,
+ Zo_POD = 10143,
+ Zo_Panic = 10147,
+ Zo_PartNumber = 10153,
+ Zo_PathLossExponent = 10164,
+ Zo_PersistentMemoryWrites = 10181,
+ Zo_PersonalAlarm = 10204,
+ Zo_PhaseHarmonicCurrentMultiplier = 10218,
+ Zo_PhysicalClosedLimit = 10249,
+ Zo_PhysicalClosedLimitLift = 10269,
+ Zo_PhysicalClosedLimitTilt = 10293,
+ Zo_PhysicalEnvironment = 10317,
+ Zo_Power = 10337,
+ Zo_PowerDivisor = 10343,
+ Zo_PowerFactor = 10356,
+ Zo_PowerFactorPhB = 10368,
+ Zo_PowerFactorPhC = 10383,
+ Zo_PowerMultiplier = 10398,
+ Zo_PowerOffEffect = 10414,
+ Zo_PowerOnRecall = 10429,
+ Zo_PowerOnTimer = 10443,
+ Zo_PowerSource = 10456,
+ Zo_PowerThreshold = 10468,
+ Zo_PresetReadingTime = 10483,
+ Zo_Pressure = 10501,
+ Zo_PressureMaxMeasuredValue = 10510,
+ Zo_PressureMaxScaledValue = 10535,
+ Zo_PressureMinMeasuredValue = 10558,
+ Zo_PressureMinScaledValue = 10583,
+ Zo_PressureScale = 10606,
+ Zo_PressureScaledTolerance = 10620,
+ Zo_PressureScaledValue = 10644,
+ Zo_PressureTolerance = 10664,
+ Zo_PreviousBlockPeriodConsumptionDelivered = 10682,
+ Zo_Primary1Intensity = 10722,
+ Zo_Primary1X = 10740,
+ Zo_Primary1Y = 10750,
+ Zo_Primary2Intensity = 10760,
+ Zo_Primary2X = 10778,
+ Zo_Primary2Y = 10788,
+ Zo_Primary3Intensity = 10798,
+ Zo_Primary3X = 10816,
+ Zo_Primary3Y = 10826,
+ Zo_Primary4Intensity = 10836,
+ Zo_Primary4X = 10854,
+ Zo_Primary4Y = 10864,
+ Zo_Primary5Intensity = 10874,
+ Zo_Primary5X = 10892,
+ Zo_Primary5Y = 10902,
+ Zo_Primary6Intensity = 10912,
+ Zo_Primary6X = 10930,
+ Zo_Primary6Y = 10940,
+ Zo_ProductCode = 10950,
+ Zo_ProductRevision = 10962,
+ Zo_ProductURL = 10978,
+ Zo_ProfileIntervalPeriod = 10989,
+ Zo_ProxyTable = 11011,
+ Zo_QualityMeasure = 11022,
+ Zo_RGB = 11037,
+ Zo_RHDehumidificationSetpoint = 11041,
+ Zo_RMSCurrent = 11068,
+ Zo_RMSCurrentMax = 11079,
+ Zo_RMSCurrentMaxPhB = 11093,
+ Zo_RMSCurrentMaxPhC = 11110,
+ Zo_RMSCurrentMin = 11127,
+ Zo_RMSCurrentMinPhB = 11141,
+ Zo_RMSCurrentMinPhC = 11158,
+ Zo_RMSCurrentPhB = 11175,
+ Zo_RMSCurrentPhC = 11189,
+ Zo_RMSExtremeOverVoltage = 11203,
+ Zo_RMSExtremeOverVoltagePeriod = 11225,
+ Zo_RMSExtremeOverVoltagePeriodPhB = 11253,
+ Zo_RMSExtremeOverVoltagePeriodPhC = 11284,
+ Zo_RMSExtremeUnderVoltage = 11315,
+ Zo_RMSExtremeUnderVoltagePeriod = 11338,
+ Zo_RMSExtremeUnderVoltagePeriodPhB = 11367,
+ Zo_RMSExtremeUnderVoltagePeriodPhC = 11399,
+ Zo_RMSVoltage = 11431,
+ Zo_RMSVoltageMax = 11442,
+ Zo_RMSVoltageMaxPhB = 11456,
+ Zo_RMSVoltageMaxPhC = 11473,
+ Zo_RMSVoltageMin = 11490,
+ Zo_RMSVoltageMinPhB = 11504,
+ Zo_RMSVoltageMinPhC = 11521,
+ Zo_RMSVoltagePhB = 11538,
+ Zo_RMSVoltagePhC = 11552,
+ Zo_RMSVoltageSag = 11566,
+ Zo_RMSVoltageSagPeriod = 11580,
+ Zo_RMSVoltageSagPeriodPhB = 11600,
+ Zo_RMSVoltageSagPeriodPhC = 11623,
+ Zo_RMSVoltageSwell = 11646,
+ Zo_RMSVoltageSwellPeriod = 11662,
+ Zo_RMSVoltageSwellPeriodPhB = 11684,
+ Zo_RMSVoltageSwellPeriodPhC = 11709,
+ Zo_ReactiveCurrent = 11734,
+ Zo_ReactiveCurrentPhB = 11750,
+ Zo_ReactiveCurrentPhC = 11769,
+ Zo_ReactivePower = 11788,
+ Zo_ReactivePowerPhB = 11802,
+ Zo_ReactivePowerPhC = 11819,
+ Zo_ReadingSnapShotTime = 11836,
+ Zo_RecallScene = 11856,
+ Zo_RelativeHumidity = 11868,
+ Zo_RelativeHumidityDisplay = 11885,
+ Zo_RelativeHumidityMode = 11909,
+ Zo_RemainingTime = 11930,
+ Zo_RemoteSensing = 11944,
+ Zo_RemoveAllGroups = 11958,
+ Zo_RemoveAllScenes = 11974,
+ Zo_RemoveGroup = 11990,
+ Zo_RemoveScene = 12002,
+ Zo_ReportingPeriod = 12014,
+ Zo_ResetAlarm = 12030,
+ Zo_ResetAllAlarms = 12041,
+ Zo_SWBuildID = 12056,
+ Zo_Sat = 12066,
+ Zo_SatMove = 12070,
+ Zo_SatStep = 12078,
+ Zo_SceneCount = 12086,
+ Zo_SceneNameSupport = 12097,
+ Zo_SceneValid = 12114,
+ Zo_ScheduleMode = 12125,
+ Zo_SeaPressure = 12138,
+ Zo_SecurityLevel = 12150,
+ Zo_ServerActiveFunctionality = 12164,
+ Zo_ServerFunctionality = 12190,
+ Zo_SharedSecurityKey = 12210,
+ Zo_SharedSecurityKeyType = 12228,
+ Zo_ShortPollInterval = 12250,
+ Zo_Shutter = 12268,
+ Zo_ShutterClose = 12276,
+ Zo_ShutterLift = 12289,
+ Zo_ShutterOpen = 12301,
+ Zo_ShutterStop = 12313,
+ Zo_ShutterTilt = 12325,
+ Zo_SinkTable = 12337,
+ Zo_SoftwareRevision = 12347,
+ Zo_StackVersion = 12364,
+ Zo_StandardTime = 12377,
+ Zo_StartUpOnOff = 12390,
+ Zo_Status = 12403,
+ Zo_StoreScene = 12410,
+ Zo_SupplyStatus = 12421,
+ Zo_SwitchActions = 12434,
+ Zo_SwitchType = 12448,
+ Zo_SystemMode = 12459,
+ Zo_TRVBoost = 12470,
+ Zo_TRVChildProtection = 12479,
+ Zo_TRVMirrorDisplay = 12498,
+ Zo_TRVMode = 12515,
+ Zo_TRVWindowOpen = 12523,
+ Zo_TempTarget = 12537,
+ Zo_Temperature = 12548,
+ Zo_TemperatureDisplayMode = 12560,
+ Zo_TemperatureMaxMeasuredValue = 12583,
+ Zo_TemperatureMinMeasuredValue = 12611,
+ Zo_TemperatureTolerance = 12639,
+ Zo_TerncyDuration = 12660,
+ Zo_TerncyRotate = 12675,
+ Zo_ThSetpoint = 12688,
+ Zo_ThermostatAlarmMask = 12699,
+ Zo_ThermostatKeypadLockout = 12719,
+ Zo_ThermostatOccupancy = 12743,
+ Zo_ThermostatRunningMode = 12763,
+ Zo_ThermostatScheduleProgrammingVisibility = 12785,
+ Zo_Time = 12825,
+ Zo_TimeEpoch = 12830,
+ Zo_TimeStatus = 12840,
+ Zo_TimeZone = 12851,
+ Zo_TotalActivePower = 12860,
+ Zo_TotalApparentPower = 12877,
+ Zo_TotalProfileNum = 12896,
+ Zo_TotalReactivePower = 12912,
+ Zo_TuyaCalibration = 12931,
+ Zo_TuyaCalibrationTime = 12947,
+ Zo_TuyaMCUVersion = 12967,
+ Zo_TuyaMotorReversal = 12982,
+ Zo_TuyaMovingState = 13000,
+ Zo_TuyaQuery = 13016,
+ Zo_UnoccupiedCoolingSetpoint = 13026,
+ Zo_UnoccupiedHeatingSetpoint = 13052,
+ Zo_UtilityName = 13078,
+ Zo_ValidUntilTime = 13090,
+ Zo_ValvePosition = 13105,
+ Zo_VelocityLift = 13119,
+ Zo_ViewGroup = 13132,
+ Zo_ViewScene = 13142,
+ Zo_VolumePerReport = 13152,
+ Zo_Water = 13168,
+ Zo_WhitePointX = 13174,
+ Zo_WhitePointY = 13186,
+ Zo_WindowCoveringType = 13198,
+ Zo_X = 13217,
+ Zo_Y = 13219,
+ Zo_ZCLVersion = 13221,
+ Zo_ZoneID = 13232,
+ Zo_ZoneState = 13239,
+ Zo_ZoneStatus = 13249,
+ Zo_ZoneStatusChange = 13260,
+ Zo_ZoneType = 13277,
+ Zo__ = 13286,
+ Zo_xx = 13288,
+ Zo_xx000A00 = 13291,
+ Zo_xx0A = 13300,
+ Zo_xx0A00 = 13305,
+ Zo_xx19 = 13312,
+ Zo_xx190A = 13317,
+ Zo_xx190A00 = 13324,
+ Zo_xxxx = 13333,
+ Zo_xxxx00 = 13338,
+ Zo_xxxx0A00 = 13345,
+ Zo_xxxxyy = 13354,
+ Zo_xxxxyyyy = 13361,
+ Zo_xxxxyyyy0A00 = 13370,
+ Zo_xxxxyyzz = 13383,
+ Zo_xxyy = 13392,
+ Zo_xxyy0A00 = 13397,
+ Zo_xxyyyy = 13406,
+ Zo_xxyyyy000000000000 = 13413,
+ Zo_xxyyyy0A0000000000 = 13432,
+ Zo_xxyyyyzz = 13451,
+ Zo_xxyyyyzzzz = 13460,
+ Zo_xxyyzzzz = 13471,
};
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino
index 17be8d13f..5298fa5fb 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_1_attributes.ino
@@ -1129,7 +1129,35 @@ const Z_AttributeConverter Z_PostProcess[] PROGMEM = {
{ Zuint8, Cx0500, 0xFFF0 + ZA_GlassBreak, Z_(GlassBreak),Cm1, 0 },
// Metering (Smart Energy) cluster
- { Zuint48, Cx0702, 0x0000, Z_(EnergyTotal), Cm1, 0 },
+ { Zuint48, Cx0702, 0x0000, Z_(CurrentSummationDelivered),Cm1, 0 },
+ { Zuint48, Cx0702, 0x0001, Z_(CurrentSummationReceived),Cm1, 0 },
+ { Zuint48, Cx0702, 0x0002, Z_(CurrentMaxDemandDelivered),Cm1, 0 },
+ { Zuint48, Cx0702, 0x0003, Z_(CurrentMaxDemandReceived),Cm1, 0 },
+ { Zuint48, Cx0702, 0x0004, Z_(DFTSummation), Cm1, 0 },
+ { Zuint16, Cx0702, 0x0005, Z_(DailyFreezeTime), Cm1, 0 },
+ { Zint8, Cx0702, 0x0006, Z_(PowerFactor), Cm1, 0 },
+ { ZUTC, Cx0702, 0x0007, Z_(ReadingSnapShotTime), Cm1, 0 },
+ { ZUTC, Cx0702, 0x0008, Z_(CurrentMaxDemandDeliveredTime),Cm1, 0 },
+ { ZUTC, Cx0702, 0x0009, Z_(CurrentMaxDemandReceivedTime),Cm1, 0 },
+ { Zuint8, Cx0702, 0x000A, Z_(DefaultUpdatePeriod), Cm1, 0 },
+ { Zuint8, Cx0702, 0x000B, Z_(FastPollUpdatePeriod), Cm1, 0 },
+ { Zuint48, Cx0702, 0x000C, Z_(CurrentBlockPeriodConsumptionDelivered),Cm1, 0 },
+ { Zuint24, Cx0702, 0x000D, Z_(DailyConsumptionTarget),Cm1, 0 },
+ { Zenum8, Cx0702, 0x000E, Z_(CurrentBlock), Cm1, 0 },
+ { Zenum8, Cx0702, 0x000F, Z_(ProfileIntervalPeriod),Cm1, 0 },
+ { Zuint16, Cx0702, 0x0010, Z_(IntervalReadReportingPeriod),Cm1, 0 },
+ { Zuint16, Cx0702, 0x0011, Z_(PresetReadingTime), Cm1, 0 },
+ { Zuint16, Cx0702, 0x0012, Z_(VolumePerReport), Cm1, 0 },
+ { Zuint8, Cx0702, 0x0013, Z_(FlowRestriction), Cm1, 0 },
+ { Zenum8, Cx0702, 0x0014, Z_(SupplyStatus), Cm1, 0 },
+ { Zuint48, Cx0702, 0x0015, Z_(CurrentInletEnergyCarrierSummation),Cm1, 0 },
+ { Zuint48, Cx0702, 0x0016, Z_(CurrentOutletEnergyCarrierSummation),Cm1, 0 },
+ { Zint24, Cx0702, 0x0017, Z_(InletTemperature), Cm1, 0 },
+ { Zint24, Cx0702, 0x0018, Z_(OutletTemperature), Cm1, 0 },
+ { Zint24, Cx0702, 0x0019, Z_(ControlTemperature), Cm1, 0 },
+ { Zint24, Cx0702, 0x001A, Z_(CurrentInletEnergyCarrierDemand),Cm1, 0 },
+ { Zint24, Cx0702, 0x001B, Z_(CurrentOutletEnergyCarrierDemand),Cm1, 0 },
+ { Zuint48, Cx0702, 0x001C, Z_(PreviousBlockPeriodConsumptionDelivered),Cm1, 0 },
// Meter Identification cluster
{ Zstring, Cx0B01, 0x0000, Z_(CompanyName), Cm1, 0 },
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
index 4614011aa..658d508a3 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
@@ -717,20 +717,24 @@ void ZCLFrame::applySynonymAttributes(Z_attribute_list& attr_list) {
Z_attribute_synonym syn = Z_plugin_matchAttributeSynonym(device.modelId, device.manufacturerId,
attr.cluster, attr.attr_id);
if (syn.found()) {
- attr.setKeyId(syn.new_cluster, syn.new_attribute);
- if ((syn.multiplier != 1 && syn.multiplier != 0) || (syn.divider != 1 && syn.divider != 0) || (syn.base != 0)) {
- // we need to change the value
- float fval = attr.getFloat();
- if (syn.multiplier != 1 && syn.multiplier != 0) {
- fval = fval * syn.multiplier;
+ if (syn.new_attribute == 0xFFFF) { // if attr is 0xFFFF, remove attribute
+ attr_list.removeAttribute(&attr);
+ } else {
+ attr.setKeyId(syn.new_cluster, syn.new_attribute);
+ if ((syn.multiplier != 1 && syn.multiplier != 0) || (syn.divider != 1 && syn.divider != 0) || (syn.base != 0)) {
+ // we need to change the value
+ float fval = attr.getFloat();
+ if (syn.multiplier != 1 && syn.multiplier != 0) {
+ fval = fval * syn.multiplier;
+ }
+ if (syn.divider != 1 && syn.divider != 0) {
+ fval = fval / syn.divider;
+ }
+ if (syn.base != 0) {
+ fval = fval + syn.base;
+ }
+ attr.setFloat(fval);
}
- if (syn.divider != 1 && syn.divider != 0) {
- fval = fval / syn.divider;
- }
- if (syn.base != 0) {
- fval = fval + syn.base;
- }
- attr.setFloat(fval);
}
}
}
@@ -1189,9 +1193,6 @@ void ZCLFrame::syntheticAnalogValue(Z_attribute_list &attr_list, class Z_attribu
if (modelId.startsWith(F("lumi.sensor_cube"))) {
attr.setKeyId(0x000C, 0xFF55); // change to AqaraRotate
}
- if (modelId.startsWith(F("lumi.plug"))) {
- attr.setKeyId(0x0702, 0x0000); // change to EnergyTotal
- }
if (modelId.startsWith(F("lumi.ctrl"))) {
attr.setKeyId(0x0B04, 0x050B); // change to ActivePower
}
diff --git a/tasmota/zigbee/Aqara_plug.zb b/tasmota/zigbee/Aqara_plug.zb
new file mode 100644
index 000000000..a9c2d9720
--- /dev/null
+++ b/tasmota/zigbee/Aqara_plug.zb
@@ -0,0 +1,6 @@
+#Z2Tv1
+# Aqara Smart Plug EU
+# https://zigbee.blakadder.com/Aqara_SP-EUC01.html
+:lumi.plug.*,LUMI
+0B04/050B=0B04/FFFF # ignore the original ActivePower since it returns always zero
+000C/0055=0B04/050B
From 4f343fd7b73a823400219cce11f026820d14f5eb Mon Sep 17 00:00:00 2001
From: joba-1
Date: Mon, 14 Nov 2022 23:56:38 +0100
Subject: [PATCH 197/319] add RgxClients for ESP8266
---
.../xdrv_58_range_extender.ino | 25 +++++++++++++------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 7352861dd..ed806c158 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -95,10 +95,8 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
"|"
"NAPT"
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
-#ifdef ESP32
"|"
"Clients"
-#endif // ESP32
"|"
"Address"
"|"
@@ -111,9 +109,7 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
&CmndRgxNAPT,
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
-#ifdef ESP32
&CmndRgxClients,
-#endif // ESP32
&CmndRgxAddresses,
&CmndRgxAddresses,
};
@@ -172,17 +168,18 @@ void RgxCheckConfig(void)
}
}
-#ifdef ESP32
void CmndRgxClients(void)
{
+ Response_P(PSTR("{\"RgxClients\":{"));
+ const char *sep = "";
+
+#if defined(ESP32)
wifi_sta_list_t wifi_sta_list = {0};
tcpip_adapter_sta_list_t adapter_sta_list = {0};
esp_wifi_ap_get_sta_list(&wifi_sta_list);
tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
- Response_P(PSTR("{\"RgxClients\":{"));
- const char *sep = "";
for (int i=0; ibssid;
+ ResponseAppend_P(PSTR("%s\"%02X%02X%02X%02X%02X%02X\":{\"" D_CMND_IPADDRESS "\":\"%_I\"}"),
+ sep, m[0], m[1], m[2], m[3], m[4], m[5], station->ip.addr);
+ sep = ",";
+ station = STAILQ_NEXT(station, next);
+ }
+ wifi_softap_free_station_info();
+#endif
+
ResponseAppend_P(PSTR("}}"));
}
-#endif // ESP32
void CmndRgxState(void)
{
From e88d1682e9854a78d7bf3f90e3b333a6b0431462 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 15 Nov 2022 10:10:29 +0100
Subject: [PATCH 198/319] Add command ``SwitchMode 16``
Add command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
---
CHANGELOG.md | 3 ++-
RELEASENOTES.md | 3 +++
tasmota/include/tasmota.h | 13 +++++++++++--
tasmota/tasmota_support/support_switch.ino | 3 +++
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e152076a..7440cc613 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
+- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
### Breaking Changed
@@ -17,7 +18,7 @@ All notable changes to this project will be documented in this file.
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
- TuyaMcu rewrite by btsimonh (#17051)
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
-- Zigbee improved Aqara plug support and completed cluster 0x0702
+- Zigbee improved Aqara plug support and completed cluster 0x0702 (#17073)
- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
### Fixed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index fdc8a7b16..8bc75e96b 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -110,6 +110,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.4
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
+- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
@@ -130,12 +131,14 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Changed
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
+- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
- TuyaMcu rewrite by btsimonh [#17051](https://github.com/arendst/Tasmota/issues/17051)
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds [#17055](https://github.com/arendst/Tasmota/issues/17055)
+- Zigbee improved Aqara plug support and completed cluster 0x0702 [#17073](https://github.com/arendst/Tasmota/issues/17073)
### Fixed
- Serial bridge default serial configuration from 5N1 to 8N1 regression from v10.1.0.3
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index cc53ee79f..bde60e52f 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -322,8 +322,17 @@ enum WifiConfigOptions {WIFI_RESTART, EX_WIFI_SMARTCONFIG, WIFI_MANAGER, EX_WIFI
enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED, WIFI_TEST_FINISHED_BAD};
-enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI,
- FOLLOWMULTI, FOLLOWMULTI_INV, PUSHHOLDMULTI, PUSHHOLDMULTI_INV, PUSHON, PUSHON_INV, PUSH_IGNORE, MAX_SWITCH_OPTION};
+enum SwitchModeOptions {TOGGLE,
+ FOLLOW, FOLLOW_INV,
+ PUSHBUTTON, PUSHBUTTON_INV,
+ PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV,
+ PUSHBUTTON_TOGGLE,
+ TOGGLEMULTI,
+ FOLLOWMULTI, FOLLOWMULTI_INV,
+ PUSHHOLDMULTI, PUSHHOLDMULTI_INV,
+ PUSHON, PUSHON_INV,
+ PUSH_IGNORE, PUSH_IGNORE_INV, // 15, 16
+ MAX_SWITCH_OPTION};
enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION};
diff --git a/tasmota/tasmota_support/support_switch.ino b/tasmota/tasmota_support/support_switch.ino
index 7a3f01dae..6bf59bbcb 100644
--- a/tasmota/tasmota_support/support_switch.ino
+++ b/tasmota/tasmota_support/support_switch.ino
@@ -409,6 +409,9 @@ void SwitchHandler(uint32_t mode) {
Switch.last_state[i] = button; // Update switch state before publishing
MqttPublishSensor();
break;
+ case PUSH_IGNORE_INV:
+ MqttPublishSensor(); // Publishing before update
+ break;
}
Switch.last_state[i] = button;
}
From 5f3d504c301466eefccb2521029290ca79036657 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 15 Nov 2022 11:11:32 +0100
Subject: [PATCH 199/319] Add support for HMC5883L
Add support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/include/tasmota.h | 20 ++---
tasmota/my_user_config.h | 2 +-
tasmota/tasmota_support/support_features.ino | 4 +-
.../tasmota_xsns_sensor/xsns_101_hmc5883l.ino | 78 ++++++++++---------
tools/decode-status.py | 2 +-
7 files changed, 58 insertions(+), 50 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7440cc613..2c9543344 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
+- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 8bc75e96b..06b3968aa 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -120,6 +120,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for Plantower PMSx003T AQI models with temperature and humidity [#16971](https://github.com/arendst/Tasmota/issues/16971)
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
+- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069)
- WS2812 and Light Art-Net DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index bde60e52f..d00ee6295 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -322,16 +322,16 @@ enum WifiConfigOptions {WIFI_RESTART, EX_WIFI_SMARTCONFIG, WIFI_MANAGER, EX_WIFI
enum WifiTestOptions {WIFI_NOT_TESTING, WIFI_TESTING, WIFI_TEST_FINISHED, WIFI_TEST_FINISHED_BAD};
-enum SwitchModeOptions {TOGGLE,
- FOLLOW, FOLLOW_INV,
- PUSHBUTTON, PUSHBUTTON_INV,
- PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV,
- PUSHBUTTON_TOGGLE,
- TOGGLEMULTI,
- FOLLOWMULTI, FOLLOWMULTI_INV,
- PUSHHOLDMULTI, PUSHHOLDMULTI_INV,
- PUSHON, PUSHON_INV,
- PUSH_IGNORE, PUSH_IGNORE_INV, // 15, 16
+enum SwitchModeOptions {TOGGLE, // 0
+ FOLLOW, FOLLOW_INV, // 1, 2 - Follow switch state
+ PUSHBUTTON, PUSHBUTTON_INV, // 3, 4 - Pushbutton (default 1, 0 = toggle)
+ PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, // 5, 6 - Pushbutton with hold (default 1, 0 = toggle, Hold = hold)
+ PUSHBUTTON_TOGGLE, // 7 - = 0
+ TOGGLEMULTI, // 8 - = 0 with multi toggle
+ FOLLOWMULTI, FOLLOWMULTI_INV, // 9, 10 - Multi change follow (0 = off, 1 = on, 2x change = hold)
+ PUSHHOLDMULTI, PUSHHOLDMULTI_INV, // 11, 12 - Pushbutton with dimmer mode
+ PUSHON, PUSHON_INV, // 13, 14 - Pushon mode (1 = on, switch off using PulseTime)
+ PUSH_IGNORE, PUSH_IGNORE_INV, // 15, 16 - Send only MQTT message on switch change
MAX_SWITCH_OPTION};
enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION};
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 23415f8fd..58e6bb30b 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -691,7 +691,7 @@
// #define USE_HYT // [I2CDriver68] Enable HYTxxx temperature and humidity sensor (I2C address 0x28) (+0k5 code)
// #define USE_LUXV30B // [I2CDriver70] Enable RFRobot SEN0390 LuxV30b ambient light sensor (I2C address 0x4A) (+0k5 code)
// #define USE_QMC5883L // [I2CDriver71] Enable QMC5883L magnetic induction sensor (I2C address 0x0D) (+0k8 code)
-// #define USE_HMC5883L // [I2CDriver73] Enable HMC5883L magnetic induction sensor (I2C address 0x1E)
+// #define USE_HMC5883L // [I2CDriver73] Enable HMC5883L magnetic induction sensor (I2C address 0x1E) (+1k3 code)
// #define QMC5883L_TEMP_SHIFT 23 // sensor temperature are not calibrated (only relativ measurement) and need an absolute ground value in °C (see datasheet)
// #define USE_INA3221 // [I2CDriver72] Enable INA3221 3-channel DC voltage and current sensor (I2C address 0x40-0x44) (+3.2k code)
// #define INA3221_ADDRESS1 // allow to change the 1st address to search for INA3221 to 0x41..0x43
diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino
index f61e15e14..e337b2a90 100644
--- a/tasmota/tasmota_support/support_features.ino
+++ b/tasmota/tasmota_support/support_features.ino
@@ -852,7 +852,9 @@ void ResponseAppendFeatures(void)
#ifdef USE_DINGTIAN_RELAY
feature9 |= 0x00000100; // xdrv_90_dingtian_relay.ino
#endif
-// feature9 |= 0x00000200;
+#if defined(USE_I2C) && defined(USE_HMC5883L)
+ feature9 |= 0x00000200; // xsns_101_hmc5883l.ino
+#endif
// feature9 |= 0x00000400;
// feature9 |= 0x00000800;
diff --git a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino
index 56a311354..a800a8998 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_101_hmc5883l.ino
@@ -1,7 +1,7 @@
/*
xsns_101_hmc5883l.ino - HMC5883L 3-Axis Digital Compass sensor support for Tasmota
- (inspired by Helge Scheunemann)
- Copyright (C) 2022 Andreas Achtzehn
+
+ Copyright (C) 2022 Andreas Achtzehn (inspired by Helge Scheunemann)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,8 +27,8 @@
\*********************************************************************************************/
// Define driver ID
-#define XSNS_101 101
-#define XI2C_73 73 // See I2CDEVICES.md
+#define XSNS_101 101
+#define XI2C_73 73 // See I2CDEVICES.md
/* The default I2C address of this chip */
#define HMC5883L_ADDR 0x1E
@@ -45,8 +45,8 @@
#define HMC5883L_CONFIG_B 0x01
#define HMC5883L_MODE 0x02
#define HMC5883L_CHIP_ID_A 0x0A
-#define HMC5883L_CHIP_ID_B 0x0B
-#define HMC5883L_CHIP_ID_C 0x0C
+#define HMC5883L_CHIP_ID_B 0x0B
+#define HMC5883L_CHIP_ID_C 0x0C
/* Bit values for the STATUS register */
const uint8_t HMC5883L_STATUS_RDY = 0b00000001;
@@ -104,25 +104,26 @@ bool HMC5883L_SetConfig() {
uint8_t cfgB = (( (HMC5883L->gain ) << HMC5883L_CONFIG_B_GAIN_SHIFT ) & HMC5883L_CONFIG_B_GAIN_MASK );
- AddLog(LOG_LEVEL_INFO,"HMC5883L: CONFIG A: %#X CONFIG B: %#X MODE: %#X",cfgA, cfgB, HMC5883L->mode);
+ AddLog(LOG_LEVEL_INFO,"HMC: CONFIG A: %#X CONFIG B: %#X MODE: %#X", cfgA, cfgB, HMC5883L->mode);
- if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_A, cfgA ) == false) {
- AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting CONFIG A failed.");
- return false;
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_A, cfgA ) == false) {
+ AddLog(LOG_LEVEL_INFO,"HMC: Setting CONFIG A failed");
+ return false;
}
- if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_B, cfgB ) == false) {
- AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting CONFIG B failed.");
- return false;
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_CONFIG_B, cfgB ) == false) {
+ AddLog(LOG_LEVEL_INFO,"HMC: Setting CONFIG B failed");
+ return false;
}
if (HMC5883L->mode == HMC5883L_MODE_CONT) {
- if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_CONT ) == false)
- { AddLog(LOG_LEVEL_INFO,"HMC5883L: Setting continuous mode failed.");
- return false; }
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_CONT ) == false) {
+ AddLog(LOG_LEVEL_INFO,"HMC: Setting continuous mode failed");
+ return false;
+ }
}
return true;
}
-// Initialize the device
+// Initialize the device
void HMC5883L_Init() {
if (!I2cSetDevice(HMC5883L_ADDR)) { return; }
@@ -142,11 +143,13 @@ void HMC5883L_Init() {
//Read the magnetic data
void HMC5883L_ReadData(void) {
if (HMC5883L->mode == HMC5883L_MODE_SINGLE) {
- if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_SINGLE ) == false)
- { return; }
+ if (I2cWrite8(HMC5883L_ADDR, HMC5883L_MODE, HMC5883L_MODE_SINGLE ) == false) { return; }
+ }
+
+ uint32_t timeout = millis() + 20;
+ while (!(I2cRead8(HMC5883L_ADDR, HMC5883L_STATUS) & HMC5883L_STATUS_RDY)) {
+ if (millis() > timeout) { return; } // Chip not yet ready, next round try again
}
-
- while (!(I2cRead8(HMC5883L_ADDR, HMC5883L_STATUS) & HMC5883L_STATUS_RDY)) { } // Chip not yet ready, next round try again
HMC5883L->MX = I2cReadS16(HMC5883L_ADDR, HMC5883L_X_MSB); // Select starting with MSB register
HMC5883L->MY = I2cReadS16(HMC5883L_ADDR, HMC5883L_Y_MSB);
@@ -184,32 +187,32 @@ bool HMC5883L_Command() {
bool commandKnown = false;
char cmd[20];
char ss2[20];
-
+
subStr(cmd, XdrvMailbox.data, ",", 1);
int8_t value = atoi(subStr(ss2, XdrvMailbox.data, ",", 2));
- if (strcmp(cmd,"GAIN")) {
+ if (strcmp(cmd,"GAIN")) {
HMC5883L->gain = value;
- commandKnown = true;
- }
- if (strcmp(cmd,"AVG")) {
- HMC5883L->average_mode = value;
commandKnown = true;
}
- if (strcmp(cmd,"RATE")) {
- HMC5883L->data_rate = value;
+ if (strcmp(cmd,"AVG")) {
+ HMC5883L->average_mode = value;
commandKnown = true;
}
- if (strcmp(cmd,"MMODE")) {
- HMC5883L->measurement_mode = value;
+ if (strcmp(cmd,"RATE")) {
+ HMC5883L->data_rate = value;
commandKnown = true;
}
-
- //AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC5883L: cmd: (%s) value: %d cmdKnown: %d"), cmd, value,commandKnown);
+ if (strcmp(cmd,"MMODE")) {
+ HMC5883L->measurement_mode = value;
+ commandKnown = true;
+ }
+
+ //AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC: cmd: (%s) value: %d cmdKnown: %d"), cmd, value,commandKnown);
if (commandKnown == false) { return false; }
-
- AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC5883L: Reconfiguring."));
+
+ AddLog(LOG_LEVEL_INFO,PSTR(D_LOG_I2C "HMC: Reconfiguring."));
return HMC5883L_SetConfig();
}
@@ -227,8 +230,9 @@ bool Xsns101(uint32_t function) {
else if (HMC5883L != nullptr) {
switch (function) {
case FUNC_COMMAND_SENSOR:
- if (XSNS_101 == XdrvMailbox.index)
- return HMC5883L_Command(); // Return true on success
+ if (XSNS_101 == XdrvMailbox.index) {
+ return HMC5883L_Command(); // Return true on success
+ }
break;
case FUNC_JSON_APPEND:
HMC5883L_Show(1);
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 8a8324025..5780173b3 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -288,7 +288,7 @@ a_features = [[
],[
"USE_SGP40","USE_LUXV30B","USE_CANSNIFFER","USE_QMC5883L",
"USE_MODBUS_ENERGY","USE_SHELLY_PRO","USE_DALI","USE_BP1658CJ",
- "USE_DINGTIAN_RELAY","","","",
+ "USE_DINGTIAN_RELAY","USE_HMC5883L","","",
"","","","",
"","","","",
"","","","",
From e468cf53ee85991c4381b32cfb0aa17b53289d09 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Tue, 15 Nov 2022 18:53:38 +0100
Subject: [PATCH 200/319] add command RgxPort to setup port forwarding
---
.../xdrv_58_range_extender.ino | 51 ++++++++++++++++++-
1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 7352861dd..4ac0a2012 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -94,6 +94,8 @@ const char kDrvRgxCommands[] PROGMEM = "Rgx|" // Prefix
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
"|"
"NAPT"
+ "|"
+ "Port"
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
#ifdef ESP32
"|"
@@ -110,6 +112,7 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
&CmndRgxPassword,
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
&CmndRgxNAPT,
+ &CmndRgxPort,
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
#ifdef ESP32
&CmndRgxClients,
@@ -124,7 +127,6 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
#endif // ESP8266
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
-#include
#include
#ifdef ESP8266
#include
@@ -271,7 +273,52 @@ void CmndRgxNAPT(void)
}
}
ResponseCmndStateText(Settings->sbflag1.range_extender_napt);
-};
+}
+
+void CmndRgxPort(void)
+{
+ char *tok, *state, *parm_mac;
+ uint16_t gw, dst;
+ uint8_t proto = 0;
+
+ Response_P(PSTR("ERROR"));
+
+ if (ArgC()!=4) return;
+ if ((tok = strtok_r(XdrvMailbox.data, ", ", &state)) == 0) return;
+ if (strcasecmp("TCP", tok) == 0) proto = IP_PROTO_TCP;
+ if (strcasecmp("UDP", tok) == 0) proto = IP_PROTO_UDP;
+ if (!proto) return;
+ if ((tok = strtok_r(0, ", ", &state)) == 0) return;
+ if ((gw = strtoul(tok, nullptr, 0)) == 0) return;
+ if ((parm_mac = strtok_r(0, ", ", &state)) == 0) return;
+ if ((tok = strtok_r(0, ", ", &state)) == 0) return;
+ if ((dst = strtoul(tok, nullptr, 0)) == 0) return;
+
+#ifdef ESP32
+ wifi_sta_list_t wifi_sta_list = {0};
+ tcpip_adapter_sta_list_t adapter_sta_list = {0};
+
+ esp_wifi_ap_get_sta_list(&wifi_sta_list);
+ tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
+
+ for (int i=0; i %_I:%u"),
+ (proto == IP_PROTO_TCP) ? "TCP" : "UDP", (uint32_t)WiFi.localIP(), gw, adapter_sta_list.sta[i].ip.addr, dst);
+ return;
+ }
+ break;
+ }
+ }
+#endif // ESP32
+}
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
void ResponseRgxConfig(void)
From 8af22a1904e60380df5a2a80857b2a8e3e51dc97 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Tue, 15 Nov 2022 20:12:07 +0100
Subject: [PATCH 201/319] remove unneeded return
---
tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino | 1 -
1 file changed, 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 4ac0a2012..27b257177 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -312,7 +312,6 @@ void CmndRgxPort(void)
{
Response_P(PSTR("OK %s %_I:%u -> %_I:%u"),
(proto == IP_PROTO_TCP) ? "TCP" : "UDP", (uint32_t)WiFi.localIP(), gw, adapter_sta_list.sta[i].ip.addr, dst);
- return;
}
break;
}
From f7fa09ebbef2728ab7fb3c56b01ce38b4d6eaadc Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Tue, 15 Nov 2022 23:28:34 +0100
Subject: [PATCH 202/319] Berry add ``udp->stop()`` method
---
CHANGELOG.md | 1 +
lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 11 ++++++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c9543344..6d54b3036 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
+- Berry add ``udp->stop()`` method
### Breaking Changed
diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
index 4186673c5..489be4005 100644
--- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
+++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
@@ -37,7 +37,7 @@ extern "C" {
return be_call_c_func(vm, (void*) &be_udp_deinit_ntv, "=.p", "");
}
- // udp.begin(address:string, port:int) -> nil
+ // udp.begin(address:string, port:int) -> bool
int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) {
IPAddress addr((uint32_t)0);
// if no host or host is "" then we defult to INADDR_ANY (0.0.0.0)
@@ -50,6 +50,14 @@ extern "C" {
return be_call_c_func(vm, (void*) &be_udp_begin_ntv, "b", ".si");
}
+ // udp.stop() -> nil
+ void be_udp_stop_ntv(WiFiUDP *udp) {
+ udp->stop();
+ }
+ int32_t be_udp_stop(struct bvm *vm) {
+ return be_call_c_func(vm, (void*) &be_udp_stop_ntv, "b", ".");
+ }
+
// udp.begin_multicast(address:string, port:int) -> nil
int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) {
IPAddress addr((uint32_t)0);
@@ -159,6 +167,7 @@ class be_class_udp (scope: global, name: udp) {
begin, func(be_udp_begin)
begin_multicast, func(be_udp_begin_mcast)
read, func(be_udp_read)
+ stop, func(be_udp_stop)
}
@const_object_info_end */
From 0849b6e5ef7c0c9864e23dfe4561842dec6f7712 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 16 Nov 2022 08:33:13 +0100
Subject: [PATCH 203/319] Rename to udp.close()
---
CHANGELOG.md | 2 +-
lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d54b3036..dcf38e790 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file.
- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
-- Berry add ``udp->stop()`` method
+- Berry add ``udp->close()`` method (#17094)
### Breaking Changed
diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
index 489be4005..27a97189f 100644
--- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
+++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp
@@ -167,7 +167,7 @@ class be_class_udp (scope: global, name: udp) {
begin, func(be_udp_begin)
begin_multicast, func(be_udp_begin_mcast)
read, func(be_udp_read)
- stop, func(be_udp_stop)
+ close, func(be_udp_stop)
}
@const_object_info_end */
From b92d5ab12c80d2ff71c490623f6de7239d39d2a5 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 16 Nov 2022 10:47:55 +0100
Subject: [PATCH 204/319] Fix ArtNet compilation on ESP32
---
.../tasmota_xdrv_driver/xdrv_04_light_artnet.ino | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
index 4ce80f126..a1ea8328d 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -145,9 +145,9 @@ void ArtNetProcessPacket(uint8_t * buf, size_t len) {
if (artnet_conf.matrix) {
// Ws2812 led strip
- size_t pix_size = Ws2812StripGetPixelSize();
+ size_t pix_size = Ws2812StripGetPixelSize();
datalen = datalen - (datalen % pix_size);
-
+
if (artnet_conf.alt && (row % 2)) {
for (int32_t i = idx, j = idx + datalen - pix_size; i < j; i += pix_size, j -= pix_size) {
for (int32_t k = 0; k < pix_size; k++) {
@@ -223,9 +223,9 @@ void ArtNetLoop(void)
packet_len = ArtNetUdp->parsePacket();
packet_ready = (packet_len > 0);
while (packet_ready) {
- uint8_t packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
+ uint8_t packet_buffer[WS2812_ARTNET_UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet
- packet_len = ArtNetUdp->read(packet_buffer, UDP_BUFFER_SIZE);
+ packet_len = ArtNetUdp->read(packet_buffer, WS2812_ARTNET_UDP_BUFFER_SIZE);
ArtNetUdp->flush(); // Finish reading the current packet
#endif
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet %*_H (%d)"), 32, packet_buffer, packet_len);
@@ -237,7 +237,7 @@ void ArtNetLoop(void)
packet_ready = ArtNetUdp->next();
if (!packet_ready) {
// if no more incoming packet, still wait for 20 microseconds
- delay(1); // delayMicroseconds seems broken, need to
+ delay(1); // delayMicroseconds seems broken, need to
packet_ready = ArtNetUdp->next();
}
#else
@@ -291,13 +291,13 @@ void CmndArtNetConfig() {
ArtNetStop();
}
ArtNetLoadSettings();
-
+
TrimSpace(XdrvMailbox.data);
if (strlen(XdrvMailbox.data) > 0) {
JsonParser parser(XdrvMailbox.data);
JsonParserObject root = parser.getRootObject();
if (!root) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; }
-
+
artnet_conf.rows = root.getUInt(PSTR("Rows"), artnet_conf.rows);
artnet_conf.cols = root.getUInt(PSTR("Cols"), artnet_conf.cols);
artnet_conf.offs = root.getUInt(PSTR("Offset"), artnet_conf.offs);
From 229c2cce06cf2572039f4fa23f642cc86cf70031 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 16 Nov 2022 10:55:56 +0100
Subject: [PATCH 205/319] Revert Art-Net to ArtNet
---
CHANGELOG.md | 8 ++++----
RELEASENOTES.md | 4 ++--
tasmota/my_user_config.h | 2 +-
tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dcf38e790..a24b2651d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
- New ``FUNC_NETWORK_UP`` and ``FUNC_NETWORK_DOWN`` events
-- WS2812 and Light Art-Net DMX control over UDP port 6454 (#17059)
+- WS2812 and Light ArtNet DMX control over UDP port 6454 (#17059)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
- Berry add ``udp->close()`` method (#17094)
@@ -44,9 +44,9 @@ All notable changes to this project will be documented in this file.
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for NTAG2xx tags read and write on PN532 NFC reader (#16939)
- Berry ``bytes().reverse()`` method (#16977)
-- ESP32 Support for DMX Art-Net Led matrix animations (#16984)
+- ESP32 Support for DMX ArtNet Led matrix animations (#16984)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
-- ESP32 DMX Art-Net optimization to avoid any object allocation and avoid garbage collector pauses
+- ESP32 DMX ArtNet optimization to avoid any object allocation and avoid garbage collector pauses
- Berry add ``dyn`` class
### Changed
@@ -69,7 +69,7 @@ All notable changes to this project will be documented in this file.
- Berry add `bytes().setbytes()` (#16892)
- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
-- Prepare for DMX Art-Net support on ESP32
+- Prepare for DMX ArtNet support on ESP32
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 06b3968aa..94d13f0d6 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -121,11 +121,11 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069)
-- WS2812 and Light Art-Net DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
+- WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
-- ESP32 Support for DMX Art-Net Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
+- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
### Breaking Changed
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 58e6bb30b..725c55d9b 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -571,7 +571,7 @@
#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code)
//#define USE_LSC_MCSL // Add support for GPE Multi color smart light as sold by Action in the Netherlands (+1k1 code)
-// #define USE_LIGHT_ARTNET // Add support for DMX/Art-Net via UDP on port 6454 (+3.5k code)
+// #define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code)
#define USE_LIGHT_ARTNET_MCAST 239,255,25,54 // Multicast address used to listen: 239.255.25.24
// -- Counter input -------------------------------
diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
index 9d6e36f15..c0f7ff7e5 100644
--- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
+++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino
@@ -785,7 +785,7 @@ void CmndWidth(void)
}
/*********************************************************************************************\
- * Internal calls for Art-Net
+ * Internal calls for ArtNet
\*********************************************************************************************/
// check is the Neopixel strip is configured
bool Ws2812StripConfigured(void) {
From 0b18c60ba244fb7d3bd57b39bbe5eb0e49532750 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 16 Nov 2022 13:43:36 +0100
Subject: [PATCH 206/319] Zigbee ZbProbe for unknown devices and doc helper
---
tasmota/include/i18n.h | 1 +
.../xdrv_23_zigbee_A_impl.ino | 61 ++++++++++++++++++-
2 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 85445545b..7896e761b 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -689,6 +689,7 @@
#define D_CMND_ZIGBEE_LOAD "Load"
#define D_CMND_ZIGBEE_LOADDUMP "LoadDump"
#define D_CMND_ZIGBEE_UNLOAD "Unload"
+#define D_CMND_ZIGBEE_ATTRDUMP "AttrDump"
// Commands xdrv_25_A4988_Stepper.ino
#define D_CMND_MOTOR "MOTOR"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
index 4f44a8115..8fb559d34 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
@@ -21,6 +21,8 @@
#define XDRV_23 23
+#define ZIGBEE_DOC // enable special functions used for Zigbee documentation generation - generally not useful
+
#include "UnishoxStrings.h"
const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
@@ -40,7 +42,10 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_OCCUPANCY "|"
D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|" D_CMND_ZIGBEE_LEAVE "|"
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA "|" D_CMND_ZIGBEE_SCAN "|" D_CMND_ZIGBEE_ENROLL "|" D_CMND_ZIGBEE_CIE "|"
- D_CMND_ZIGBEE_LOAD "|" D_CMND_ZIGBEE_UNLOAD "|" D_CMND_ZIGBEE_LOADDUMP
+ D_CMND_ZIGBEE_LOAD "|" D_CMND_ZIGBEE_UNLOAD "|" D_CMND_ZIGBEE_LOADDUMP "|"
+#ifdef ZIGBEE_DOC
+ D_CMND_ZIGBEE_ATTRDUMP
+#endif // ZIGBEE_DOC
;
SO_SYNONYMS(kZbSynonyms,
@@ -64,6 +69,9 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
&CmndZbConfig, &CmndZbData, &CmndZbScan,
&CmndZbenroll, &CmndZbcie,
&CmndZbLoad, &CmndZbUnload, &CmndZbLoadDump,
+#ifdef ZIGBEE_DOC
+ &CmndZbAttrDump,
+#endif // ZIGBEE_DOC
};
/********************************************************************************************/
@@ -1119,8 +1127,16 @@ void CmndZbProbe(void) {
//
void CmndZbProbeOrPing(boolean probe) {
if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
- uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, nullptr, nullptr, XdrvMailbox.payload).shortaddr;
- if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE)); return; }
+ uint16_t parsed_shortaddr = BAD_SHORTADDR;
+ uint16_t shortaddr = zigbee_devices.parseDeviceFromName(XdrvMailbox.data, &parsed_shortaddr, nullptr, XdrvMailbox.payload).shortaddr;
+ if (BAD_SHORTADDR == shortaddr) {
+ if (BAD_SHORTADDR == parsed_shortaddr) { // second chance if we provided 0x.... address for a device not in the list
+ ResponseCmndChar_P(PSTR(D_ZIGBEE_UNKNOWN_DEVICE));
+ return;
+ } else {
+ shortaddr = parsed_shortaddr;
+ }
+ }
// set a timer for Reachable - 2s default value
zigbee_devices.setTimer(shortaddr, 0, Z_CAT_REACHABILITY_TIMEOUT, 0, 0, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
@@ -1417,6 +1433,45 @@ void CmndZbLoadDump(void) {
ResponseCmndDone();
}
+#ifdef ZIGBEE_DOC
+// Command `ZbAttrDump`
+// Dump all the attribute aliases for documentation purpose
+//
+void CmndZbAttrDump(void) {
+ // does not require Zigbee to actually run
+ AddLog(LOG_LEVEL_INFO, PSTR("Alias|Cluster|Attribute|Type"));
+ AddLog(LOG_LEVEL_INFO, PSTR(":---|:---|:---|:---"));
+ for (uint32_t i = 0; i < nitems(Z_PostProcess); i++) {
+ const Z_AttributeConverter *converter = &Z_PostProcess[i];
+ if (0 == pgm_read_word(&converter->name_offset)) { continue; }
+ const char * alias = Z_strings + pgm_read_word(&converter->name_offset);
+ uint16_t cluster = CxToCluster(pgm_read_byte(&converter->cluster_short));
+ uint16_t attrid = pgm_read_word(&converter->attribute);
+ uint8_t attrtype = pgm_read_byte(&converter->type);
+ char type_name[16];
+ Z_getTypeByNumber(type_name, sizeof(type_name), attrtype);
+ AddLog(LOG_LEVEL_INFO, PSTR("`%s`|0x%04X|0x%04X|%%%02X - %s"), alias, cluster, attrid, attrtype, type_name);
+ }
+ AddLog(LOG_LEVEL_INFO, PSTR(""));
+
+ AddLog(LOG_LEVEL_INFO, PSTR("Alias|Cluster|Command"));
+ AddLog(LOG_LEVEL_INFO, PSTR(":---|:---|:---"));
+ for (uint32_t i = 0; i < sizeof(Z_Commands) / sizeof(Z_Commands[0]); i++) {
+ const Z_CommandConverter *conv = &Z_Commands[i];
+ const char * alias = Z_strings + pgm_read_word(&conv->tasmota_cmd_offset);
+ uint16_t cluster = pgm_read_word(&conv->cluster);
+ uint8_t direction = pgm_read_byte(&conv->direction);
+ uint8_t cmd = pgm_read_byte(&conv->cmd);
+ if (direction & 0x01) { // only coordinator to device
+ AddLog(LOG_LEVEL_INFO, PSTR("`%s`|0x%04X|0x%02X"), alias, cluster, cmd);
+ }
+ }
+ AddLog(LOG_LEVEL_INFO, PSTR(""));
+
+ ResponseCmndDone();
+}
+#endif // ZIGBEE_DOC
+
//
// Command `ZbScan`
// Run an energy scan
From a26e634408208544a43b3c92dd5e1fb4c8ce9c2e Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 16 Nov 2022 13:44:06 +0100
Subject: [PATCH 207/319] Doc is off by default
---
tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
index 8fb559d34..c0b198523 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
@@ -21,7 +21,7 @@
#define XDRV_23 23
-#define ZIGBEE_DOC // enable special functions used for Zigbee documentation generation - generally not useful
+// #define ZIGBEE_DOC // enable special functions used for Zigbee documentation generation - generally not useful
#include "UnishoxStrings.h"
@@ -1467,7 +1467,7 @@ void CmndZbAttrDump(void) {
}
}
AddLog(LOG_LEVEL_INFO, PSTR(""));
-
+
ResponseCmndDone();
}
#endif // ZIGBEE_DOC
From 56e06b7fc545f96757d2bd96c8114dc239c4bbf0 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 16 Nov 2022 13:45:59 +0100
Subject: [PATCH 208/319] Fix command name bug
---
tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
index c0b198523..46f3b7023 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_A_impl.ino
@@ -42,9 +42,9 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_OCCUPANCY "|"
D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" D_CMND_ZIGBEE_MAP "|" D_CMND_ZIGBEE_LEAVE "|"
D_CMND_ZIGBEE_CONFIG "|" D_CMND_ZIGBEE_DATA "|" D_CMND_ZIGBEE_SCAN "|" D_CMND_ZIGBEE_ENROLL "|" D_CMND_ZIGBEE_CIE "|"
- D_CMND_ZIGBEE_LOAD "|" D_CMND_ZIGBEE_UNLOAD "|" D_CMND_ZIGBEE_LOADDUMP "|"
+ D_CMND_ZIGBEE_LOAD "|" D_CMND_ZIGBEE_UNLOAD "|" D_CMND_ZIGBEE_LOADDUMP
#ifdef ZIGBEE_DOC
- D_CMND_ZIGBEE_ATTRDUMP
+ "|" D_CMND_ZIGBEE_ATTRDUMP
#endif // ZIGBEE_DOC
;
From 99378308f7a0ffc5b3db9dc8c43ac5e053e2ee2f Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 16 Nov 2022 14:26:49 +0100
Subject: [PATCH 209/319] Update changelogs
---
CHANGELOG.md | 2 ++
RELEASENOTES.md | 2 ++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a24b2651d..c9c253068 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file.
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change (#17028)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn (#17069)
- Berry add ``udp->close()`` method (#17094)
+- Command ``RgxClients`` for range extender clients list (#17048)
+- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings (#17092)
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 94d13f0d6..72288e298 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -110,6 +110,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.4
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
+- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
+- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
From a0e7191d4e653951628767e10bc4bcc2536a608f Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 16 Nov 2022 16:15:31 +0100
Subject: [PATCH 210/319] Add command ArtNet
- Fix ArtNetStop
---
tasmota/include/i18n.h | 1 +
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 6 +++---
.../xdrv_04_light_artnet.ino | 17 +++++++++++++++++
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 7896e761b..8c8e3e4b5 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -502,6 +502,7 @@
#define D_CMND_PALETTE "Palette"
#define D_CMND_PIXELS "Pixels"
#define D_CMND_STEPPIXELS "StepPixels"
+#define D_CMND_ARTNET "ArtNet"
#define D_CMND_ARTNET_START "ArtNetStart"
#define D_CMND_ARTNET_STOP "ArtNetStop"
#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index e6cafd584..ef457a580 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -151,7 +151,7 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
"|" D_CMND_SEQUENCE_OFFSET
#endif // USE_DGR_LIGHT_SEQUENCE
#ifdef USE_LIGHT_ARTNET
- "|" D_CMND_ARTNET_START "|" D_CMND_ARTNET_STOP "|" D_CMND_ARTNET_CONFIG
+ "|" D_CMND_ARTNET "|" D_CMND_ARTNET_START "|" D_CMND_ARTNET_STOP "|" D_CMND_ARTNET_CONFIG
#endif
"|UNDOCA" ;
@@ -175,7 +175,7 @@ void (* const LightCommand[])(void) PROGMEM = {
&CmndSequenceOffset,
#endif // USE_DGR_LIGHT_SEQUENCE
#ifdef USE_LIGHT_ARTNET
- &CmndArtNetStart, &CmndArtNetStop, &CmndArtNetConfig,
+ &CmndArtNet, &CmndArtNetStart, &CmndArtNetStop, &CmndArtNetConfig,
#endif
&CmndUndocA };
@@ -1962,7 +1962,7 @@ void LightAnimate(void)
Light.fade_start_10[channel_ct] = Light.fade_end_10[channel_ct];
}
}
-
+
Light.fade_running = true;
Light.fade_duration = 0; // set the value to zero to force a recompute
Light.fade_start = 0;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
index a1ea8328d..8b5218c12 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -413,6 +413,7 @@ void ArtNetStop(void) {
void CmndArtNetStop(void) {
ArtNetStop();
+ Settings->flag6.artnet_autorun = false;
// restore default scheme
Settings->light_scheme = LS_POWER;
// Restore sleep value
@@ -421,5 +422,21 @@ void CmndArtNetStop(void) {
ResponseCmndDone();
}
+void CmndArtNet(void) {
+ if (0 == XdrvMailbox.payload) {
+ ArtNetStop();
+ Settings->flag6.artnet_autorun = false; // SetOption148 - (Light) start DMX ArtNet at boot, listen to UDP port as soon as network is up
+// Settings->light_scheme = LS_POWER; // restore default scheme
+ TasmotaGlobal.sleep = Settings->sleep; // Restore sleep value
+ Light.update = true; // Restore old color
+ }
+ if (1 == XdrvMailbox.payload) {
+ if (!ArtNetStart()) {
+ Settings->flag6.artnet_autorun = false; // SetOption148 - (Light) start DMX ArtNet at boot, listen to UDP port as soon as network is up
+ }
+ }
+ ResponseCmndStateText(artnet_udp_connected & Settings->flag6.artnet_autorun);
+}
+
#endif // USE_LIGHT_ARTNET
#endif // USE_LIGHT
From f044ccdeec1a9995c4442a69b3cdeb9a2faed4c5 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Wed, 16 Nov 2022 16:26:12 +0100
Subject: [PATCH 211/319] Remove commands ArtNetStop and ArtNetStart
---
tasmota/include/i18n.h | 2 --
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 4 ++--
.../xdrv_04_light_artnet.ino | 23 -------------------
3 files changed, 2 insertions(+), 27 deletions(-)
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index 8c8e3e4b5..a46c9d1a1 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -503,8 +503,6 @@
#define D_CMND_PIXELS "Pixels"
#define D_CMND_STEPPIXELS "StepPixels"
#define D_CMND_ARTNET "ArtNet"
-#define D_CMND_ARTNET_START "ArtNetStart"
-#define D_CMND_ARTNET_STOP "ArtNetStop"
#define D_CMND_ARTNET_CONFIG "ArtNetConfig"
#define D_SO_ARTNET_AUTORUN "ArtNetAutorun"
#define D_CMND_RGBWWTABLE "RGBWWTable"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index ef457a580..c42281b3d 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -151,7 +151,7 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
"|" D_CMND_SEQUENCE_OFFSET
#endif // USE_DGR_LIGHT_SEQUENCE
#ifdef USE_LIGHT_ARTNET
- "|" D_CMND_ARTNET "|" D_CMND_ARTNET_START "|" D_CMND_ARTNET_STOP "|" D_CMND_ARTNET_CONFIG
+ "|" D_CMND_ARTNET "|" D_CMND_ARTNET_CONFIG
#endif
"|UNDOCA" ;
@@ -175,7 +175,7 @@ void (* const LightCommand[])(void) PROGMEM = {
&CmndSequenceOffset,
#endif // USE_DGR_LIGHT_SEQUENCE
#ifdef USE_LIGHT_ARTNET
- &CmndArtNet, &CmndArtNetStart, &CmndArtNetStop, &CmndArtNetConfig,
+ &CmndArtNet, &CmndArtNetConfig,
#endif
&CmndUndocA };
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
index 8b5218c12..701374bd1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -381,18 +381,6 @@ bool ArtNetStart(void) {
return true;
}
-//
-// Command `ArtNetStart`
-// Params: XXX
-//
-void CmndArtNetStart(void) {
- if (ArtNetStart()) {
- ResponseCmndDone();
- } else {
- ResponseCmndError();
- }
-}
-
// Stop the ArtNet UDP flow and disconnect server
void ArtNetStop(void) {
artnet_udp_connected = false;
@@ -411,17 +399,6 @@ void ArtNetStop(void) {
}
}
-void CmndArtNetStop(void) {
- ArtNetStop();
- Settings->flag6.artnet_autorun = false;
- // restore default scheme
- Settings->light_scheme = LS_POWER;
- // Restore sleep value
- TasmotaGlobal.sleep = Settings->sleep;
- // OK
- ResponseCmndDone();
-}
-
void CmndArtNet(void) {
if (0 == XdrvMailbox.payload) {
ArtNetStop();
From 04b6034909b15dd137a2df317e00b64c0e254b3f Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Wed, 16 Nov 2022 16:43:25 +0100
Subject: [PATCH 212/319] action-gh-release@v1.2
fix deprecation warning "Node12"
---
.github/workflows/Tasmota_build_master.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml
index e538a623f..40f3baec2 100644
--- a/.github/workflows/Tasmota_build_master.yml
+++ b/.github/workflows/Tasmota_build_master.yml
@@ -187,7 +187,7 @@ jobs:
- name: Display structure of downloaded files
run: ls -R ./mv_firmware/
- name: Release
- uses: jason2866/action-gh-release@v1.1
+ uses: jason2866/action-gh-release@v1.2
#if: startsWith(github.ref, 'refs/tags/')
with:
tag_name: ${{ github.run_number }}
From 4eb0bf80dc0747a4fcf7b00da1514c6205564bf9 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Wed, 16 Nov 2022 17:28:03 +0100
Subject: [PATCH 213/319] preserve AP connections if STA side reconnects
---
tasmota/tasmota_support/support_wifi.ino | 9 ++++++---
.../xdrv_58_range_extender.ino | 16 ++++------------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index d06a35569..98f11ee90 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -210,10 +210,13 @@ void WifiBegin(uint8_t flag, uint8_t channel)
#endif // USE_EMULATION
WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083)
- WiFi.disconnect(true); // Delete SDK wifi config
- delay(200);
+ if (WiFi.getMode() != WIFI_AP_STA) // Preserve range extender connections
+ {
+ WiFi.disconnect(true); // Delete SDK wifi config
+ delay(200);
- WifiSetMode(WIFI_STA); // Disable AP mode
+ WifiSetMode(WIFI_STA); // Disable AP mode
+ }
WiFiSetSleepMode();
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } // B/G/N
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11G) { WiFi.setPhyMode(WIFI_PHY_MODE_11G); } // B/G
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index 27b257177..48e47b8e8 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -146,7 +146,6 @@ void (*const DrvRgxCommand[])(void) PROGMEM = {
typedef struct
{
uint8_t status = RGX_NOT_CONFIGURED;
- uint16_t lastlinkcount = 0;
#ifdef USE_WIFI_RANGE_EXTENDER_NAPT
bool napt_enabled = false;
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
@@ -360,7 +359,6 @@ void rngxSetup()
WiFi.softAP(SettingsText(SET_RGX_SSID), SettingsText(SET_RGX_PASSWORD));
AddLog(LOG_LEVEL_INFO, PSTR("RGX: WiFi Extender AP Enabled with SSID: %s"), WiFi.softAPSSID().c_str());
RgxSettings.status = RGX_SETUP_NAPT;
- RgxSettings.lastlinkcount = Wifi.link_count;
}
void rngxSetupNAPT(void)
@@ -463,17 +461,11 @@ bool Xdrv58(uint32_t function)
}
else if (RgxSettings.status == RGX_CONFIGURED)
{
- if (Wifi.status != WL_CONNECTED)
+ if (Wifi.status == WL_CONNECTED && WiFi.getMode() != WIFI_AP_STA)
{
- // No longer connected, need to setup again
- AddLog(LOG_LEVEL_INFO, PSTR("RGX: No longer connected, prepare to reconnect WiFi AP..."));
- RgxSettings.status = RGX_NOT_CONFIGURED;
- }
- else if (RgxSettings.lastlinkcount != Wifi.link_count && WiFi.getMode() != WIFI_AP_STA)
- {
- // Assume WiFi has reconnected and been reconfigured, prepare to reconnect
- AddLog(LOG_LEVEL_INFO, PSTR("RGX: Link count now: %d, WiFi.getMode(): %d, unconfigure..."), Wifi.link_count, WiFi.getMode());
- RgxSettings.status = RGX_NOT_CONFIGURED;
+ // Should not happen... our AP is gone and only a restart will get it back properly
+ AddLog(LOG_LEVEL_INFO, PSTR("RGX: WiFi mode is %d not %d. Restart..."), WiFi.getMode(), WIFI_AP_STA);
+ TasmotaGlobal.restart_flag = 2;
}
}
break;
From 5f0b92568ee88e77fd5c0f6b0a5dc6cb1c3769eb Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 16 Nov 2022 18:41:07 +0100
Subject: [PATCH 214/319] Add ArtNet to Tasmota32 precompiled
---
tasmota/include/tasmota_configurations_ESP32.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index 07f178f44..c9754c710 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -559,6 +559,7 @@
#undef USE_SHELLY_DIMMER // Disable support for Shelly Dimmer (+3k code)
#define USE_LIGHT_PALETTE // Add support for color palette (+0k9 code)
+#define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code)
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code)
From 7344fd54dc80d5117349b6031833b122b580d85a Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Wed, 16 Nov 2022 21:24:57 +0100
Subject: [PATCH 215/319] Fix ArtNet crash
---
tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
index 701374bd1..c2620fd9d 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -146,8 +146,12 @@ void ArtNetProcessPacket(uint8_t * buf, size_t len) {
if (artnet_conf.matrix) {
// Ws2812 led strip
size_t pix_size = Ws2812StripGetPixelSize();
+ // check that datalen does not exceed the number of columns
+ if (datalen > artnet_conf.cols * pix_size) { datalen = artnet_conf.cols * pix_size; }
+ // round to exact number of pixels
datalen = datalen - (datalen % pix_size);
+ size_t offset_in_matrix = 0;
if (artnet_conf.alt && (row % 2)) {
for (int32_t i = idx, j = idx + datalen - pix_size; i < j; i += pix_size, j -= pix_size) {
for (int32_t k = 0; k < pix_size; k++) {
@@ -156,6 +160,7 @@ void ArtNetProcessPacket(uint8_t * buf, size_t len) {
buf[j+k] = temp;
}
}
+ offset_in_matrix = artnet_conf.cols * pix_size - datalen; // add a potential offset if the frame is smaller than the columns
}
// process dimmer
@@ -179,7 +184,7 @@ void ArtNetProcessPacket(uint8_t * buf, size_t len) {
// process pixels
size_t h_bytes = artnet_conf.cols * pix_size; // size in bytes of a single row
- size_t offset_in_matrix = artnet_conf.offs * pix_size + row * h_bytes;
+ offset_in_matrix += artnet_conf.offs * pix_size + row * h_bytes;
if (datalen > h_bytes) { datalen = h_bytes; } // copy at most one line
Ws2812CopyPixels(&buf[idx], datalen, offset_in_matrix);
@@ -366,6 +371,8 @@ bool ArtNetStart(void) {
Settings->light_pixels = artnet_conf.rows * artnet_conf.cols + artnet_conf.offs;
Settings->light_rotation = 0;
Ws2812ReinitStrip();
+ } else {
+ Ws2812Clear();
}
}
From b1ebda85248b365bd324c79d3870e74e0ff135a1 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Wed, 16 Nov 2022 23:51:54 +0100
Subject: [PATCH 216/319] Range extender port forwarding also for ESP8266
---
.../xdrv_58_range_extender.ino | 23 +++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index e1a42fa71..a0e5f3f62 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -302,7 +302,7 @@ void CmndRgxPort(void)
if ((tok = strtok_r(0, ", ", &state)) == 0) return;
if ((dst = strtoul(tok, nullptr, 0)) == 0) return;
-#ifdef ESP32
+#if defined(ESP32)
wifi_sta_list_t wifi_sta_list = {0};
tcpip_adapter_sta_list_t adapter_sta_list = {0};
@@ -324,7 +324,26 @@ void CmndRgxPort(void)
break;
}
}
-#endif // ESP32
+#elif defined(ESP8266)
+ struct station_info *station = wifi_softap_get_station_info();
+ while (station)
+ {
+ char list_mac[13];
+ const uint8_t *m = station->bssid;
+ snprintf(list_mac, sizeof(list_mac), PSTR("%02X%02X%02X%02X%02X%02X"), m[0], m[1], m[2], m[3], m[4], m[5]);
+ if (strcasecmp(list_mac, parm_mac) == 0)
+ {
+ if (ip_portmap_add(proto, (uint32_t)WiFi.localIP(), gw, station->ip.addr, dst))
+ {
+ Response_P(PSTR("OK %s %_I:%u -> %_I:%u"),
+ (proto == IP_PROTO_TCP) ? "TCP" : "UDP", (uint32_t)WiFi.localIP(), gw, station->ip.addr, dst);
+ }
+ break;
+ }
+ station = STAILQ_NEXT(station, next);
+ }
+ wifi_softap_free_station_info();
+#endif // ESP8266
}
#endif // USE_WIFI_RANGE_EXTENDER_NAPT
From be7581b377e1c226002eb22b5285b04b5beaa2f5 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Thu, 17 Nov 2022 11:13:40 +0100
Subject: [PATCH 217/319] Fix linker error using undef USE_WS2812 for ESP32
---
tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
index c2620fd9d..4dd37548b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -21,6 +21,10 @@
#ifdef USE_LIGHT
#ifdef USE_LIGHT_ARTNET
+#ifndef USE_WS2812
+#define USE_WS2812 // needed since USE_LIGHT_ARTNET is enabled for ESP32 by default
+#endif
+
#ifndef WS2812_ARTNET_UDP_BUFFER_SIZE
#define WS2812_ARTNET_UDP_BUFFER_SIZE 140 // Max 30 columns with 4 bytes per pixel
#endif
From a924e41ff36a59964151f4e5b37ca36a03fc4a2c Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 17 Nov 2022 11:44:51 +0100
Subject: [PATCH 218/319] Bump version v12.2.0.5
- Fixed ModbusBridge baudrates over 76500 baud (#17106)
- Bump version v12.2.0.5
---
CHANGELOG.md | 16 +++++++++++++---
RELEASENOTES.md | 3 ++-
tasmota/include/tasmota_types.h | 8 ++++++--
tasmota/include/tasmota_version.h | 2 +-
tasmota/tasmota_support/settings.ino | 3 +++
5 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9c253068..18ea13489 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,19 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
-## [12.2.0.4]
+## [12.2.0.5]
+### Added
+
+### Breaking Changed
+
+### Changed
+
+### Fixed
+- ModbusBridge baudrates over 76500 baud (#17106)
+
+### Removed
+
+## [12.2.0.4] 20221117
### Added
- Support for Plantower PMSx003T AQI models with temperature and humidity (#16971)
- Support for Dingtian x595/x165 shift register based relay boards by Barbudor (#17032)
@@ -15,8 +27,6 @@ All notable changes to this project will be documented in this file.
- Command ``RgxClients`` for range extender clients list (#17048)
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings (#17092)
-### Breaking Changed
-
### Changed
- Reverted Flash Mode back from ``DIO`` to ``DOUT`` for ESP8266/ESP8285 (#17019)
- ESP32 Framework (Core) from v2.0.5.2 to v2.0.5.3 (#17034)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 72288e298..517b565d9 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -107,7 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
-## Changelog v12.2.0.4
+## Changelog v12.2.0.5
### Added
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
@@ -149,6 +149,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Deduplicate code and fix %timer n% rule regression from v12.2.0 [#16914](https://github.com/arendst/Tasmota/issues/16914)
- Serial initialization for baudrate and config [#16970](https://github.com/arendst/Tasmota/issues/16970)
- ModbusBridge buffer overflow [#16979](https://github.com/arendst/Tasmota/issues/16979)
+- ModbusBridge baudrates over 76500 baud [#17106](https://github.com/arendst/Tasmota/issues/17106)
- SenseAir S8 module detection [#17033](https://github.com/arendst/Tasmota/issues/17033)
### Removed
diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h
index d1dd5c9eb..fbd94f0ab 100644
--- a/tasmota/include/tasmota_types.h
+++ b/tasmota/include/tasmota_types.h
@@ -729,7 +729,9 @@ typedef struct {
WebCamCfg2 webcam_config2; // 730
#endif // ESP32
uint16_t artnet_universe; // 734
- uint8_t free_esp32_734[7]; // 736
+ uint16_t modbus_sbaudrate; // 736
+
+ uint8_t free_esp32_738[5]; // 738
uint8_t novasds_startingoffset; // 73D
uint8_t web_color[18][3]; // 73E
@@ -830,7 +832,9 @@ typedef struct {
uint8_t shd_warmup_time; // F5E
uint8_t tcp_config; // F5F
uint8_t light_step_pixels; // F60
- uint8_t modbus_sbaudrate; // F61
+
+ uint8_t ex_modbus_sbaudrate; // F61 - v12.2.0.5
+
uint8_t modbus_sconfig; // F62
uint8_t free_f63[13]; // F63 - Decrement if adding new Setting variables just above and below
diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h
index 360603d83..4b48759ed 100644
--- a/tasmota/include/tasmota_version.h
+++ b/tasmota/include/tasmota_version.h
@@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
-const uint32_t VERSION = 0x0C020004; // 12.2.0.4
+const uint32_t VERSION = 0x0C020005; // 12.2.0.5
#endif // _TASMOTA_VERSION_H_
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index 9eeb09103..d3c4fd907 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -1607,6 +1607,9 @@ void SettingsDelta(void) {
Settings->energy_voltage_calibration2 = Settings->energy_voltage_calibration;
Settings->energy_current_calibration2 = Settings->energy_current_calibration;
}
+ if (Settings->version < 0x0C020005) { // 12.2.0.5
+ Settings->modbus_sbaudrate = Settings->ex_modbus_sbaudrate;
+ }
Settings->version = VERSION;
SettingsSave(1);
From 34ededb9d8822328f3d9e4e5b6d3a59e440f65fa Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 17 Nov 2022 12:01:09 +0100
Subject: [PATCH 219/319] Add comment for future use
---
tasmota/tasmota_support/support_wifi.ino | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index 98f11ee90..cb0e2abaa 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -210,13 +210,20 @@ void WifiBegin(uint8_t flag, uint8_t channel)
#endif // USE_EMULATION
WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083)
- if (WiFi.getMode() != WIFI_AP_STA) // Preserve range extender connections
- {
- WiFi.disconnect(true); // Delete SDK wifi config
+
+/*
+ // Replaced by below code (20221117)
+ WiFi.disconnect(true); // Delete SDK wifi config
+ delay(200);
+ WifiSetMode(WIFI_STA); // Disable AP mode
+*/
+ if (WiFi.getMode() != WIFI_AP_STA) { // Preserve range extender connections (#17103)
+ WiFi.disconnect(true); // Delete SDK wifi config
delay(200);
- WifiSetMode(WIFI_STA); // Disable AP mode
+ WifiSetMode(WIFI_STA); // Disable AP mode
}
+
WiFiSetSleepMode();
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } // B/G/N
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11G) { WiFi.setPhyMode(WIFI_PHY_MODE_11G); } // B/G
From b149da46c6fe8733fa418aab1d9d3e032bf5ba2b Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Thu, 17 Nov 2022 11:36:08 +0100
Subject: [PATCH 220/319] Add DS18x20 parasitic power usage on ESP32
---
CHANGELOG.md | 1 +
.../xsns_05_esp32_ds18x20.ino | 31 ++++++++++++++++++-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9c253068..cb75c9c3a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file.
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
- Zigbee improved Aqara plug support and completed cluster 0x0702 (#17073)
- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
+- Add parasitic power usage for DS18x20 on ESP32 defining W1_PARASITE_POWER
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
index 310f9d5da..2113f1aed 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino
@@ -51,6 +51,9 @@ const char kDs18x20Types[] PROGMEM = "DS18x20|DS18S20|DS1822|DS18B20|MAX31850";
uint8_t ds18x20_chipids[] = { 0, DS18S20_CHIPID, DS1822_CHIPID, DS18B20_CHIPID, MAX31850_CHIPID };
struct {
+#ifdef W1_PARASITE_POWER
+ float temperature;
+#endif
float temp_sum;
uint16_t numread;
uint8_t address[8];
@@ -130,9 +133,15 @@ void Ds18x20Convert(void) {
for (uint32_t i = 0; i < DS18X20Data.gpios; i++) {
ds = ds18x20_gpios[i];
ds->reset();
+#ifdef W1_PARASITE_POWER
+ // With parasite power held wire high at the end for parasitically powered devices
+ ds->write(W1_SKIP_ROM, 1); // Address all Sensors on Bus
+ ds->write(W1_CONVERT_TEMP, 1); // start conversion, no parasite power on at the end
+#else
ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
-// delay(750); // 750ms should be enough for 12bit conv
+#endif
+// delay(750); // 750ms should be enough for 12bit conv
}
}
@@ -147,7 +156,12 @@ bool Ds18x20Read(uint8_t sensor, float &t) {
ds = ds18x20_gpios[ds18x20_sensor[index].pins_id];
ds->reset();
ds->select(ds18x20_sensor[index].address);
+#ifdef W1_PARASITE_POWER
+ // With parasite power held wire high at the end for parasitically powered devices
+ ds->write(W1_READ_SCRATCHPAD, 1); // Read Scratchpad
+#else
ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad
+#endif
for (uint32_t i = 0; i < 9; i++) {
data[i] = ds->read();
@@ -157,6 +171,9 @@ bool Ds18x20Read(uint8_t sensor, float &t) {
case DS18S20_CHIPID: {
int16_t tempS = (((data[1] << 8) | (data[0] & 0xFE)) << 3) | ((0x10 - data[6]) & 0x0F);
t = ConvertTemp(tempS * 0.0625f - 0.250f);
+#ifdef W1_PARASITE_POWER
+ ds18x20_sensor[index].temperature = t;
+#endif
ds18x20_sensor[index].valid = SENSOR_MAX_MISS;
return true;
}
@@ -168,12 +185,18 @@ bool Ds18x20Read(uint8_t sensor, float &t) {
sign = -1;
}
t = ConvertTemp(sign * temp12 * 0.0625f); // Divide by 16
+#ifdef W1_PARASITE_POWER
+ ds18x20_sensor[index].temperature = t;
+#endif
ds18x20_sensor[index].valid = SENSOR_MAX_MISS;
return true;
}
case MAX31850_CHIPID: {
int16_t temp14 = (data[1] << 8) + (data[0] & 0xFC);
t = ConvertTemp(temp14 * 0.0625f); // Divide by 16
+#ifdef W1_PARASITE_POWER
+ ds18x20_sensor[index].temperature = t;
+#endif
ds18x20_sensor[index].valid = SENSOR_MAX_MISS;
return true;
}
@@ -244,7 +267,13 @@ void Ds18x20Show(bool json) {
uint8_t dsxflg = 0;
for (uint32_t i = 0; i < DS18X20Data.sensors; i++) {
+#ifdef W1_PARASITE_POWER
+ // With parasite power read one sensor at a time
+ if (ds18x20_sensor[i].valid) {
+ t = ds18x20_sensor[i].temperature;
+#else
if (Ds18x20Read(i, t)) { // Check if read failed
+#endif
Ds18x20Name(i);
if (json) {
From e578171a164ee1c93e9d80ba0528b3f877161aba Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 17 Nov 2022 12:47:09 +0100
Subject: [PATCH 221/319] Update changelogs
---
CHANGELOG.md | 2 +-
RELEASENOTES.md | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3b7a8144..b0ef04cd5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
## [12.2.0.5]
### Added
+- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER (#17112)
### Breaking Changed
@@ -34,7 +35,6 @@ All notable changes to this project will be documented in this file.
- WS2812 sends signal to only ``Pixels`` leds instead of sending to 512 leds (#17055)
- Zigbee improved Aqara plug support and completed cluster 0x0702 (#17073)
- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
-- Add parasitic power usage for DS18x20 on ESP32 defining W1_PARASITE_POWER
### Fixed
- SenseAir S8 module detection (#17033)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 517b565d9..dc470bdb0 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -128,6 +128,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
- ESP32 Support for DMX ArtNet Led matrix animations [#16984](https://github.com/arendst/Tasmota/issues/16984)
+- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER [#17112](https://github.com/arendst/Tasmota/issues/17112)
### Breaking Changed
- Redesign distance sensors VL53LXX, TOF10120, HRXL and DYP to use cm instead of mm [#17021](https://github.com/arendst/Tasmota/issues/17021)
From d1c7ee882b228b43c1e385452fbdd20a5a748fd6 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 17 Nov 2022 14:58:16 +0100
Subject: [PATCH 222/319] Reset energy today at midnight (#16791)
---
tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
index ba8ca1c53..6621eee9b 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_03_energy.ino
@@ -365,6 +365,8 @@ void Energy200ms(void)
Energy.kWhtoday[i] = 0;
Energy.kWhtoday_offset[i] = 0;
RtcSettings.energy_kWhtoday_ph[i] = 0;
+ Settings->energy_kWhtoday_ph[i] = 0;
+
Energy.start_energy[i] = 0;
// Energy.kWhtoday_delta = 0; // dont zero this, we need to carry the remainder over to tomorrow
Energy.daily_sum_import_balanced = 0.0;
From 0cd97d3890a26c849fbe91b5843467163c8c3579 Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Thu, 17 Nov 2022 15:14:28 +0100
Subject: [PATCH 223/319] Fix generic modbus single phase register output
---
tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
index 6f78aa48a..06e643632 100644
--- a/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
+++ b/tasmota/tasmota_xnrg_energy/xnrg_29_modbus.ino
@@ -750,18 +750,19 @@ void EnergyModbusShow(bool json) {
values[j] = NrgMbsUser[i].data[j];
}
uint32_t resolution = EnergyModbusResolution(NrgMbsUser[i].resolution);
+ uint32_t single = (!isnan(NrgMbsUser[i].data[1]) && !isnan(NrgMbsUser[i].data[2])) ? 0 : 1;
#ifdef ENERGY_MODBUS_DEBUG_SHOW
AddLog(LOG_LEVEL_DEBUG, PSTR("NRG: resolution %d -> %d"), NrgMbsUser[i].resolution, resolution);
#endif
if (json) {
- ResponseAppend_P(PSTR(",\"%s\":%s"), NrgMbsUser[i].json_name, EnergyFormat(value_chr, values, resolution));
+ ResponseAppend_P(PSTR(",\"%s\":%s"), NrgMbsUser[i].json_name, EnergyFormat(value_chr, values, resolution, single));
#ifdef USE_WEBSERVER
} else {
WSContentSend_PD(PSTR("{s}%s{m}%s %s{e}"),
NrgMbsUser[i].gui_name,
- WebEnergyFormat(value_chr, values, resolution),
+ WebEnergyFormat(value_chr, values, resolution, single),
NrgMbsUser[i].gui_unit);
#endif // USE_WEBSERVER
}
From 16b796ccd59aa40b79eabf363c0e9f143336f4b3 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 17 Nov 2022 17:30:44 +0100
Subject: [PATCH 224/319] Fix emulation regression from ArtNet implementation
---
tasmota/tasmota_support/support_tasmota.ino | 21 +++++-----------
tasmota/tasmota_xdrv_driver/xdrv_04_light.ino | 8 ++-----
.../xdrv_04_light_artnet.ino | 24 +++++++++++++++++++
3 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino
index 803bd0adf..f8234b9d3 100644
--- a/tasmota/tasmota_support/support_tasmota.ino
+++ b/tasmota/tasmota_support/support_tasmota.ino
@@ -1554,11 +1554,6 @@ void Every250mSeconds(void)
break;
case 3:
{
- // is there a network state change since last time, if so send events to modules
- static bool network_was_down = true; // keep track of the previous state of network
- bool network_state_changed = (network_was_down != (bool)TasmotaGlobal.global_state.network_down); // network state changed from last tick
- network_was_down = TasmotaGlobal.global_state.network_down;
-
if (!TasmotaGlobal.global_state.network_down) {
#ifdef FIRMWARE_MINIMAL
#ifdef CONFIG_IDF_TARGET_ESP32C3
@@ -1607,23 +1602,19 @@ void Every250mSeconds(void)
#endif // USE_DEVICE_GROUPS
// send FUNC_NETWORK_UP to all modules
- if (network_state_changed) {
- // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_UP"));
- XdrvXsnsCall(FUNC_NETWORK_UP);
- }
+// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_UP"));
+ XdrvXsnsCall(FUNC_NETWORK_UP);
MqttCheck();
} else {
#ifdef USE_DEVICE_GROUPS
- DeviceGroupsStop();
+ DeviceGroupsStop();
#endif // USE_DEVICE_GROUPS
- // send FUNC_NETWORK_UP to all modules
- if (network_state_changed) {
- // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_DOWN"));
- XdrvXsnsCall(FUNC_NETWORK_DOWN);
- }
+ // send FUNC_NETWORK_DOWN to all modules
+// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("WIF: Sending FUNC_NETWORK_DOWN"));
+ XdrvXsnsCall(FUNC_NETWORK_DOWN);
} // Every x.75 second
}
break;
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
index c42281b3d..c865603c8 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino
@@ -3463,14 +3463,10 @@ bool Xdrv04(uint32_t function)
ArtNetJSONAppend();
break;
case FUNC_NETWORK_UP:
- if (Settings->flag6.artnet_autorun) {
- if (!ArtNetStart()) {
- Settings->flag6.artnet_autorun = false; // disable autorun if it failed, avoid nasty loop errors
- }
- }
+ ArtNetFuncNetworkUp();
break;
case FUNC_NETWORK_DOWN:
- ArtNetStop();
+ ArtNetFuncNetworkDown();
break;
#endif // USE_LIGHT_ARTNET
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
index 4dd37548b..00259f326 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light_artnet.ino
@@ -426,5 +426,29 @@ void CmndArtNet(void) {
ResponseCmndStateText(artnet_udp_connected & Settings->flag6.artnet_autorun);
}
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool artnet_network_up = false;
+
+void ArtNetFuncNetworkUp(void) {
+ if (!artnet_network_up) {
+ artnet_network_up = true;
+ if (Settings->flag6.artnet_autorun) {
+ if (!ArtNetStart()) {
+ Settings->flag6.artnet_autorun = false; // disable autorun if it failed, avoid nasty loop errors
+ }
+ }
+ }
+}
+
+void ArtNetFuncNetworkDown(void) {
+ if (artnet_network_up) {
+ artnet_network_up = false;
+ ArtNetStop();
+ }
+}
+
#endif // USE_LIGHT_ARTNET
#endif // USE_LIGHT
From 619c5431d77cd898d46886beae94d0ce5a7ff182 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Thu, 17 Nov 2022 17:54:42 +0100
Subject: [PATCH 225/319] Add Wemo SSDP presentationURL
Add Wemo SSDP presentationURL for easy access using Windows Networks Other Device device double click (#17084)
As implemented only works when USE_UNISHOX_COMPRESSION is disabled.
---
tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino | 4 ++++
tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
index 0d433fbdf..3dab180f5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
@@ -240,6 +240,7 @@ const char WEMO_SETUP_XML[] PROGMEM =
"3.1415"
"uuid:{x2"
"{x3"
+ "http://{x4:80/"
"0"
""
""
@@ -335,6 +336,9 @@ void HandleUpnpSetupWemo(void)
setup_xml.replace("{x1", SettingsText(SET_FRIENDLYNAME1));
setup_xml.replace("{x2", WemoUuid());
setup_xml.replace("{x3", WemoSerialnumber());
+
+ setup_xml.replace("{x4", WiFi.localIP().toString());
+
WSSend(200, CT_XML, setup_xml);
}
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
index 5ceb84ac9..8ef0e3be1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
@@ -203,6 +203,7 @@ const char WEMO_SETUP_XML[] PROGMEM =
"3.1415"
"uuid:{x2"
"{x3"
+ "http://{x4:80/"
"0"
""
""
@@ -396,6 +397,9 @@ private:
setup_xml.replace("{x1", SettingsText(SET_FRIENDLYNAME1 + (_deviceId - 1)));
setup_xml.replace("{x2", WemoUuid());
setup_xml.replace("{x3", WemoSerialnumber());
+
+ setup_xml.replace("{x4", WiFi.localIP().toString());
+
InternalWSSend(200, CT_XML, setup_xml);
#ifdef USE_EMULATION_WEMO_DEBUG
AddLog(LOG_LEVEL_DEBUG, PSTR("WMO: Sending device #%d: %s"), _deviceId, setup_xml.c_str());
From c607a67024fcd0ec5385d4f1150addd6b101277e Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 17 Nov 2022 20:26:00 +0100
Subject: [PATCH 226/319] Include Wemo SSDP presentationURL in Unishox
---
tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino | 28 +++++------
.../xdrv_21_wemo_multi.ino | 46 ++++++++++---------
2 files changed, 39 insertions(+), 35 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
index 3dab180f5..f3fa8ab92 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo.ino
@@ -130,9 +130,9 @@ const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0
"\xD0\xEC\x05\x4C\xFC\xFC\x3D\x0E\xC0\x43\xD8\xCE\xC0\x45\xE1\xA0\xFC\x9C\x29\x1B"
"\x8D";
-//urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x30urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n
-//Successfully compressed from 923 to 392 bytes (-57.5%)
-const size_t WEMO_SETUP_XML_SIZE = 923;
+//urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x3http://{x4:80/0urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n
+//Successfully compressed from 972 to 426 bytes (-56.2%)
+const size_t WEMO_SETUP_XML_SIZE = 972;
const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E"
"\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46"
"\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F"
@@ -143,16 +143,18 @@ const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\
"\x47\xA1\xD8\x08\xB3\x81\x0A\xC8\xB1\xA3\x9F\xCF\xC3\x96\x74\x99\x34\x81\x0E\xD8"
"\x20\xD0\x3D\x08\x59\x08\x5C\x7E\x0B\x17\xA2\x1E\x67\xB4\xD8\x72\x8F\x43\xB0\x88"
"\x59\x08\x5C\x7E\x1E\x9E\x7F\xDB\x04\x3B\xA7\xB4\xD8\x72\xCF\x43\xB0\x81\x22\x71"
- "\xE8\x3B\x7A\xFE\x64\x5E\xAB\xA6\x7E\x1C\x67\xA1\xD8\x40\x8F\x2C\xF4\xF3\xF9\x9E"
- "\x86\xC8\x2D\xF5\x02\x24\x90\x44\x8A\x09\x7C\x46\x82\x15\x33\xCC\x75\xFB\x43\x66"
- "\x6F\xA8\xF3\x39\x0F\x43\xB0\x81\x1F\x09\x04\x3C\x58\xB4\x40\x4E\xC5\x0B\x44\x04"
- "\x6C\x58\x11\x71\x52\xD1\x0F\xC3\xD0\x10\xB8\xE0\x21\x65\xF2\x08\xFC\x3B\x05\x8C"
- "\xE1\x87\x60\x21\x4D\x3B\x01\x23\x0D\x04\x6C\x08\xF4\x66\x6F\xA8\xBC\x2C\x70\x22"
- "\xE1\xEC\xCD\xF5\x02\x4E\x1A\x08\xF8\x09\xE8\x45\xE0\xC6\x08\x2F\xE1\x11\xF8\x08"
- "\x34\x81\x0B\x59\x3A\x1B\x06\x84\x7A\x1D\x80\x87\x5C\x11\x37\x2A\x01\x60\xBC\x34"
- "\x0D\x75\x7B\xC6\x30\x18\x5F\x0C\xC0\x87\x8A\x03\x02\xE1\x90\x11\xB0\xB0\x5F\xE1"
- "\x88\x11\xB0\xB0\x51\xE1\x80\x10\xEE\x82\xDF\x0C\x60\x87\x18\x10\x79\x7D\x04\x2E"
- "\x83\xD1\xF8\x7A\x1D\x9F\xCC\xA3\xF2\x70\xA4\x6E";
+ "\xE8\x33\xEF\xCF\xAA\xEB\x73\x88\x59\x7C\x82\x3F\x05\x55\x0C\x3C\xCE\xC3\xB0\xF6"
+ "\x9B\x0E\x61\xE7\xF6\x76\x1E\x87\x61\x02\x5D\xC3\xD0\x76\xF5\xFC\xC8\xBD\x57\x4C"
+ "\xFC\x38\xCF\x43\xB0\x81\x1E\x59\xE9\xE7\xF3\x3D\x0D\x90\x5B\xEA\x04\x49\x20\x89"
+ "\x14\x12\xF8\xBE\x04\x2A\x2B\x67\x98\xEB\xF6\x86\xCC\xDF\x51\xE6\x72\x1E\x87\x61"
+ "\x02\x3E\x12\x08\x78\xB1\x68\x80\x9D\x8A\x16\x88\x08\xD8\xB0\x22\xE2\xA5\xA2\x1F"
+ "\x87\xA0\x21\x72\x22\x42\xCB\xE4\x11\xF8\x76\x0B\x19\xC3\x0E\xC0\x42\x9A\x76\x02"
+ "\x46\x1A\x08\xD8\x11\xE8\xCC\xDF\x51\x78\x58\xE0\x45\xC3\xD9\x9B\xEA\x04\x9C\x34"
+ "\x11\xF0\x13\xD0\x8B\xC1\x8C\x10\x5F\xC2\x23\xF0\x10\x69\x02\x16\xB2\x74\x36\x0D"
+ "\x08\xF4\x3B\x01\x0E\xB8\x22\x6E\x2A\x01\xC1\x78\x68\x1A\xEA\xF7\x8C\x60\x30\xBE"
+ "\x19\x81\x0F\x14\x06\x05\xC3\x20\x23\x61\x60\xBF\xC3\x10\x23\x61\x60\xA3\xC3\x2A"
+ "\x01\x21\xDD\x05\xBE\x18\xC1\x0E\x30\x20\xF2\xFA\x08\x5D\x0A\xB3\xF0\xF4\x3B\x3F"
+ "\x99\x47\xE4\xE1\x48\xDC";
#else
const char WEMO_EVENTSERVICE_XML[] PROGMEM =
""
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
index 8ef0e3be1..c6b5f9410 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_21_wemo_multi.ino
@@ -93,29 +93,31 @@ const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0
"\xD0\xEC\x05\x4C\xFC\xFC\x3D\x0E\xC0\x43\xD8\xCE\xC0\x45\xE1\xA0\xFC\x9C\x29\x1B"
"\x8D";
-//urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x30urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n
-//Successfully compressed from 923 to 392 bytes (-57.5%)
-const size_t WEMO_SETUP_XML_SIZE = 923;
+//urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x3http://{x4:80/0urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n
+//Successfully compressed from 972 to 426 bytes (-56.2%)
+const size_t WEMO_SETUP_XML_SIZE = 972;
const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E"
- "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46"
- "\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F"
- "\x01\x33\x07\x3C\xC3\xCE\xAF\xE0\x41\x36\x79\x9C\x87\xA1\xD8\x40\x8D\x83\x9E\x86"
- "\x3F\xAF\x84\x08\xC8\xBA\xC6\xB3\xF0\xF6\x9B\x0E\x43\xD0\xEC\x20\x48\x9C\x7A\x0D"
- "\xBE\x16\x62\xC3\xA1\x7F\x7F\x3F\x01\x07\x31\x45\xBD\x4F\xFD\x75\xB9\xD6\x12\x2D"
- "\xE0\xCE\x87\xA1\xD8\x09\x18\x21\xE8\x37\x04\x61\x17\x58\xD6\x7E\x17\xB0\x33\x47"
- "\x47\xA1\xD8\x08\xB3\x81\x0A\xC8\xB1\xA3\x9F\xCF\xC3\x96\x74\x99\x34\x81\x0E\xD8"
- "\x20\xD0\x3D\x08\x59\x08\x5C\x7E\x0B\x17\xA2\x1E\x67\xB4\xD8\x72\x8F\x43\xB0\x88"
- "\x59\x08\x5C\x7E\x1E\x9E\x7F\xDB\x04\x3B\xA7\xB4\xD8\x72\xCF\x43\xB0\x81\x22\x71"
- "\xE8\x3B\x7A\xFE\x64\x5E\xAB\xA6\x7E\x1C\x67\xA1\xD8\x40\x8F\x2C\xF4\xF3\xF9\x9E"
- "\x86\xC8\x2D\xF5\x02\x24\x90\x44\x8A\x09\x7C\x46\x82\x15\x33\xCC\x75\xFB\x43\x66"
- "\x6F\xA8\xF3\x39\x0F\x43\xB0\x81\x1F\x09\x04\x3C\x58\xB4\x40\x4E\xC5\x0B\x44\x04"
- "\x6C\x58\x11\x71\x52\xD1\x0F\xC3\xD0\x10\xB8\xE0\x21\x65\xF2\x08\xFC\x3B\x05\x8C"
- "\xE1\x87\x60\x21\x4D\x3B\x01\x23\x0D\x04\x6C\x08\xF4\x66\x6F\xA8\xBC\x2C\x70\x22"
- "\xE1\xEC\xCD\xF5\x02\x4E\x1A\x08\xF8\x09\xE8\x45\xE0\xC6\x08\x2F\xE1\x11\xF8\x08"
- "\x34\x81\x0B\x59\x3A\x1B\x06\x84\x7A\x1D\x80\x87\x5C\x11\x37\x2A\x01\x60\xBC\x34"
- "\x0D\x75\x7B\xC6\x30\x18\x5F\x0C\xC0\x87\x8A\x03\x02\xE1\x90\x11\xB0\xB0\x5F\xE1"
- "\x88\x11\xB0\xB0\x51\xE1\x80\x10\xEE\x82\xDF\x0C\x60\x87\x18\x10\x79\x7D\x04\x2E"
- "\x83\xD1\xF8\x7A\x1D\x9F\xCC\xA3\xF2\x70\xA4\x6E";
+ "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46"
+ "\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F"
+ "\x01\x33\x07\x3C\xC3\xCE\xAF\xE0\x41\x36\x79\x9C\x87\xA1\xD8\x40\x8D\x83\x9E\x86"
+ "\x3F\xAF\x84\x08\xC8\xBA\xC6\xB3\xF0\xF6\x9B\x0E\x43\xD0\xEC\x20\x48\x9C\x7A\x0D"
+ "\xBE\x16\x62\xC3\xA1\x7F\x7F\x3F\x01\x07\x31\x45\xBD\x4F\xFD\x75\xB9\xD6\x12\x2D"
+ "\xE0\xCE\x87\xA1\xD8\x09\x18\x21\xE8\x37\x04\x61\x17\x58\xD6\x7E\x17\xB0\x33\x47"
+ "\x47\xA1\xD8\x08\xB3\x81\x0A\xC8\xB1\xA3\x9F\xCF\xC3\x96\x74\x99\x34\x81\x0E\xD8"
+ "\x20\xD0\x3D\x08\x59\x08\x5C\x7E\x0B\x17\xA2\x1E\x67\xB4\xD8\x72\x8F\x43\xB0\x88"
+ "\x59\x08\x5C\x7E\x1E\x9E\x7F\xDB\x04\x3B\xA7\xB4\xD8\x72\xCF\x43\xB0\x81\x22\x71"
+ "\xE8\x33\xEF\xCF\xAA\xEB\x73\x88\x59\x7C\x82\x3F\x05\x55\x0C\x3C\xCE\xC3\xB0\xF6"
+ "\x9B\x0E\x61\xE7\xF6\x76\x1E\x87\x61\x02\x5D\xC3\xD0\x76\xF5\xFC\xC8\xBD\x57\x4C"
+ "\xFC\x38\xCF\x43\xB0\x81\x1E\x59\xE9\xE7\xF3\x3D\x0D\x90\x5B\xEA\x04\x49\x20\x89"
+ "\x14\x12\xF8\xBE\x04\x2A\x2B\x67\x98\xEB\xF6\x86\xCC\xDF\x51\xE6\x72\x1E\x87\x61"
+ "\x02\x3E\x12\x08\x78\xB1\x68\x80\x9D\x8A\x16\x88\x08\xD8\xB0\x22\xE2\xA5\xA2\x1F"
+ "\x87\xA0\x21\x72\x22\x42\xCB\xE4\x11\xF8\x76\x0B\x19\xC3\x0E\xC0\x42\x9A\x76\x02"
+ "\x46\x1A\x08\xD8\x11\xE8\xCC\xDF\x51\x78\x58\xE0\x45\xC3\xD9\x9B\xEA\x04\x9C\x34"
+ "\x11\xF0\x13\xD0\x8B\xC1\x8C\x10\x5F\xC2\x23\xF0\x10\x69\x02\x16\xB2\x74\x36\x0D"
+ "\x08\xF4\x3B\x01\x0E\xB8\x22\x6E\x2A\x01\xC1\x78\x68\x1A\xEA\xF7\x8C\x60\x30\xBE"
+ "\x19\x81\x0F\x14\x06\x05\xC3\x20\x23\x61\x60\xBF\xC3\x10\x23\x61\x60\xA3\xC3\x2A"
+ "\x01\x21\xDD\x05\xBE\x18\xC1\x0E\x30\x20\xF2\xFA\x08\x5D\x0A\xB3\xF0\xF4\x3B\x3F"
+ "\x99\x47\xE4\xE1\x48\xDC";
#else
const char WEMO_EVENTSERVICE_XML[] PROGMEM =
""
From e144b57b53e3af9d7ec1a09e4794081362ac5566 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Thu, 17 Nov 2022 20:29:31 +0100
Subject: [PATCH 227/319] Avoid crash if malloc fails
---
lib/default/Ext-printf/src/ext_printf.cpp | 31 +++++++++++------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/lib/default/Ext-printf/src/ext_printf.cpp b/lib/default/Ext-printf/src/ext_printf.cpp
index 17a32701f..4ae6ee25e 100644
--- a/lib/default/Ext-printf/src/ext_printf.cpp
+++ b/lib/default/Ext-printf/src/ext_printf.cpp
@@ -208,9 +208,12 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
// get a fresh malloc allocated string based on the current pointer (can be in PROGMEM)
// It is the caller's responsibility to free the memory
+//
+// Returns nullptr if something went wrong
char * copyStr(const char * str) {
if (str == nullptr) { return nullptr; }
char * cpy = (char*) malloc(strlen_P(str) + 1);
+ if (cpy == nullptr) { return nullptr; } // something went wrong
strcpy_P(cpy, str);
return cpy;
}
@@ -222,10 +225,13 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
va_list va_cpy;
va_copy(va_cpy, va);
+ if (out_buf != nullptr) { *out_buf = '\0'; } // safeguard, if we abort, the result is an empty string
+
// iterate on fmt to extract arguments and patch them in place
char * fmt_cpy = copyStr(fmt_P);
- if (fmt_cpy == nullptr) { return 0; }
+ if (fmt_cpy == nullptr) { return 0; } // we couldn't copy the format, abort
char * fmt = fmt_cpy;
+ int32_t ret = 0; // return 0 if unsuccessful
const uint32_t ALLOC_SIZE = 12;
static const char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
@@ -277,6 +283,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else if (decimals > 0) {
char * hex_char = (char*) malloc(decimals*2 + 2);
+ if (hex_char == nullptr) { goto abort; }
ToHex_P((const uint8_t *)cur_val, decimals, hex_char, decimals*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
@@ -292,6 +299,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
if (buf_len) {
char * hex_char = (char*) malloc(buf_len*2 + 2);
+ if (hex_char == nullptr) { goto abort; }
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
@@ -307,6 +315,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
else if (decimals > 0) {
uint32_t val_size = decimals*6 + 2;
char * val_char = (char*) malloc(val_size);
+ if (val_char == nullptr) { goto abort; }
val_char[0] = '\0';
for (uint32_t count = 0; count < decimals; count++) {
uint32_t value = pgm_read_byte((const uint8_t *)cur_val +1) << 8 | pgm_read_byte((const uint8_t *)cur_val);
@@ -328,6 +337,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
case 'I': // Input is `uint32_t` 32 bits IP address, output is decimal dotted address
{
char * ip_str = (char*) malloc(16);
+ if (ip_str == nullptr) { goto abort; }
snprintf_P(ip_str, 16, PSTR("%u.%u.%u.%u"), cur_val & 0xFF, (cur_val >> 8) & 0xFF, (cur_val >> 16) & 0xFF, (cur_val >> 24) & 0xFF);
new_val_str = ip_str;
allocs[alloc_idx++] = new_val_str;
@@ -371,6 +381,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
new_val_str = copyStr(hex);
+ if (new_val_str == nullptr) { goto abort; }
allocs[alloc_idx++] = new_val_str;
}
}
@@ -384,24 +395,11 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
U64toHex(*(uint64_t*)cur_val, hex, decimals);
new_val_str = copyStr(hex);
+ if (new_val_str == nullptr) { goto abort; }
allocs[alloc_idx++] = new_val_str;
}
}
break;
- // Trying to do String allocation alternatives, but not as interesting as I thought in the beginning
- // case 's':
- // {
- // new_val_str = copyStr(((String*)cur_val)->c_str());
- // allocs[alloc_idx++] = new_val_str;
- // }
- // break;
- // case 'S':
- // {
- // funcString_t * func_str = (funcString_t*) cur_val;
- // new_val_str = copyStr((*func_str)().c_str());
- // allocs[alloc_idx++] = new_val_str;
- // }
- // break;
}
*cur_val_ptr = new_val_str;
*fmt = 's'; // replace `%_X` with `%0s` to display a string instead
@@ -412,8 +410,8 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
}
+
// Serial.printf("> format_final=%s\n", fmt_cpy); Serial.flush();
- int32_t ret = 0; // return 0 if unsuccessful
if (out_buf != nullptr) {
ret = vsnprintf_P(out_buf, buf_len, fmt_cpy, va_cpy);
} else {
@@ -434,6 +432,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
va_end(va_cpy);
+abort:
// disallocated all temporary strings
for (uint32_t i = 0; i < alloc_idx; i++) {
free((void*)allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
From d1c71ca91b5c440715662141dcf472a1a61b3b0e Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 18 Nov 2022 00:04:54 +0100
Subject: [PATCH 228/319] Fix Zigbee auto-responder frame direction
---
tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
index db21e801f..3ec2ae123 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
@@ -2307,6 +2307,9 @@ void ZCLFrame::autoResponder(const uint16_t *attr_list_ids, size_t attr_len) {
zcl.clusterSpecific = false; /* not cluster specific */
zcl.needResponse = false; /* noresponse */
zcl.direct = true; /* direct response */
+ if (localShortAddr == 0x0000) {
+ zcl.direction = 1; // if we are coordinator, then response is from client to server
+ }
zcl.setTransac(transactseq);
zcl.payload.addBuffer(buf);
zigbeeZCLSendCmd(zcl);
From 7e9e7b8e3e46af18756a30a70b0a9c45c303b1d9 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 18 Nov 2022 00:21:01 +0100
Subject: [PATCH 229/319] Zigbee add default plugin in flash
---
.../xdrv_23_zigbee_5_2_converters.ino | 11 -
.../xdrv_23_zigbee_7_6_flash_fs.ino | 142 +++++++
...ugin.ino => xdrv_23_zigbee_7_7_plugin.ino} | 386 +++++++++---------
.../xdrv_23_zigbee_7_8_default_plugin.ino | 53 +++
4 files changed, 391 insertions(+), 201 deletions(-)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_flash_fs.ino
rename tasmota/tasmota_xdrv_driver/{xdrv_23_zigbee_7_6_plugin.ino => xdrv_23_zigbee_7_7_plugin.ino} (58%)
create mode 100644 tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_8_default_plugin.ino
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
index 658d508a3..6266e8f49 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
@@ -761,17 +761,6 @@ void ZCLFrame::computeSyntheticAttributes(Z_attribute_list& attr_list) {
attr_list.addAttribute(0x0001, 0x0021).setUInt(toPercentageCR2032(mv) * 2);
}
break;
- case 0x00010021: // BatteryPercentage
- if (modelId.startsWith(F("TRADFRI")) ||
- modelId.startsWith(F("SYMFONISK"))) {
- attr.setUInt(attr.getUInt() * 2); // bug in IKEA remotes battery, need to double the value
- }
- break;
- case 0x00060000: // "Power" for lumi Door/Window is converted to "Contact"
- if (modelId.startsWith(F("lumi.sensor_magnet"))) {
- attr.setKeyId(0x0500, 0xFFF0 + ZA_Contact); // change cluster and attribute to 0500/FFF0
- }
- break;
case 0x02010008: // Pi Heating Demand - solve Eutotronic bug
case 0x02014008: // Eurotronic Host Flags decoding
{
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_flash_fs.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_flash_fs.ino
new file mode 100644
index 000000000..034a2ff64
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_flash_fs.ino
@@ -0,0 +1,142 @@
+/*
+ xdrv_23_zigbee_7_6_flash_fs.ino - implement a Flash based read-only triviall file-system
+
+ Copyright (C) 2022 Theo Arends and Stephan Hadinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_ZIGBEE
+
+#ifdef ESP32
+#include
+#else
+#include "FSImpl.h"
+#endif
+
+/********************************************************************
+** Subfile implementation
+**
+** Takes a string point in Flash and turn it to a read-only file
+********************************************************************/
+
+class FlashFileImpl;
+typedef std::shared_ptr FlashFileImplPtr;
+
+class FlashFileImpl : public FileImpl {
+public:
+
+ FlashFileImpl(const char* str) {
+ _buf = str;
+ _len = strlen_P(str);
+ _seek = 0;
+ }
+
+ virtual ~FlashFileImpl() {}
+
+ size_t write(const uint8_t *buf, size_t size) {
+ return 0; // not accepted
+ }
+
+ size_t read(uint8_t* buf, size_t size) {
+ if (_seek < _len) {
+ if (size + _seek > _len) {
+ size = _len - _seek; // always > 0 because of guarding test
+ }
+ memcpy_P(buf, _buf + _seek, size);
+ _seek += size;
+ return size;
+ }
+ return 0; // abort
+ }
+
+ void flush() {
+ // do nothing
+ }
+
+ bool setBufferSize(size_t size) {
+ return true;
+ }
+
+ bool seek(uint32_t pos, SeekMode mode) {
+ // AddLog(LOG_LEVEL_DEBUG, "ZIP: seek pos=%i mode=%i", pos, mode);
+ if (SeekSet == mode) {
+ if (pos <= _len) {
+ _seek = pos;
+ return true;
+ }
+ } else if (SeekCur == mode) {
+ if (_seek + pos <= _len) {
+ _seek += pos;
+ return true;
+ }
+ } else if (SeekEnd == mode) {
+ _seek = _len;
+ return true;
+ }
+ return false;
+ }
+
+ size_t position() const {
+ return _seek;
+ }
+
+ size_t size() const {
+ return _len;
+ }
+
+ void close() {
+ // do nothing
+ }
+ time_t getLastWrite() {
+ return 0;
+ }
+
+ const char* path() const {
+ return "";
+ }
+
+ const char* name() const {
+ return "";
+ }
+
+ boolean isDirectory(void) {
+ return false; // no directory allowed
+ }
+
+ FileImplPtr openNextFile(const char* mode) {
+ return nullptr; // TODO
+ }
+
+ void rewindDirectory(void) {
+ // ignore
+ }
+
+ operator bool() {
+ return true;
+ }
+
+ // ESP8266 specific?
+ bool truncate(uint32_t size) { return false; }
+ const char* fullName() const { return ""; }
+ bool isFile() const { return true; }
+ bool isDirectory() const { return false; }
+
+protected:
+ const char * _buf;
+ size_t _len;
+ uint32_t _seek;
+};
+
+#endif // USE_ZIGBEE
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_plugin.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino
similarity index 58%
rename from tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_plugin.ino
rename to tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino
index 4a1ef2b59..0e8fa2ce5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_6_plugin.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_7_plugin.ino
@@ -125,6 +125,200 @@ bool Zb_readline(class File *f, char* buf, size_t size) {
extern FS *ffsp;
#endif
+bool ZbLoad_inner(const char *filename, File &fp) {
+ char * filename_imported = nullptr;
+ Z_plugin_template * tmpl = nullptr; // current template with matchers and attributes
+ bool new_matchers = false; // indicates that we have finished the current matchers
+ char buf_line[96]; // max line is 96 bytes (comments don't count)
+
+ // read the first 6 chars
+ bool invalid_header = false;
+ static const char Z2T_HEADER_V1[] PROGMEM = "#Z2Tv1";
+ for (uint32_t i = 0; i < 6; i++) {
+ int c = fp.read();
+ if (c < 0) {
+ invalid_header = true;
+ break;
+ }
+ buf_line[i] = c;
+ buf_line[i+1] = 0;
+ }
+ if (!invalid_header) {
+ if (strcmp_P(buf_line, Z2T_HEADER_V1) != 0) {
+ invalid_header = true;
+ }
+ }
+
+ if (invalid_header) {
+ AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' invalid header", filename);
+ return false;
+ }
+
+ // parse line by line
+ while (1) {
+ if (!Zb_readline(&fp, buf_line, sizeof(buf_line))) {
+ // EOF
+ break;
+ }
+
+ // at first valid line, we instanciate a new plug-in instance and assign a filemane
+ if (filename_imported == nullptr) {
+ // allocate only once the filename for multiple entries
+ // freed only by `ZbUnload`
+ filename_imported = (char*) malloc(strlen(filename)+1);
+ strcpy(filename_imported, filename);
+ }
+
+ // there is a non-empty line, containing no space/tab/crlf
+ // depending on the first char, parse either device name or cluster/attribute+name
+ if (buf_line[0] == ':') {
+ if (tmpl == nullptr || new_matchers) {
+ tmpl = &g_plugin_templates.addToLast();
+ tmpl->filename = filename_imported;
+ new_matchers = false;
+ }
+ // parse device name
+ char *rest = buf_line + 1; // skip first char ':'
+ char *token = strtok_r(rest, ",", &rest);
+ Z_plugin_matcher & matcher = tmpl->matchers.addToLast();
+ if (token != nullptr) {
+ matcher.setModel(token);
+ }
+ token = strtok_r(rest, ",", &rest);
+ if (token != nullptr) {
+ matcher.setManuf(token);
+ }
+ } else {
+ if (tmpl == nullptr) {
+ continue;
+ }
+ new_matchers = true;
+ char *rest = buf_line;
+ char *token = strtok_r(rest, ",", &rest);
+ if (token == nullptr) {
+ continue;
+ }
+
+ // detect if token contains '=', if yes it is a synonym
+ char * delimiter_equal = strchr(token, '=');
+
+ if (delimiter_equal == nullptr) {
+ // NORMAL ATTRIBUTE
+ // token is of from '0000/0000' or '0000/0000%00'
+ char * delimiter_slash = strchr(token, '/');
+ char * delimiter_percent = strchr(token, '%');
+ if (delimiter_slash == nullptr || (delimiter_percent != nullptr && delimiter_slash > delimiter_percent)) {
+ AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' wrong delimiter '%s'", filename, token);
+ }
+
+ uint16_t attr_id = 0xFFFF;
+ uint16_t cluster_id = 0xFFFF;
+ uint8_t type_id = Zunk;
+ int8_t multiplier = 1;
+ int8_t divider = 1;
+ int16_t base = 0;
+ char * name = nullptr;
+ uint16_t manuf = 0;
+
+ cluster_id = strtoul(token, &delimiter_slash, 16);
+ if (!delimiter_percent) {
+ attr_id = strtoul(delimiter_slash+1, nullptr, 16);
+ } else {
+ attr_id = strtoul(delimiter_slash+1, &delimiter_percent, 16);
+ type_id = Z_getTypeByName(delimiter_percent+1);
+ }
+ // NAME of the attribute
+ token = strtok_r(rest, ",", &rest);
+ if (token == nullptr) {
+ AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' ignore missing name '%s'", filename, buf_line);
+ continue;
+ }
+ name = token;
+ // ADDITIONAL ELEMENTS?
+ // Ex: `manuf:1037`
+ while (token = strtok_r(rest, ",", &rest)) {
+ char * sub_token;
+ // look for multiplier
+ if (sub_token = Z_subtoken(token, Z_MUL)) {
+ multiplier = strtol(sub_token, nullptr, 10);
+ }
+ // look for divider
+ else if (sub_token = Z_subtoken(token, Z_DIV)) {
+ divider = strtol(sub_token, nullptr, 10); // negative to indicate divider
+ }
+ // look for offset (base)
+ else if (sub_token = Z_subtoken(token, Z_ADD)) {
+ base = strtol(sub_token, nullptr, 10); // negative to indicate divider
+ }
+ // look for `manuf:HHHH`
+ else if (sub_token = Z_subtoken(token, Z_MANUF)) {
+ manuf = strtoul(sub_token, nullptr, 16);
+ }
+ else {
+ AddLog(LOG_LEVEL_DEBUG, "ZIG: ZbLoad unrecognized modifier '%s'", token);
+ }
+ }
+
+ // token contains the name of the attribute
+ Z_plugin_attribute & plugin_attr = tmpl->attributes.addToLast();
+ plugin_attr.cluster = cluster_id;
+ plugin_attr.attribute = attr_id;
+ plugin_attr.type = type_id;
+ plugin_attr.setName(name);
+ plugin_attr.multiplier = multiplier;
+ plugin_attr.divider = divider;
+ plugin_attr.base = base;
+ plugin_attr.manuf = manuf;
+ } else {
+ // ATTRIBUTE SYNONYM
+ // token is of from '0000/0000=0000/0000,1'
+ char * rest2 = token;
+ char * tok2 = strtok_r(rest2, "=", &rest2);
+ char * delimiter_slash = strchr(tok2, '/');
+ uint16_t cluster_id = strtoul(tok2, &delimiter_slash, 16);
+ uint16_t attr_id = strtoul(delimiter_slash+1, nullptr, 16);
+ tok2 = strtok_r(rest2, "=", &rest2);
+ char * delimiter_slash2 = strchr(tok2, '/');
+ uint16_t new_cluster_id = strtoul(tok2, &delimiter_slash2, 16);
+ uint16_t new_attr_id = strtoul(delimiter_slash2+1, nullptr, 16);
+ int8_t multiplier = 1;
+ int8_t divider = 1;
+ int16_t base = 0;
+
+ // ADDITIONAL ELEMENTS?
+ while (token = strtok_r(rest, ",", &rest)) {
+ char * sub_token;
+ // look for multiplier
+ if (sub_token = Z_subtoken(token, Z_MUL)) {
+ multiplier = strtol(sub_token, nullptr, 10);
+ }
+ // look for divider
+ else if (sub_token = Z_subtoken(token, Z_DIV)) {
+ divider = strtol(sub_token, nullptr, 10); // negative to indicate divider
+ }
+ // look for offset (base)
+ else if (sub_token = Z_subtoken(token, Z_ADD)) {
+ base = strtol(sub_token, nullptr, 10); // negative to indicate divider
+ }
+ else {
+ AddLog(LOG_LEVEL_DEBUG, "ZIG: ZbLoad unrecognized modifier '%s'", token);
+ }
+ }
+ // create the synonym
+ Z_attribute_synonym & syn = tmpl->synonyms.addToLast();
+ syn.cluster = cluster_id;
+ syn.attribute = attr_id;
+ syn.new_cluster = new_cluster_id;
+ syn.new_attribute = new_attr_id;
+ syn.multiplier = multiplier;
+ syn.divider = divider;
+ syn.base = base;
+ }
+ }
+ }
+ return true;
+}
+
// load a file from filesystem
// returns `true` if success
bool ZbLoad(const char *filename_raw) {
@@ -147,196 +341,7 @@ bool ZbLoad(const char *filename_raw) {
return false;
}
- char * filename_imported = nullptr;
- Z_plugin_template * tmpl = nullptr; // current template with matchers and attributes
- bool new_matchers = false; // indicates that we have finished the current matchers
- char buf_line[96]; // max line is 96 bytes (comments don't count)
-
- // read the first 6 chars
- bool invalid_header = false;
- static const char Z2T_HEADER_V1[] PROGMEM = "#Z2Tv1";
- for (uint32_t i = 0; i < 6; i++) {
- int c = fp.read();
- if (c < 0) {
- invalid_header = true;
- break;
- }
- buf_line[i] = c;
- buf_line[i+1] = 0;
- }
- if (!invalid_header) {
- if (strcmp_P(buf_line, Z2T_HEADER_V1) != 0) {
- invalid_header = true;
- }
- }
-
- if (invalid_header) {
- AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' invalid header", filename_raw);
- return false;
- }
-
- // parse line by line
- while (1) {
- if (!Zb_readline(&fp, buf_line, sizeof(buf_line))) {
- // EOF
- break;
- }
-
- // at first valid line, we instanciate a new plug-in instance and assign a filemane
- if (filename_imported == nullptr) {
- // allocate only once the filename for multiple entries
- // freed only by `ZbUnload`
- filename_imported = (char*) malloc(strlen(filename.c_str())+1);
- strcpy(filename_imported, filename.c_str());
- }
-
- // there is a non-empty line, containing no space/tab/crlf
- // depending on the first char, parse either device name or cluster/attribute+name
- if (buf_line[0] == ':') {
- if (tmpl == nullptr || new_matchers) {
- tmpl = &g_plugin_templates.addToLast();
- tmpl->filename = filename_imported;
- new_matchers = false;
- }
- // parse device name
- char *rest = buf_line + 1; // skip first char ':'
- char *token = strtok_r(rest, ",", &rest);
- Z_plugin_matcher & matcher = tmpl->matchers.addToLast();
- if (token != nullptr) {
- matcher.setModel(token);
- }
- token = strtok_r(rest, ",", &rest);
- if (token != nullptr) {
- matcher.setManuf(token);
- }
- } else {
- if (tmpl == nullptr) {
- continue;
- }
- new_matchers = true;
- char *rest = buf_line;
- char *token = strtok_r(rest, ",", &rest);
- if (token == nullptr) {
- continue;
- }
-
- // detect if token contains '=', if yes it is a synonym
- char * delimiter_equal = strchr(token, '=');
-
- if (delimiter_equal == nullptr) {
- // NORMAL ATTRIBUTE
- // token is of from '0000/0000' or '0000/0000%00'
- char * delimiter_slash = strchr(token, '/');
- char * delimiter_percent = strchr(token, '%');
- if (delimiter_slash == nullptr || (delimiter_percent != nullptr && delimiter_slash > delimiter_percent)) {
- AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' wrong delimiter '%s'", filename_raw, token);
- }
-
- uint16_t attr_id = 0xFFFF;
- uint16_t cluster_id = 0xFFFF;
- uint8_t type_id = Zunk;
- int8_t multiplier = 1;
- int8_t divider = 1;
- int16_t base = 0;
- char * name = nullptr;
- uint16_t manuf = 0;
-
- cluster_id = strtoul(token, &delimiter_slash, 16);
- if (!delimiter_percent) {
- attr_id = strtoul(delimiter_slash+1, nullptr, 16);
- } else {
- attr_id = strtoul(delimiter_slash+1, &delimiter_percent, 16);
- type_id = Z_getTypeByName(delimiter_percent+1);
- }
- // NAME of the attribute
- token = strtok_r(rest, ",", &rest);
- if (token == nullptr) {
- AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' ignore missing name '%s'", filename_raw, buf_line);
- continue;
- }
- name = token;
- // ADDITIONAL ELEMENTS?
- // Ex: `manuf:1037`
- while (token = strtok_r(rest, ",", &rest)) {
- char * sub_token;
- // look for multiplier
- if (sub_token = Z_subtoken(token, Z_MUL)) {
- multiplier = strtol(sub_token, nullptr, 10);
- }
- // look for divider
- else if (sub_token = Z_subtoken(token, Z_DIV)) {
- divider = strtol(sub_token, nullptr, 10); // negative to indicate divider
- }
- // look for offset (base)
- else if (sub_token = Z_subtoken(token, Z_ADD)) {
- base = strtol(sub_token, nullptr, 10); // negative to indicate divider
- }
- // look for `manuf:HHHH`
- else if (sub_token = Z_subtoken(token, Z_MANUF)) {
- manuf = strtoul(sub_token, nullptr, 16);
- }
- else {
- AddLog(LOG_LEVEL_DEBUG, "ZIG: ZbLoad unrecognized modifier '%s'", token);
- }
- }
-
- // token contains the name of the attribute
- Z_plugin_attribute & plugin_attr = tmpl->attributes.addToLast();
- plugin_attr.cluster = cluster_id;
- plugin_attr.attribute = attr_id;
- plugin_attr.type = type_id;
- plugin_attr.setName(name);
- plugin_attr.multiplier = multiplier;
- plugin_attr.divider = divider;
- plugin_attr.base = base;
- plugin_attr.manuf = manuf;
- } else {
- // ATTRIBUTE SYNONYM
- // token is of from '0000/0000=0000/0000,1'
- char * rest2 = token;
- char * tok2 = strtok_r(rest2, "=", &rest2);
- char * delimiter_slash = strchr(tok2, '/');
- uint16_t cluster_id = strtoul(tok2, &delimiter_slash, 16);
- uint16_t attr_id = strtoul(delimiter_slash+1, nullptr, 16);
- tok2 = strtok_r(rest2, "=", &rest2);
- char * delimiter_slash2 = strchr(tok2, '/');
- uint16_t new_cluster_id = strtoul(tok2, &delimiter_slash2, 16);
- uint16_t new_attr_id = strtoul(delimiter_slash2+1, nullptr, 16);
- int8_t multiplier = 1;
- int8_t divider = 1;
- int16_t base = 0;
-
- // ADDITIONAL ELEMENTS?
- while (token = strtok_r(rest, ",", &rest)) {
- char * sub_token;
- // look for multiplier
- if (sub_token = Z_subtoken(token, Z_MUL)) {
- multiplier = strtol(sub_token, nullptr, 10);
- }
- // look for divider
- else if (sub_token = Z_subtoken(token, Z_DIV)) {
- divider = strtol(sub_token, nullptr, 10); // negative to indicate divider
- }
- // look for offset (base)
- else if (sub_token = Z_subtoken(token, Z_ADD)) {
- base = strtol(sub_token, nullptr, 10); // negative to indicate divider
- }
- else {
- AddLog(LOG_LEVEL_DEBUG, "ZIG: ZbLoad unrecognized modifier '%s'", token);
- }
- }
- // create the synonym
- Z_attribute_synonym & syn = tmpl->synonyms.addToLast();
- syn.cluster = cluster_id;
- syn.attribute = attr_id;
- syn.new_cluster = new_cluster_id;
- syn.new_attribute = new_attr_id;
- syn.multiplier = multiplier;
- syn.divider = divider;
- syn.base = base;
- }
- }
- }
+ return ZbLoad_inner(filename.c_str(), fp);
} else {
AddLog(LOG_LEVEL_ERROR, "ZIG: filesystem not enabled");
}
@@ -447,6 +452,7 @@ void ZbLoadDump(void) {
// Auto-load all files ending with '.zb'
void ZbAutoload(void) {
+ ZbAutoLoadFromFlash();
#ifdef USE_UFILESYS
if (ffsp) {
File dir = ffsp->open("/", "r");
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_8_default_plugin.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_8_default_plugin.ino
new file mode 100644
index 000000000..62e9f167f
--- /dev/null
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_7_8_default_plugin.ino
@@ -0,0 +1,53 @@
+/*
+ xdrv_23_zigbee_7_8_default_plugin.ino - default plugin stored in Flash
+
+ Copyright (C) 2021 Theo Arends and Stephan Hadinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_ZIGBEE
+
+/********************************************************************
+** Default plugin
+**
+** Below is a the template loaded at boot
+** We simulate a read-only file from the filesystem
+********************************************************************/
+
+const char Z_DEF_PLUGIN[] PROGMEM =
+ "#Z2Tv1" "\n"
+
+ // bug in IKEA remotes battery, need to double the value
+ ":TRADFRI*," "\n"
+ ":SYMFONISK*," "\n"
+ "0001/0021=0001/0021,mul:2" "\n" // BatteryPercentage
+
+ // "Power" for lumi Door/Window is converted to "Contact"
+ ":lumi.sensor_magnet*," "\n"
+ "0006/0000=0500/FFF2" "\n" // 0xFFF0 + ZA_Contact
+;
+
+/********************************************************************
+** Load from flash
+********************************************************************/
+void ZbAutoLoadFromFlash(void) {
+ FlashFileImplPtr fp = FlashFileImplPtr(new FlashFileImpl(Z_DEF_PLUGIN));
+ File f = File(fp);
+ if (ZbLoad_inner(PSTR(""), f)) {
+ AddLog(LOG_LEVEL_INFO, "ZIG: ZbLoad '%s' loaded successfully", PSTR(""));
+ }
+}
+
+#endif // USE_ZIGBEE
From cb234a26944b4197c0f4091167852b38821aca8a Mon Sep 17 00:00:00 2001
From: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Date: Fri, 18 Nov 2022 07:43:38 +0100
Subject: [PATCH 230/319] Revert "Avoid crash if malloc fails"
---
lib/default/Ext-printf/src/ext_printf.cpp | 31 ++++++++++++-----------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/lib/default/Ext-printf/src/ext_printf.cpp b/lib/default/Ext-printf/src/ext_printf.cpp
index 4ae6ee25e..17a32701f 100644
--- a/lib/default/Ext-printf/src/ext_printf.cpp
+++ b/lib/default/Ext-printf/src/ext_printf.cpp
@@ -208,12 +208,9 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
// get a fresh malloc allocated string based on the current pointer (can be in PROGMEM)
// It is the caller's responsibility to free the memory
-//
-// Returns nullptr if something went wrong
char * copyStr(const char * str) {
if (str == nullptr) { return nullptr; }
char * cpy = (char*) malloc(strlen_P(str) + 1);
- if (cpy == nullptr) { return nullptr; } // something went wrong
strcpy_P(cpy, str);
return cpy;
}
@@ -225,13 +222,10 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
va_list va_cpy;
va_copy(va_cpy, va);
- if (out_buf != nullptr) { *out_buf = '\0'; } // safeguard, if we abort, the result is an empty string
-
// iterate on fmt to extract arguments and patch them in place
char * fmt_cpy = copyStr(fmt_P);
- if (fmt_cpy == nullptr) { return 0; } // we couldn't copy the format, abort
+ if (fmt_cpy == nullptr) { return 0; }
char * fmt = fmt_cpy;
- int32_t ret = 0; // return 0 if unsuccessful
const uint32_t ALLOC_SIZE = 12;
static const char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
@@ -283,7 +277,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else if (decimals > 0) {
char * hex_char = (char*) malloc(decimals*2 + 2);
- if (hex_char == nullptr) { goto abort; }
ToHex_P((const uint8_t *)cur_val, decimals, hex_char, decimals*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
@@ -299,7 +292,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
if (buf_len) {
char * hex_char = (char*) malloc(buf_len*2 + 2);
- if (hex_char == nullptr) { goto abort; }
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
@@ -315,7 +307,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
else if (decimals > 0) {
uint32_t val_size = decimals*6 + 2;
char * val_char = (char*) malloc(val_size);
- if (val_char == nullptr) { goto abort; }
val_char[0] = '\0';
for (uint32_t count = 0; count < decimals; count++) {
uint32_t value = pgm_read_byte((const uint8_t *)cur_val +1) << 8 | pgm_read_byte((const uint8_t *)cur_val);
@@ -337,7 +328,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
case 'I': // Input is `uint32_t` 32 bits IP address, output is decimal dotted address
{
char * ip_str = (char*) malloc(16);
- if (ip_str == nullptr) { goto abort; }
snprintf_P(ip_str, 16, PSTR("%u.%u.%u.%u"), cur_val & 0xFF, (cur_val >> 8) & 0xFF, (cur_val >> 16) & 0xFF, (cur_val >> 24) & 0xFF);
new_val_str = ip_str;
allocs[alloc_idx++] = new_val_str;
@@ -381,7 +371,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
new_val_str = copyStr(hex);
- if (new_val_str == nullptr) { goto abort; }
allocs[alloc_idx++] = new_val_str;
}
}
@@ -395,11 +384,24 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
U64toHex(*(uint64_t*)cur_val, hex, decimals);
new_val_str = copyStr(hex);
- if (new_val_str == nullptr) { goto abort; }
allocs[alloc_idx++] = new_val_str;
}
}
break;
+ // Trying to do String allocation alternatives, but not as interesting as I thought in the beginning
+ // case 's':
+ // {
+ // new_val_str = copyStr(((String*)cur_val)->c_str());
+ // allocs[alloc_idx++] = new_val_str;
+ // }
+ // break;
+ // case 'S':
+ // {
+ // funcString_t * func_str = (funcString_t*) cur_val;
+ // new_val_str = copyStr((*func_str)().c_str());
+ // allocs[alloc_idx++] = new_val_str;
+ // }
+ // break;
}
*cur_val_ptr = new_val_str;
*fmt = 's'; // replace `%_X` with `%0s` to display a string instead
@@ -410,8 +412,8 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
}
-
// Serial.printf("> format_final=%s\n", fmt_cpy); Serial.flush();
+ int32_t ret = 0; // return 0 if unsuccessful
if (out_buf != nullptr) {
ret = vsnprintf_P(out_buf, buf_len, fmt_cpy, va_cpy);
} else {
@@ -432,7 +434,6 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
va_end(va_cpy);
-abort:
// disallocated all temporary strings
for (uint32_t i = 0; i < alloc_idx; i++) {
free((void*)allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
From 0674f9b0b67f71864dc07ed012ca01a121e2aced Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 18 Nov 2022 13:00:59 +0100
Subject: [PATCH 231/319] Add command ``SSerialBuffer 64..256``
Add command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) (#17120)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
.../TasmotaSerial-3.5.0/src/TasmotaSerial.cpp | 88 ++++++++++++++-----
.../TasmotaSerial-3.5.0/src/TasmotaSerial.h | 10 ++-
tasmota/include/i18n.h | 1 +
.../xdrv_08_serial_bridge.ino | 40 +++++++--
6 files changed, 108 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0ef04cd5..cbc9cc693 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
## [12.2.0.5]
### Added
- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER (#17112)
+- Command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) (#17120)
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index dc470bdb0..7d52cd8f2 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -112,6 +112,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
+- Command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) [#17120](https://github.com/arendst/Tasmota/issues/17120)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
index f750b956f..59b6dfe10 100644
--- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
+++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.cpp
@@ -134,12 +134,70 @@ bool TasmotaSerial::freeUart(void) {
}
return false;
}
+
+void TasmotaSerial::Esp32Begin(void) {
+ TSerial->begin(m_speed, m_config, m_rx_pin, m_tx_pin);
+ // For low bit rate, below 9600, set the Full RX threshold at 10 bytes instead of the default 120
+ if (m_speed <= 9600) {
+ // At 9600, 10 chars are ~10ms
+ uart_set_rx_full_threshold(m_uart, 10);
+ } else if (m_speed < 115200) {
+ // At 19200, 120 chars are ~60ms
+ // At 76800, 120 chars are ~15ms
+ uart_set_rx_full_threshold(m_uart, 120);
+ } else {
+ // At 115200, 256 chars are ~20ms
+ // Zigbee requires to keep frames together, i.e. 256 bytes max
+ uart_set_rx_full_threshold(m_uart, 256);
+ }
+ // For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
+ if (m_speed < 115200) {
+ // At 76800 the timeout is ~1ms
+ uart_set_rx_timeout(m_uart, 6);
+ }
+}
#endif
+size_t TasmotaSerial::setRxBufferSize(size_t size) {
+ if (size != serial_buffer_size) {
+ if (m_hardserial) {
+ if (size > 256) { // Default hardware serial Rx buffer size
+ #ifdef ESP8266
+ serial_buffer_size = size;
+ Serial.setRxBufferSize(serial_buffer_size);
+ #endif // ESP8266
+ #ifdef ESP32
+ if (TSerial) {
+ // RX Buffer can't be resized when Serial is already running
+ serial_buffer_size = size;
+ TSerial->flush();
+ TSerial->end();
+ delay(10); // Allow time to cleanup queues - if not used hangs ESP32
+ TSerial->setRxBufferSize(serial_buffer_size);
+ Esp32Begin();
+ }
+ #endif // ESP32
+ }
+ }
+ else if (m_buffer) {
+ uint8_t *m_buffer_temp = (uint8_t*)malloc(size); // Allocate new buffer
+ if (m_buffer_temp) { // If succesful de-allocate old buffer
+ free(m_buffer);
+ m_buffer = m_buffer_temp;
+ serial_buffer_size = size;
+ }
+ }
+ }
+ return serial_buffer_size;
+}
+
bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
if (!m_valid) { return false; }
if (m_hardserial) {
+ if (serial_buffer_size < 256) {
+ serial_buffer_size = 256;
+ }
#ifdef ESP8266
Serial.flush();
Serial.begin(speed, (SerialConfig)config);
@@ -157,10 +215,10 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
TSerial = new HardwareSerial(m_uart);
#else
if (0 == m_uart) {
- Serial.flush();
- Serial.end();
- delay(10); // Allow time to cleanup queues - if not used hangs ESP32
- TSerial = &Serial;
+ Serial.flush();
+ Serial.end();
+ delay(10); // Allow time to cleanup queues - if not used hangs ESP32
+ TSerial = &Serial;
} else {
TSerial = new HardwareSerial(m_uart);
}
@@ -173,25 +231,9 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
return m_valid; // As we currently only support hardware serial on ESP32 it's safe to exit here
}
}
- TSerial->begin(speed, config, m_rx_pin, m_tx_pin);
- // For low bit rate, below 9600, set the Full RX threshold at 10 bytes instead of the default 120
- if (speed <= 9600) {
- // At 9600, 10 chars are ~10ms
- uart_set_rx_full_threshold(m_uart, 10);
- } else if (speed < 115200) {
- // At 19200, 120 chars are ~60ms
- // At 76800, 120 chars are ~15ms
- uart_set_rx_full_threshold(m_uart, 120);
- } else {
- // At 115200, 256 chars are ~20ms
- // Zigbee requires to keep frames together, i.e. 256 bytes max
- uart_set_rx_full_threshold(m_uart, 256);
- }
- // For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
- if (speed < 115200) {
- // At 76800 the timeout is ~1ms
- uart_set_rx_timeout(m_uart, 6);
- }
+ m_speed = speed;
+ m_config = config;
+ Esp32Begin();
// Serial.printf("TSR: Using UART%d\n", m_uart);
#endif // ESP32
} else {
diff --git a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h
index f0ff57cd2..759433d66 100644
--- a/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h
+++ b/lib/default/TasmotaSerial-3.5.0/src/TasmotaSerial.h
@@ -40,6 +40,9 @@ class TasmotaSerial : public Stream {
TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE);
virtual ~TasmotaSerial();
+ size_t setRxBufferSize(size_t size);
+ size_t getRxBufferSize() { return serial_buffer_size; }
+
bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1);
void end(bool turnOffDebug = true);
bool hardwareSerial(void);
@@ -65,6 +68,7 @@ class TasmotaSerial : public Stream {
bool isValidGPIOpin(int pin);
#ifdef ESP32
bool freeUart(void);
+ void Esp32Begin(void);
#endif
size_t txWrite(uint8_t byte);
@@ -80,18 +84,20 @@ class TasmotaSerial : public Stream {
uint32_t m_bit_follow_metric = 0;
uint32_t m_in_pos;
uint32_t m_out_pos;
- uint32_t serial_buffer_size;
+ uint32_t serial_buffer_size = TM_SERIAL_BUFFER_SIZE;
bool m_valid;
bool m_nwmode;
bool m_hardserial;
bool m_hardswap;
bool m_high_speed = false;
bool m_very_high_speed = false; // above 100000 bauds
- uint8_t *m_buffer;
+ uint8_t *m_buffer = nullptr;
void _fast_write(uint8_t b); // IRAM minimized version
#ifdef ESP32
+ uint32_t m_speed;
+ uint32_t m_config;
HardwareSerial *TSerial;
int m_uart = 0;
#endif
diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h
index a46c9d1a1..b40438194 100644
--- a/tasmota/include/i18n.h
+++ b/tasmota/include/i18n.h
@@ -575,6 +575,7 @@
// Commands xdrv_08_serial_bridge.ino
#define D_CMND_SSERIALSEND "SSerialSend"
#define D_CMND_SBAUDRATE "SBaudrate"
+#define D_CMND_SSERIALBUFFER "SSerialBuffer"
#define D_CMND_SSERIALCONFIG "SSerialConfig"
#define D_JSON_SSERIALRECEIVED "SSerialReceived"
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index b4562561b..aae239e10 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -27,20 +27,22 @@
#define USE_SERIAL_BRIDGE_TEE
-#ifdef ESP8266
-const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = MIN_INPUT_BUFFER_SIZE;
-#else
-const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = INPUT_BUFFER_SIZE;
-#endif
-
const char kSerialBridgeCommands[] PROGMEM = "|" // No prefix
- D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALCONFIG;
+ D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALBUFFER "|" D_CMND_SSERIALCONFIG;
void (* const SerialBridgeCommand[])(void) PROGMEM = {
- &CmndSSerialSend, &CmndSBaudrate, &CmndSSerialConfig };
+ &CmndSSerialSend, &CmndSBaudrate, &CmndSSerialBuffer, &CmndSSerialConfig };
#include
+#ifdef ESP8266
+const uint16_t SERIAL_BRIDGE_BUFFER_MIN_SIZE = TM_SERIAL_BUFFER_SIZE; // 64 (TasmotaSerial.h)
+const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = MIN_INPUT_BUFFER_SIZE; // 256
+#else
+const uint16_t SERIAL_BRIDGE_BUFFER_MIN_SIZE = MIN_INPUT_BUFFER_SIZE; // 256
+const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = INPUT_BUFFER_SIZE; // 800
+#endif
+
TasmotaSerial *SerialBridgeSerial = nullptr;
unsigned long serial_bridge_polling_window = 0;
@@ -263,6 +265,28 @@ void CmndSBaudrate(void) {
ResponseCmndNumber(Settings->sbaudrate * 300);
}
+void CmndSSerialBuffer(void) {
+ // Allow non-pesistent serial receive buffer size change
+ if (SerialBridgeSerial->hardwareSerial()) {
+ // between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
+ CmndSerialBuffer();
+ } else {
+ // ESP8266 (software serial): between TM_SERIAL_BUFFER_SIZE and SERIAL_BRIDGE_BUFFER_SIZE characters
+ // ESP32 (hardware serial only): between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
+ if (XdrvMailbox.data_len > 0) {
+ size_t size = XdrvMailbox.payload;
+ if (XdrvMailbox.payload < SERIAL_BRIDGE_BUFFER_MIN_SIZE) {
+ size = SERIAL_BRIDGE_BUFFER_MIN_SIZE; // 64 / 256
+ }
+ else if (XdrvMailbox.payload > SERIAL_BRIDGE_BUFFER_SIZE) {
+ size = SERIAL_BRIDGE_BUFFER_SIZE; // 256 / 800
+ }
+ SerialBridgeSerial->setRxBufferSize(size);
+ }
+ ResponseCmndNumber(SerialBridgeSerial->getRxBufferSize());
+ }
+}
+
void CmndSSerialConfig(void) {
// See TasmotaSerialConfig for possible options
// SSerialConfig 0..23 where 3 equals 8N1
From 69f903618da484b586860301aa1faeb5c494ea5a Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 18 Nov 2022 14:31:49 +0100
Subject: [PATCH 232/319] Fix intermittent wifi AP starts
---
tasmota/tasmota_support/support_wifi.ino | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index cb0e2abaa..692822384 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -217,12 +217,17 @@ void WifiBegin(uint8_t flag, uint8_t channel)
delay(200);
WifiSetMode(WIFI_STA); // Disable AP mode
*/
+#ifdef USE_WIFI_RANGE_EXTENDER
if (WiFi.getMode() != WIFI_AP_STA) { // Preserve range extender connections (#17103)
WiFi.disconnect(true); // Delete SDK wifi config
delay(200);
-
WifiSetMode(WIFI_STA); // Disable AP mode
}
+#else
+ WiFi.disconnect(true); // Delete SDK wifi config
+ delay(200);
+ WifiSetMode(WIFI_STA); // Disable AP mode
+#endif
WiFiSetSleepMode();
// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } // B/G/N
From 783631903dfa742f2a66c42f8a8fab5e341239ca Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Fri, 18 Nov 2022 16:21:54 +0100
Subject: [PATCH 233/319] Add user control over Serial Bridge buffers
- Add optional define ``SERIAL_BRIDGE_BUFFER_SIZE`` to set Serial Bridge internal buffer size (Default ESP8266 = 256, ESP32 = 800)
- Add command ``SSerialBuffer 256..SERIAL_BRIDGE_BUFFER_SIZE`` to change serial bridge rx buffer size (#17120)
---
CHANGELOG.md | 4 +-
RELEASENOTES.md | 4 +-
tasmota/my_user_config.h | 1 +
.../xdrv_08_serial_bridge.ino | 40 ++++++++++---------
4 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cbc9cc693..742e3e45d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,11 +6,13 @@ All notable changes to this project will be documented in this file.
## [12.2.0.5]
### Added
- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER (#17112)
-- Command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) (#17120)
+- Optional define ``SERIAL_BRIDGE_BUFFER_SIZE`` to set Serial Bridge internal buffer size (Default ESP8266 = 256, ESP32 = 800)
+- Command ``SSerialBuffer 256..SERIAL_BRIDGE_BUFFER_SIZE`` to change serial bridge rx buffer size (#17120)
### Breaking Changed
### Changed
+- Serial Bridge default internal serial rx buffer size from 64 to 256 (#17120)
### Fixed
- ModbusBridge baudrates over 76500 baud (#17106)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 7d52cd8f2..230f65435 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -112,9 +112,10 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
-- Command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) [#17120](https://github.com/arendst/Tasmota/issues/17120)
+- Command ``SSerialBuffer 256..SERIAL_BRIDGE_BUFFER_SIZE`` to change serial bridge rx buffer size [#17120](https://github.com/arendst/Tasmota/issues/17120)
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
+- Optional define ``SERIAL_BRIDGE_BUFFER_SIZE`` to set Serial Bridge internal buffer size (Default ESP8266 = 256, ESP32 = 800)
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
@@ -138,6 +139,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ESP32 Framework (Core) from v2.0.5 to v2.0.5.3
- ESP32 LVGL library from v8.3.2 to v8.3.3 (no functional change)
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
+- Serial Bridge default internal serial rx buffer size from 64 to 256 [#17120](https://github.com/arendst/Tasmota/issues/17120)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)
- ADE7953 monitoring from instant power to accumulated energy [#16941](https://github.com/arendst/Tasmota/issues/16941)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 725c55d9b..f5d80c0f1 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -780,6 +780,7 @@
#define SR04_MAX_SENSOR_DISTANCE 500 // Set sensor max detection distance
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
+// #define SERIAL_BRIDGE_BUFFER_SIZE 256 // Serial Bridge receive buffer size (Default ESP8266 = 256, ESP32 = 800)
//#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+4.5k code)
//#define USE_MODBUS_BRIDGE_TCP // Add support for software Modbus TCP Bridge (also enable Modbus TCP Bridge) (+2k code)
//#define USE_TCP_BRIDGE // Add support for Serial to TCP bridge (+1.3k code)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index aae239e10..92bbeceb5 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -27,6 +27,16 @@
#define USE_SERIAL_BRIDGE_TEE
+#ifdef SERIAL_BRIDGE_BUFFER_SIZE
+const uint16_t SERIAL_BRIDGE_BUFSIZE = SERIAL_BRIDGE_BUFFER_SIZE;
+#else
+#ifdef ESP8266
+const uint16_t SERIAL_BRIDGE_BUFSIZE = MIN_INPUT_BUFFER_SIZE; // 256
+#else
+const uint16_t SERIAL_BRIDGE_BUFSIZE = INPUT_BUFFER_SIZE; // 800
+#endif // ESP32
+#endif // SERIAL_BRIDGE_BUFFER_SIZE
+
const char kSerialBridgeCommands[] PROGMEM = "|" // No prefix
D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALBUFFER "|" D_CMND_SSERIALCONFIG;
@@ -34,15 +44,6 @@ void (* const SerialBridgeCommand[])(void) PROGMEM = {
&CmndSSerialSend, &CmndSBaudrate, &CmndSSerialBuffer, &CmndSSerialConfig };
#include
-
-#ifdef ESP8266
-const uint16_t SERIAL_BRIDGE_BUFFER_MIN_SIZE = TM_SERIAL_BUFFER_SIZE; // 64 (TasmotaSerial.h)
-const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = MIN_INPUT_BUFFER_SIZE; // 256
-#else
-const uint16_t SERIAL_BRIDGE_BUFFER_MIN_SIZE = MIN_INPUT_BUFFER_SIZE; // 256
-const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = INPUT_BUFFER_SIZE; // 800
-#endif
-
TasmotaSerial *SerialBridgeSerial = nullptr;
unsigned long serial_bridge_polling_window = 0;
@@ -94,7 +95,7 @@ void SerialBridgeInput(void) {
static bool serial_bridge_overrun = false;
if (isprint(serial_in_byte)) { // Any char between 32 and 127
- if (serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) { // Add char to string if it still fits
+ if (serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFSIZE -1) { // Add char to string if it still fits
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
} else {
serial_bridge_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
@@ -128,12 +129,12 @@ void SerialBridgeInput(void) {
((Settings->serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127
!serial_bridge_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter
- if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ...
+ if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFSIZE -1) && // Add char to string if it still fits and ...
!in_byte_is_delimiter) { // Char is not a delimiter
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
}
- if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFFER_SIZE -1) || // Send message when buffer is full or ...
+ if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFSIZE -1) || // Send message when buffer is full or ...
in_byte_is_delimiter) { // Char is delimiter
serial_bridge_polling_window = 0; // Publish now
break;
@@ -182,13 +183,14 @@ void SerialBridgeInput(void) {
void SerialBridgeInit(void) {
if (PinUsed(GPIO_SBR_RX) && PinUsed(GPIO_SBR_TX)) {
- SerialBridgeSerial = new TasmotaSerial(Pin(GPIO_SBR_RX), Pin(GPIO_SBR_TX), HARDWARE_FALLBACK);
+// SerialBridgeSerial = new TasmotaSerial(Pin(GPIO_SBR_RX), Pin(GPIO_SBR_TX), HARDWARE_FALLBACK); // Default TM_SERIAL_BUFFER_SIZE (=64) size
+ SerialBridgeSerial = new TasmotaSerial(Pin(GPIO_SBR_RX), Pin(GPIO_SBR_TX), HARDWARE_FALLBACK, 0, MIN_INPUT_BUFFER_SIZE); // 256
if (SetSSerialBegin()) {
if (SerialBridgeSerial->hardwareSerial()) {
ClaimSerial();
serial_bridge_buffer = TasmotaGlobal.serial_in_buffer; // Use idle serial buffer to save RAM
} else {
- serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFFER_SIZE));
+ serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFSIZE));
}
SerialBridgeSerial->flush();
SerialBridgePrintf("\r\n");
@@ -271,15 +273,15 @@ void CmndSSerialBuffer(void) {
// between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
CmndSerialBuffer();
} else {
- // ESP8266 (software serial): between TM_SERIAL_BUFFER_SIZE and SERIAL_BRIDGE_BUFFER_SIZE characters
+ // ESP8266 (software serial): between MIN_INPUT_BUFFER_SIZE and SERIAL_BRIDGE_BUFSIZE characters
// ESP32 (hardware serial only): between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
if (XdrvMailbox.data_len > 0) {
size_t size = XdrvMailbox.payload;
- if (XdrvMailbox.payload < SERIAL_BRIDGE_BUFFER_MIN_SIZE) {
- size = SERIAL_BRIDGE_BUFFER_MIN_SIZE; // 64 / 256
+ if (XdrvMailbox.payload < MIN_INPUT_BUFFER_SIZE) {
+ size = MIN_INPUT_BUFFER_SIZE; // 256 / 256
}
- else if (XdrvMailbox.payload > SERIAL_BRIDGE_BUFFER_SIZE) {
- size = SERIAL_BRIDGE_BUFFER_SIZE; // 256 / 800
+ else if (XdrvMailbox.payload > SERIAL_BRIDGE_BUFSIZE) {
+ size = SERIAL_BRIDGE_BUFSIZE; // 256 / 800
}
SerialBridgeSerial->setRxBufferSize(size);
}
From 774decee215cd0b5aa4f58d9b7dabd5c71cef6db Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Fri, 18 Nov 2022 17:27:09 +0100
Subject: [PATCH 234/319] Avoid crash if malloc fails take 2
---
lib/default/Ext-printf/src/ext_printf.cpp | 35 ++++++++++++-----------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/lib/default/Ext-printf/src/ext_printf.cpp b/lib/default/Ext-printf/src/ext_printf.cpp
index 17a32701f..df9204e3e 100644
--- a/lib/default/Ext-printf/src/ext_printf.cpp
+++ b/lib/default/Ext-printf/src/ext_printf.cpp
@@ -208,9 +208,12 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
// get a fresh malloc allocated string based on the current pointer (can be in PROGMEM)
// It is the caller's responsibility to free the memory
+//
+// Returns nullptr if something went wrong
char * copyStr(const char * str) {
if (str == nullptr) { return nullptr; }
char * cpy = (char*) malloc(strlen_P(str) + 1);
+ if (cpy == nullptr) { return nullptr; } // something went wrong
strcpy_P(cpy, str);
return cpy;
}
@@ -224,8 +227,10 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
// iterate on fmt to extract arguments and patch them in place
char * fmt_cpy = copyStr(fmt_P);
- if (fmt_cpy == nullptr) { return 0; }
+ if (fmt_cpy == nullptr) { return 0; } // we couldn't copy the format, abort
char * fmt = fmt_cpy;
+ int32_t ret = 0; // return 0 if unsuccessful
+ bool aborted = true; // did something went wrong?
const uint32_t ALLOC_SIZE = 12;
static const char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
@@ -277,6 +282,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else if (decimals > 0) {
char * hex_char = (char*) malloc(decimals*2 + 2);
+ if (hex_char == nullptr) { goto free_allocs; }
ToHex_P((const uint8_t *)cur_val, decimals, hex_char, decimals*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
@@ -292,6 +298,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
if (buf_len) {
char * hex_char = (char*) malloc(buf_len*2 + 2);
+ if (hex_char == nullptr) { goto free_allocs; }
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
@@ -307,6 +314,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
else if (decimals > 0) {
uint32_t val_size = decimals*6 + 2;
char * val_char = (char*) malloc(val_size);
+ if (val_char == nullptr) { goto free_allocs; }
val_char[0] = '\0';
for (uint32_t count = 0; count < decimals; count++) {
uint32_t value = pgm_read_byte((const uint8_t *)cur_val +1) << 8 | pgm_read_byte((const uint8_t *)cur_val);
@@ -328,6 +336,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
case 'I': // Input is `uint32_t` 32 bits IP address, output is decimal dotted address
{
char * ip_str = (char*) malloc(16);
+ if (ip_str == nullptr) { goto free_allocs; }
snprintf_P(ip_str, 16, PSTR("%u.%u.%u.%u"), cur_val & 0xFF, (cur_val >> 8) & 0xFF, (cur_val >> 16) & 0xFF, (cur_val >> 24) & 0xFF);
new_val_str = ip_str;
allocs[alloc_idx++] = new_val_str;
@@ -371,6 +380,7 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
new_val_str = copyStr(hex);
+ if (new_val_str == nullptr) { goto free_allocs; }
allocs[alloc_idx++] = new_val_str;
}
}
@@ -384,24 +394,11 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
U64toHex(*(uint64_t*)cur_val, hex, decimals);
new_val_str = copyStr(hex);
+ if (new_val_str == nullptr) { goto free_allocs; }
allocs[alloc_idx++] = new_val_str;
}
}
break;
- // Trying to do String allocation alternatives, but not as interesting as I thought in the beginning
- // case 's':
- // {
- // new_val_str = copyStr(((String*)cur_val)->c_str());
- // allocs[alloc_idx++] = new_val_str;
- // }
- // break;
- // case 'S':
- // {
- // funcString_t * func_str = (funcString_t*) cur_val;
- // new_val_str = copyStr((*func_str)().c_str());
- // allocs[alloc_idx++] = new_val_str;
- // }
- // break;
}
*cur_val_ptr = new_val_str;
*fmt = 's'; // replace `%_X` with `%0s` to display a string instead
@@ -413,9 +410,9 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
}
}
// Serial.printf("> format_final=%s\n", fmt_cpy); Serial.flush();
- int32_t ret = 0; // return 0 if unsuccessful
if (out_buf != nullptr) {
ret = vsnprintf_P(out_buf, buf_len, fmt_cpy, va_cpy);
+ aborted = false; // we completed without malloc error
} else {
// if there is no output buffer, we allocate one on the heap
// first we do a dry-run to know the target size
@@ -428,12 +425,18 @@ int32_t ext_vsnprintf_P(char * out_buf, size_t buf_len, const char * fmt_P, va_l
allocated_buf[0] = 0; // default to empty string
vsnprintf_P(allocated_buf, target_len + 1, fmt_cpy, va_cpy);
ret = (int32_t) allocated_buf;
+ aborted = false; // we completed without malloc error
}
}
}
va_end(va_cpy);
+free_allocs:
+ if (aborted && out_buf != nullptr) { // if something went wrong, set output string to empty string to avoid corrupt data
+ *out_buf = '\0';
+ }
+
// disallocated all temporary strings
for (uint32_t i = 0; i < alloc_idx; i++) {
free((void*)allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
From 7129c6404811559e9c4b5cb4b921ce3f373d9525 Mon Sep 17 00:00:00 2001
From: Christian Baars
Date: Fri, 18 Nov 2022 20:46:42 +0100
Subject: [PATCH 235/319] hide sensors from discovery to do this in Berry
---
tasmota/include/xsns_62_esp32_mi.h | 1 -
tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino | 14 +++++++-------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/tasmota/include/xsns_62_esp32_mi.h b/tasmota/include/xsns_62_esp32_mi.h
index 409821481..8418554df 100644
--- a/tasmota/include/xsns_62_esp32_mi.h
+++ b/tasmota/include/xsns_62_esp32_mi.h
@@ -201,7 +201,6 @@ struct {
uint32_t allwaysAggregate:1; // always show all known values of one sensor in brdigemode
uint32_t noSummary:1; // no sensor values at TELE-period
uint32_t directBridgeMode:1; // send every received BLE-packet as a MQTT-message in real-time
- uint32_t showRSSI:1;
uint32_t activeScan:1;
uint32_t ignoreBogusBattery:1;
uint32_t minimalSummary:1; // DEPRECATED!!
diff --git a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
index ead1c2260..0b8c2eb26 100644
--- a/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
+++ b/tasmota/tasmota_xsns_sensor/xsns_62_esp32_mi.ino
@@ -615,7 +615,6 @@ void MI32PreInit(void) {
MI32.option.noSummary = 0;
MI32.option.minimalSummary = 0;
MI32.option.directBridgeMode = 0;
- MI32.option.showRSSI = 1;
MI32.option.ignoreBogusBattery = 1; // from advertisements
MI32loadCfg();
@@ -640,7 +639,7 @@ void MI32Init(void) {
}
}
- if(MI32.mode.didGetConfig){
+ if(MI32.mode.didGetConfig && !Settings->flag5.zigbee_hide_bridge_topic){ // borrow SO125 1 to turn off HomeKit
MI32.mode.didStartHAP = 0;
#ifdef USE_MI_HOMEKIT
MI32getSetupCodeFromMAC(MI32.hk_setup_code);
@@ -2096,6 +2095,7 @@ void MI32Show(bool json)
if(!MI32.mode.triggeredTele){
if(MI32.option.noSummary) return; // no message at TELEPERIOD
}
+ if(TasmotaGlobal.masterlog_level == LOG_LEVEL_DEBUG_MORE) return; // we want to announce sensors unlinked to the ESP, check for LOG_LEVEL_DEBUG_MORE is medium-safe
MI32suspendScanTask();
for (uint32_t i = 0; i < MIBLEsensors.size(); i++) {
if(MI32.mode.triggeredTele && MIBLEsensors[i].eventType.raw == 0) continue;
@@ -2228,10 +2228,9 @@ void MI32Show(bool json)
}
}
}
- if (MI32.option.showRSSI) {
- MI32ShowContinuation(&commaflg);
- ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].RSSI);
- }
+ MI32ShowContinuation(&commaflg);
+ ResponseAppend_P(PSTR("\"RSSI\":%d"), MIBLEsensors[i].RSSI);
+
ResponseJsonEnd();
MIBLEsensors[i].eventType.raw = 0;
@@ -2319,6 +2318,7 @@ int ExtStopBLE(){
MI32Scan->stop();
MI32.mode.deleteScanTask = 1;
AddLog(LOG_LEVEL_INFO,PSTR("M32: stop BLE"));
+ while (MI32.mode.runningScan) yield();
}
#ifdef USE_MI_HOMEKIT
if(MI32.mode.didStartHAP) {
@@ -2371,7 +2371,7 @@ bool Xsns62(uint32_t function)
break;
#ifdef USE_MI_EXT_GUI
case FUNC_WEB_ADD_MAIN_BUTTON:
- if (MI32.mode.didGetConfig) WSContentSend_P(HTTP_BTN_MENU_MI32);
+ if (Settings->flag5.mi32_enable) WSContentSend_P(HTTP_BTN_MENU_MI32);
break;
case FUNC_WEB_ADD_HANDLER:
WebServer_on(PSTR("/m32"), MI32HandleWebGUI);
From 52faed8c088afb60f14fe294074588498bf1106c Mon Sep 17 00:00:00 2001
From: Anton <35825286+anton-v-a@users.noreply.github.com>
Date: Sat, 19 Nov 2022 01:40:24 -0500
Subject: [PATCH 236/319] Bugfix: RfSend command to support bits>32 for decimal
command format
---
tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino b/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino
index 68077778e..05c28fa07 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_17_rcswitch.ino
@@ -180,7 +180,7 @@ void CmndRfSend(void)
for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 5; str = strtok_r(nullptr, ", ", &p)) {
switch (i++) {
case 0:
- data = strtoul(str, nullptr, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
+ data = strtoull(str, nullptr, 0); // Allow decimal (5246996) and hexadecimal (0x501014) input
break;
case 1:
bits = atoi(str);
From b2adcdcee5c124440e1b4d7a6b4fab33df99dac4 Mon Sep 17 00:00:00 2001
From: Anton <35825286+anton-v-a@users.noreply.github.com>
Date: Sat, 19 Nov 2022 01:56:17 -0500
Subject: [PATCH 237/319] Adding protocol for DOOYA 2700AC remote
Adding protocol for DOOYA 2700AC remote (used with DT82TV curtain motors)
This remote uses 40-bit code
PR #17139 is needed to support it in decimal format of RfSend command (JSON format works as is)
---
lib/lib_rf/rc-switch/src/RCSwitch.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/lib_rf/rc-switch/src/RCSwitch.cpp b/lib/lib_rf/rc-switch/src/RCSwitch.cpp
index 69b3f37a3..a02cbb38f 100644
--- a/lib/lib_rf/rc-switch/src/RCSwitch.cpp
+++ b/lib/lib_rf/rc-switch/src/RCSwitch.cpp
@@ -149,8 +149,9 @@ static const RCSwitch::Protocol PROGMEM proto[] = {
{ 400, 0, { 0, 0 }, 1, { 1, 1 }, { 1, 2 }, { 2, 1 }, false, 43 }, // 31 (Mertik Maxitrol G6R-H4T1)
{ 365, 0, { 0, 0 }, 1, { 18, 1 }, { 3, 1 }, { 1, 3 }, true, 0 }, // 32 (1ByOne Doorbell) from @Fatbeard https://github.com/sui77/rc-switch/pull/277
{ 340, 0, { 0, 0 }, 1, { 14, 4 }, { 1, 2 }, { 2, 1 }, false, 0 }, // 33 (Dooya Control DC2708L)
- { 120, 0, { 0, 0 }, 1, { 1, 28 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 34 DIGOO SD10 - so as to use this protocol RCSWITCH_SEPARATION_LIMIT must be set to 2600
- { 20, 0, { 0, 0 }, 1, { 239, 78 }, {20, 35 }, {35, 20}, false, 10000 } // 35 Dooya 5-Channel blinds remote DC1603
+ { 120, 0, { 0, 0 }, 1, { 1, 28 }, { 1, 3 }, { 3, 1 }, false, 0 }, // 34 DIGOO SD10 - so as to use this protocol RCSWITCH_SEPARATION_LIMIT must be set to 2600
+ { 20, 0, { 0, 0 }, 1, { 239, 78 }, {20, 35 }, {35, 20}, false, 10000},// 35 Dooya 5-Channel blinds remote DC1603
+ { 250, 0, { 0, 0 }, 1, { 18, 6 }, { 1, 3 }, { 3, 1 }, false, 0 } // 36 Dooya remote DC2700AC for Dooya DT82TV curtains motor
};
enum {
From 4844209a3bdd20dbf4d89d712f0f5c9453e6b917 Mon Sep 17 00:00:00 2001
From: joba-1
Date: Sat, 19 Nov 2022 12:47:53 +0100
Subject: [PATCH 238/319] rgx add port forward with ip and "dry" refactoring
---
.../xdrv_58_range_extender.ino | 61 +++++++++++++------
1 file changed, 41 insertions(+), 20 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
index a0e5f3f62..88631bb27 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_58_range_extender.ino
@@ -283,14 +283,39 @@ void CmndRgxNAPT(void)
ResponseCmndStateText(Settings->sbflag1.range_extender_napt);
}
+// CmndRgxPort helper: Do port map and set response if successful
+void CmndRgxPortMap(uint8_t proto, uint16_t gw_port, uint32_t dst_ip, uint16_t dst_port)
+{
+ uint32_t gw_ip = (uint32_t)WiFi.localIP();
+ if (ip_portmap_add(proto, gw_ip, gw_port, dst_ip, dst_port))
+ {
+ Response_P(PSTR("OK %s %_I:%u -> %_I:%u"),
+ (proto == IP_PROTO_TCP) ? "TCP" : "UDP", gw_ip, gw_port, dst_ip, dst_port);
+ }
+}
+
+// CmndRgxPort helper: If mac from esp list and mac from command parameters are the same try port map and return true
+bool CmndRgxPortMapCheck(const uint8_t *mac, const char *parm_mac, uint8_t proto, uint16_t gw_port, uint32_t dst_ip, uint16_t dst_port)
+{
+ char list_mac[13];
+ snprintf(list_mac, sizeof(list_mac), PSTR("%02X%02X%02X%02X%02X%02X"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ if (strcasecmp(list_mac, parm_mac) == 0)
+ {
+ CmndRgxPortMap(proto, gw_port, dst_ip, dst_port);
+ return true;
+ }
+ return false;
+}
+
void CmndRgxPort(void)
{
- char *tok, *state, *parm_mac;
+ char *tok, *state, *parm_addr;
uint16_t gw, dst;
uint8_t proto = 0;
Response_P(PSTR("ERROR"));
+ // Parameter parsing
if (ArgC()!=4) return;
if ((tok = strtok_r(XdrvMailbox.data, ", ", &state)) == 0) return;
if (strcasecmp("TCP", tok) == 0) proto = IP_PROTO_TCP;
@@ -298,10 +323,22 @@ void CmndRgxPort(void)
if (!proto) return;
if ((tok = strtok_r(0, ", ", &state)) == 0) return;
if ((gw = strtoul(tok, nullptr, 0)) == 0) return;
- if ((parm_mac = strtok_r(0, ", ", &state)) == 0) return;
+ if ((parm_addr = strtok_r(0, ", ", &state)) == 0) return;
if ((tok = strtok_r(0, ", ", &state)) == 0) return;
if ((dst = strtoul(tok, nullptr, 0)) == 0) return;
+ // If forward address is an ip, then just do it...
+ // Useful for static IPs not used by the range extender dhcp server
+ // On ESP8266 the default dhcp ip range to avoid is .100-.200
+ // On ESP32 the default dhcp ip range to avoid is .2-.11
+ IPAddress ip;
+ if (ip.fromString(parm_addr))
+ {
+ CmndRgxPortMap(proto, gw, (uint32_t)ip, dst);
+ return;
+ }
+
+ // Forward address is a mac, find the associated ip...
#if defined(ESP32)
wifi_sta_list_t wifi_sta_list = {0};
tcpip_adapter_sta_list_t adapter_sta_list = {0};
@@ -311,16 +348,8 @@ void CmndRgxPort(void)
for (int i=0; i %_I:%u"),
- (proto == IP_PROTO_TCP) ? "TCP" : "UDP", (uint32_t)WiFi.localIP(), gw, adapter_sta_list.sta[i].ip.addr, dst);
- }
break;
}
}
@@ -328,16 +357,8 @@ void CmndRgxPort(void)
struct station_info *station = wifi_softap_get_station_info();
while (station)
{
- char list_mac[13];
- const uint8_t *m = station->bssid;
- snprintf(list_mac, sizeof(list_mac), PSTR("%02X%02X%02X%02X%02X%02X"), m[0], m[1], m[2], m[3], m[4], m[5]);
- if (strcasecmp(list_mac, parm_mac) == 0)
+ if (CmndRgxPortMapCheck(station->bssid, parm_addr, proto, gw, station->ip.addr, dst))
{
- if (ip_portmap_add(proto, (uint32_t)WiFi.localIP(), gw, station->ip.addr, dst))
- {
- Response_P(PSTR("OK %s %_I:%u -> %_I:%u"),
- (proto == IP_PROTO_TCP) ? "TCP" : "UDP", (uint32_t)WiFi.localIP(), gw, station->ip.addr, dst);
- }
break;
}
station = STAILQ_NEXT(station, next);
From 82df1a915202913bc7134784f3bc6f37bdfab76f Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sat, 19 Nov 2022 14:59:07 +0100
Subject: [PATCH 239/319] Zigbee fix attribute not reported
---
tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino | 1 +
tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
index 6266e8f49..5d34f5fc0 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_5_2_converters.ino
@@ -717,6 +717,7 @@ void ZCLFrame::applySynonymAttributes(Z_attribute_list& attr_list) {
Z_attribute_synonym syn = Z_plugin_matchAttributeSynonym(device.modelId, device.manufacturerId,
attr.cluster, attr.attr_id);
if (syn.found()) {
+ AddLog(LOG_LEVEL_DEBUG, PSTR("ZIG: apply synonym %04X/%04X with %04X/%04X (mul:%i div:%i)"), attr.cluster, attr.attr_id, syn.new_cluster, syn.new_attribute, syn.multiplier, syn.divider);
if (syn.new_attribute == 0xFFFF) { // if attr is 0xFFFF, remove attribute
attr_list.removeAttribute(&attr);
} else {
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
index 3ec2ae123..fa6760c8a 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
@@ -1773,6 +1773,7 @@ void Z_IncomingMessage(class ZCLFrame &zcl_received) {
callBerryZigbeeDispatcher("attributes_refined", &zcl_received, &attr_list, srcaddr);
#endif // USE_BERRY
+ if (!attr_list.isEmpty()) {
if (defer_attributes) {
// Prepare for publish
if (zigbee_devices.jsonIsConflict(srcaddr, attr_list)) {
@@ -1780,10 +1781,11 @@ void Z_IncomingMessage(class ZCLFrame &zcl_received) {
zigbee_devices.jsonPublishFlush(srcaddr);
}
zigbee_devices.jsonAppend(srcaddr, attr_list);
- zigbee_devices.setTimer(srcaddr, 0 /* groupaddr */, USE_ZIGBEE_COALESCE_ATTR_TIMER, clusterid, srcendpoint, Z_CAT_READ_ATTR, 0, &Z_PublishAttributes);
+ zigbee_devices.setTimer(srcaddr, 0 /* groupaddr */, USE_ZIGBEE_COALESCE_ATTR_TIMER, 0 /*clusterid*/, srcendpoint, Z_CAT_READ_ATTR, 0, &Z_PublishAttributes);
} else {
// Publish immediately
zigbee_devices.jsonPublishNow(srcaddr, attr_list);
+ }
}
}
}
From 425f83bf85994f1b12cb9bf30f2030e74c613459 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 19 Nov 2022 14:59:36 +0100
Subject: [PATCH 240/319] Update Serial Bridge code size
---
tasmota/include/tasmota_configurations.h | 2 +-
tasmota/include/tasmota_configurations_ESP32.h | 6 +++---
tasmota/my_user_config.h | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tasmota/include/tasmota_configurations.h b/tasmota/include/tasmota_configurations.h
index 90ea85518..60799d67c 100644
--- a/tasmota/include/tasmota_configurations.h
+++ b/tasmota/include/tasmota_configurations.h
@@ -178,7 +178,7 @@
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
-#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
+#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
//#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+3k code)
#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger
diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h
index c9754c710..11966f961 100644
--- a/tasmota/include/tasmota_configurations_ESP32.h
+++ b/tasmota/include/tasmota_configurations_ESP32.h
@@ -181,7 +181,7 @@
#define USE_WEBSERVER
#define USE_WEBCLIENT
#define USE_WEBCLIENT_HTTPS
-#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge console Tee (+0k8 code)
+#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge console Tee (+2k code)
#define USE_ETHERNET
#endif // FIRMWARE_SAFEBOOT
@@ -444,7 +444,7 @@
//#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
-#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
+#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
//#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+3k code)
//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger
@@ -662,7 +662,7 @@
#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor
#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
-#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
+#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+3k code)
#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index f5d80c0f1..0ec257898 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -779,7 +779,7 @@
//#define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code)
#define SR04_MAX_SENSOR_DISTANCE 500 // Set sensor max detection distance
//#define USE_DYP // Add support for DYP ME-007 ultrasonic distance sensor, serial port version (+0k5 code)
-#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
+#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+2k code)
// #define SERIAL_BRIDGE_BUFFER_SIZE 256 // Serial Bridge receive buffer size (Default ESP8266 = 256, ESP32 = 800)
//#define USE_MODBUS_BRIDGE // Add support for software Modbus Bridge (+4.5k code)
//#define USE_MODBUS_BRIDGE_TCP // Add support for software Modbus TCP Bridge (also enable Modbus TCP Bridge) (+2k code)
From 16b34963d5beeb817492b1c67b228b357d639cbe Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sat, 19 Nov 2022 15:01:01 +0100
Subject: [PATCH 241/319] Fix identaiton
---
.../xdrv_23_zigbee_8_parsers.ino | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
index fa6760c8a..dda38daf8 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_23_zigbee_8_parsers.ino
@@ -1774,17 +1774,17 @@ void Z_IncomingMessage(class ZCLFrame &zcl_received) {
#endif // USE_BERRY
if (!attr_list.isEmpty()) {
- if (defer_attributes) {
- // Prepare for publish
- if (zigbee_devices.jsonIsConflict(srcaddr, attr_list)) {
- // there is conflicting values, force a publish of the previous message now and don't coalesce
- zigbee_devices.jsonPublishFlush(srcaddr);
- }
- zigbee_devices.jsonAppend(srcaddr, attr_list);
- zigbee_devices.setTimer(srcaddr, 0 /* groupaddr */, USE_ZIGBEE_COALESCE_ATTR_TIMER, 0 /*clusterid*/, srcendpoint, Z_CAT_READ_ATTR, 0, &Z_PublishAttributes);
- } else {
- // Publish immediately
- zigbee_devices.jsonPublishNow(srcaddr, attr_list);
+ if (defer_attributes) {
+ // Prepare for publish
+ if (zigbee_devices.jsonIsConflict(srcaddr, attr_list)) {
+ // there is conflicting values, force a publish of the previous message now and don't coalesce
+ zigbee_devices.jsonPublishFlush(srcaddr);
+ }
+ zigbee_devices.jsonAppend(srcaddr, attr_list);
+ zigbee_devices.setTimer(srcaddr, 0 /* groupaddr */, USE_ZIGBEE_COALESCE_ATTR_TIMER, 0 /*clusterid*/, srcendpoint, Z_CAT_READ_ATTR, 0, &Z_PublishAttributes);
+ } else {
+ // Publish immediately
+ zigbee_devices.jsonPublishNow(srcaddr, attr_list);
}
}
}
From 4f31e7a1b202268b938e9c2f2b366d847b14b68e Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 20 Nov 2022 12:52:24 +0100
Subject: [PATCH 242/319] Add command ``SetOption35 0..255``
Add command ``SetOption35 0..255`` to skip number of received messages in Serial Bridge (default 0) (#17140)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/include/tasmota.h | 2 +-
tasmota/tasmota.ino | 1 +
tasmota/tasmota_support/settings.ino | 1 +
tasmota/tasmota_support/support_network.ino | 14 ++----
tasmota/tasmota_support/support_wifi.ino | 9 +---
.../xdrv_08_serial_bridge.ino | 46 +++++++++++--------
8 files changed, 35 insertions(+), 40 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 742e3e45d..8e221c91b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER (#17112)
- Optional define ``SERIAL_BRIDGE_BUFFER_SIZE`` to set Serial Bridge internal buffer size (Default ESP8266 = 256, ESP32 = 800)
- Command ``SSerialBuffer 256..SERIAL_BRIDGE_BUFFER_SIZE`` to change serial bridge rx buffer size (#17120)
+- Command ``SetOption35 0..255`` to skip number of received messages in Serial Bridge (default 0) (#17140)
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 230f65435..acf2fb682 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -109,6 +109,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.5
### Added
+- Command ``SetOption35 0..255`` to skip number of received messages in Serial Bridge (default 0) [#17140](https://github.com/arendst/Tasmota/issues/17140)
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h
index d00ee6295..911df0171 100644
--- a/tasmota/include/tasmota.h
+++ b/tasmota/include/tasmota.h
@@ -359,7 +359,7 @@ enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER };
enum SO32_49Index { P_HOLD_TIME, // SetOption32 - (Button/Switch) Key hold time detection in decaseconds (default 40)
P_MAX_POWER_RETRY, // SetOption33 - (Energy) Maximum number of retries before deciding power limit overflow (default 5)
P_BACKLOG_DELAY, // SetOption34 - (Backlog) Minimal delay in milliseconds between executing backlog commands (default 200)
- P_MDNS_DELAYED_START, // SetOption35 - (mDNS) Number of seconds before mDNS is started (default 0) - Obsolete
+ P_SERIAL_SKIP, // SetOption35 - (SerialBridge) Skip number of serial messages received (default 0)
P_BOOT_LOOP_OFFSET, // SetOption36 - (Restart) Number of restarts to start detecting boot loop (default 1)
P_RGB_REMAP, // SetOption37 - (Light) RGB and White channel separation (default 0)
P_IR_UNKNOW_THRESHOLD, // SetOption38 - (IR) Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255)
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index a9c6f6ba9..137bd80c2 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -323,6 +323,7 @@ struct TasmotaGlobal_t {
uint8_t light_driver; // Light module configured
uint8_t light_type; // Light types
uint8_t serial_in_byte; // Received byte
+ uint8_t serial_skip; // Skip number of received messages
uint8_t devices_present; // Max number of devices supported
uint8_t masterlog_level; // Master log level used to override set log level
uint8_t seriallog_level; // Current copy of Settings->seriallog_level
diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino
index d3c4fd907..4837cbdaa 100644
--- a/tasmota/tasmota_support/settings.ino
+++ b/tasmota/tasmota_support/settings.ino
@@ -1609,6 +1609,7 @@ void SettingsDelta(void) {
}
if (Settings->version < 0x0C020005) { // 12.2.0.5
Settings->modbus_sbaudrate = Settings->ex_modbus_sbaudrate;
+ Settings->param[P_SERIAL_SKIP] = 0;
}
Settings->version = VERSION;
diff --git a/tasmota/tasmota_support/support_network.ino b/tasmota/tasmota_support/support_network.ino
index a6975c750..f03edbd75 100644
--- a/tasmota/tasmota_support/support_network.ino
+++ b/tasmota/tasmota_support/support_network.ino
@@ -27,19 +27,11 @@ struct {
#ifdef USE_DISCOVERY
void StartMdns(void) {
-// static uint8_t mdns_delayed_start = Settings->param[P_MDNS_DELAYED_START];
-
if (Settings->flag3.mdns_enabled) { // SetOption55 - Control mDNS service
if (!Mdns.begun) {
-// if (mdns_delayed_start) {
-// AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION));
-// mdns_delayed_start--;
-// } else {
-// mdns_delayed_start = Settings->param[P_MDNS_DELAYED_START];
- MDNS.end(); // close existing or MDNS.begin will fail
- Mdns.begun = (uint8_t)MDNS.begin(TasmotaGlobal.hostname);
- AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? PSTR(D_INITIALIZED) : PSTR(D_FAILED));
-// }
+ MDNS.end(); // close existing or MDNS.begin will fail
+ Mdns.begun = (uint8_t)MDNS.begin(TasmotaGlobal.hostname);
+ AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? PSTR(D_INITIALIZED) : PSTR(D_FAILED));
}
}
}
diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino
index 692822384..c7218a505 100644
--- a/tasmota/tasmota_support/support_wifi.ino
+++ b/tasmota/tasmota_support/support_wifi.ino
@@ -203,20 +203,13 @@ void WiFiSetSleepMode(void)
WifiSetOutputPower();
}
-void WifiBegin(uint8_t flag, uint8_t channel)
-{
+void WifiBegin(uint8_t flag, uint8_t channel) {
#ifdef USE_EMULATION
UdpDisconnect();
#endif // USE_EMULATION
WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083)
-/*
- // Replaced by below code (20221117)
- WiFi.disconnect(true); // Delete SDK wifi config
- delay(200);
- WifiSetMode(WIFI_STA); // Disable AP mode
-*/
#ifdef USE_WIFI_RANGE_EXTENDER
if (WiFi.getMode() != WIFI_AP_STA) { // Preserve range extender connections (#17103)
WiFi.disconnect(true); // Delete SDK wifi config
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
index 92bbeceb5..fda65d687 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_08_serial_bridge.ino
@@ -95,7 +95,7 @@ void SerialBridgeInput(void) {
static bool serial_bridge_overrun = false;
if (isprint(serial_in_byte)) { // Any char between 32 and 127
- if (serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFSIZE -1) { // Add char to string if it still fits
+ if (serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFSIZE -1) { // Add char to string if it still fits
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
} else {
serial_bridge_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
@@ -129,12 +129,12 @@ void SerialBridgeInput(void) {
((Settings->serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127
!serial_bridge_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter
- if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFSIZE -1) && // Add char to string if it still fits and ...
+ if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFSIZE -1) && // Add char to string if it still fits and ...
!in_byte_is_delimiter) { // Char is not a delimiter
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
}
- if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFSIZE -1) || // Send message when buffer is full or ...
+ if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFSIZE -1) || // Send message when buffer is full or ...
in_byte_is_delimiter) { // Char is delimiter
serial_bridge_polling_window = 0; // Publish now
break;
@@ -156,25 +156,31 @@ void SerialBridgeInput(void) {
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed
bool assume_json = (!serial_bridge_raw && (serial_bridge_buffer[0] == '{'));
- Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":"));
- if (assume_json) {
- ResponseAppend_P(serial_bridge_buffer);
- } else {
- ResponseAppend_P(PSTR("\""));
- if (serial_bridge_raw) {
- ResponseAppend_P(PSTR("%*_H"), serial_bridge_in_byte_counter, serial_bridge_buffer);
- } else {
- ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str());
- }
- ResponseAppend_P(PSTR("\""));
- }
- ResponseJsonEnd();
+ TasmotaGlobal.serial_skip++; // SetOption35 Skip number of serial messages received (default 0)
+ if (TasmotaGlobal.serial_skip >= Settings->param[P_SERIAL_SKIP]) { // Handle intermediate changes to SetOption35
+ TasmotaGlobal.serial_skip = 0;
- if (Settings->flag6.mqtt_disable_sserialrec ) { // SetOption147 If it is activated, Tasmota will not publish SSerialReceived MQTT messages, but it will proccess event trigger rules
- XdrvRulesProcess(0);
- } else {
- MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
+ Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":"));
+ if (assume_json) {
+ ResponseAppend_P(serial_bridge_buffer);
+ } else {
+ ResponseAppend_P(PSTR("\""));
+ if (serial_bridge_raw) {
+ ResponseAppend_P(PSTR("%*_H"), serial_bridge_in_byte_counter, serial_bridge_buffer);
+ } else {
+ ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str());
+ }
+ ResponseAppend_P(PSTR("\""));
+ }
+ ResponseJsonEnd();
+
+ if (Settings->flag6.mqtt_disable_sserialrec ) { // SetOption147 If it is activated, Tasmota will not publish SSerialReceived MQTT messages, but it will proccess event trigger rules
+ XdrvRulesProcess(0);
+ } else {
+ MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
+ }
}
+
serial_bridge_in_byte_counter = 0;
}
}
From f9138984bfe1fb5d10082d8ef4dcfeba4044918b Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 20 Nov 2022 15:07:38 +0100
Subject: [PATCH 243/319] Add accept filename extensions to GUI
Add accept filename extensions to GUI file upload input fields (#16875)
---
CHANGELOG.md | 1 +
RELEASENOTES.md | 1 +
tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 12 ++++++------
....7.9.gbl => MGM210PA32JIA_ncp-uart-sw_6.7.9.ota} | Bin
tools/fw_TubeZigbee_efr32/readme.md | 2 +-
5 files changed, 9 insertions(+), 7 deletions(-)
rename tools/fw_TubeZigbee_efr32/{MGM210PA32JIA_ncp-uart-sw_6.7.9.gbl => MGM210PA32JIA_ncp-uart-sw_6.7.9.ota} (100%)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e221c91b..85b3cc383 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
- Optional define ``SERIAL_BRIDGE_BUFFER_SIZE`` to set Serial Bridge internal buffer size (Default ESP8266 = 256, ESP32 = 800)
- Command ``SSerialBuffer 256..SERIAL_BRIDGE_BUFFER_SIZE`` to change serial bridge rx buffer size (#17120)
- Command ``SetOption35 0..255`` to skip number of received messages in Serial Bridge (default 0) (#17140)
+- Accept filename extensions to GUI file upload input fields (#16875)
### Breaking Changed
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index acf2fb682..7873568d3 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -126,6 +126,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Support for BP1658CJ RGBCW led bulbs like Orein OS0100411267 by Cossid [#17011](https://github.com/arendst/Tasmota/issues/17011)
- Support for Dingtian x595 shift register based relay boards by Barbudor [#17032](https://github.com/arendst/Tasmota/issues/17032)
- Support for HMC5883L 3-Axis Digital Compass sensor by Andreas Achtzehn [#17069](https://github.com/arendst/Tasmota/issues/17069)
+- Accept filename extensions to GUI file upload input fields [#16875](https://github.com/arendst/Tasmota/issues/16875)
- WS2812 and Light ArtNet DMX control over UDP port 6454 [#17059](https://github.com/arendst/Tasmota/issues/17059)
- Berry ``bytes().setbytes()`` method [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Berry ``bytes().reverse()`` method [#16977](https://github.com/arendst/Tasmota/issues/16977)
diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
index b62176159..84018e4f1 100644
--- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
+++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino
@@ -354,7 +354,7 @@ const char HTTP_FORM_UPG[] PROGMEM =
"